1. 程式人生 > >虛擬化技術性能總結:Zones, KVM, Xen

虛擬化技術性能總結:Zones, KVM, Xen

先說一下,中國香港的Fengqi.Asia或大陸的風起雲所使用的後臺技術即是Joyent相關技術,應該也是中國現在唯一使用Joyent技術的公有云(如果有錯請不吝指教)。

------------------------------------------------------------

在Joyent公司,我們在兩種不同的虛擬化技術(ZonesKVM)上執行一個高效能公有云。我們也曾經用過Xen,但後來逐步淘汰了它,取而代之,在SmartOS上使用KVM。我的任務是讓他們執行得更快,所以會用到DTrace來分析核心、應用程式和上述的虛擬化技術。這篇文章我會用四種方式來總結一下它們的效能:特點、方框圖、內部情況、測試結果。


AttributeZonesXenKVM
CPU Performancehighhigh (with CPU support)high (with CPU support)
CPU Allocationflexible (FSS + “bursting”)fixed to VCPU limitfixed to VCPU limit
I/O Throughputhigh (no intrinsic overhead)low or medium (with paravirt)low or medium (with paravirt)
I/O Latencylow (no intrinsic overhead)some (I/O proxy overhead)some (I/O proxy overhead)
Memory Access Overheadnonesome (EPT/NPT or shadow page tables)some (EPT/NPT or shadow page tables)
Memory Lossnonesome (extra kernels; page tables)some (extra kernels; page tables)
Memory Allocationflexible (unused guest memory used for file system cache)fixed (and possible double-caching)fixed (and possible double-caching)
Resource Controlsmany (depends on OS)some (depends on hypervisor)most (OS + hypervisor)
Observability: from the hosthighest (see everything)low (resource usage, hypervisor statistics)medium (resource usage, hypervisor statistics, OS inspection of hypervisor)
Observability: from the guestmedium (see everything permitted, incl. some physical resource stats)low (guest only)low (guest only)
Hypervisor Complexitylow (OS partitions)high (complex hypervisor)medium
Different OS Guestsusually no (sometimes possible with syscall translation)yesyes

(上表就不翻譯了,看英文更合適)

配置調優等不同可能會導致上表的一些變化,從而細節可能會有不同。不過至少可以把上表當成一個屬性清單來做分析確認,這樣的話,當你在考慮其他技術,比如VMware時,可以參考一下此清單。其實Wikipedia上也提供了一個常用的屬性對比表

表中的三列代表三種不同的型別:: 作業系統虛擬化 (Zones)、硬體虛擬化Type 1 (Xen) and Type 2 (KVM) 。

它們虛擬化後表現出來的效能是我們最關心的。一般來說,Joyent使用高速的伺服器級別的硬體,10 GbE 網路,所用檔案系統使用 ZFS ,用 DTrace 做系統分析,儘量使用 Zones 虛擬化。我們使用自己移植的 KVM to illumos,並在Zones內部執行KVM例項,提供額外的資源控制,和增強的安全措施(“double-hulled virtualization”雙層虛擬化).

有很多屬性的細節我都想討論。這篇文章我會談談 I/O Path(網路、磁碟)和它的負載情況等。

I/O Path(I/O 路徑)

對於傳統的Unix和Zones,它們的 I/O 有什麼不同呢?

效能完全一樣——沒有額外開銷。Zones分隔OS的方式如同chroot在檔案系統裡隔離程序一樣。在軟體棧裡沒有必要提供額外的一層來讓Zones工作。

現在來看看 Xen 和 KVM(簡化版):

GK 是 Guest Kernel,在 Xen 裡的 domU 執行 guest OS。有些箭頭是指控制路徑(control-path,元件相互通訊,同步或非同步,以傳輸更多的資料。資料路徑(data-path)在某些場景下可能會在共享記憶體或環形緩衝區執行。 配置的方法可以有好幾種。比如,Xen 可以使用Isolated Driver Domains(IDD)或stub-domains,在隔離區裡執行 I/O Proxy。

使用 Xen,hypervisor 為 domains 執行 CPU 排程,每個 domain 對執行緒排程都有自己 OS 核心。Hypervisor 支援不同的 CPU 排程類,包括 Borrowed Virtual Time (BVT)、Simple Earliest Deadline First (SEDF) 和 Credit-Based。Domain 使用 OS 核心排程器,以及 domain 提供的任何正規的排程類及策略。

多個排程器的額外開銷會影響效能。多個排程器可能會在互動中產生複雜的問題,在錯誤的情景下增加 CPU 延遲。除錯它們會非常困難,特別是當 Xen hypervisor 用盡常見的 OS 效能工具資源(用 xentrace )。

通過 I/O proxy 程序(一般是 qemu)傳送 I/O 會帶來上下文交換(context-switching)和更多開銷。我們需要做大量的工作來儘可能減少開銷,包括共享記憶體傳輸、緩衝、I/O 合併(coalescing)和半虛擬化(paravirtualization)驅動程式等。

使用 KVM,hypervisor 是一個核心模組(kvm),由 OS 排程器來排程。Hypervisor 可以使用常見的 OS 核心排程器類、策略和優先順序等進行調優。KVM 的 I/O 路徑要比 Xen 少幾步。(最初的 Qumranet KVM 論文 說相比Xen,KVM需要五步,當時的描述裡沒考慮半虛擬化)

使用 Zones,就沒有上述類似的比較了。它的 I/O 路徑(對高速網路很敏感)沒有這些多餘的步驟。這在Solaris社群(Zones是Solaris的技術)和 FreeBSD 社群(Zones基於 FreeBSD jails 版)應是耳熟能詳了。Linux社群也在學習它們並開發屬於自己的版本:Linux Containers。Glauber Costa 在 Linuxcon 2012 大會的演講裡介紹了它,題目是“

有時你(或我們的客戶)的確是需要用到硬體虛擬化技術,因為他們的應用程式依賴於某個特定版本的Linux核心或Windows。針對這種情況,我們提供KVM給客戶(我們淘汰了Xen)。

內部情況(Internals)

讓我們深入研究看看它們如何工作的(經常使用DTrace)

Network I/O, Zones

下面的兩個 stack traces 顯示了一個網路包如何通過 global zone(host,即裸機安裝)傳輸到一個zone(guest)中:

  Global Zone:                            Zone:
  mac`mac_tx+0xda                         mac`mac_tx+0xda
  dld`str_mdata_fastpath_put+0x53         dld`str_mdata_fastpath_put+0x53
  ip`ip_xmit+0x82d                        ip`ip_xmit+0x82d
  ip`ire_send_wire_v4+0x3e9               ip`ire_send_wire_v4+0x3e9
  ip`conn_ip_output+0x190                 ip`conn_ip_output+0x190
  ip`tcp_send_data+0x59                   ip`tcp_send_data+0x59
  ip`tcp_output+0x58c                     ip`tcp_output+0x58c
  ip`squeue_enter+0x426                   ip`squeue_enter+0x426
  ip`tcp_sendmsg+0x14f                    ip`tcp_sendmsg+0x14f
  sockfs`so_sendmsg+0x26b                 sockfs`so_sendmsg+0x26b
  sockfs`socket_sendmsg+0x48              sockfs`socket_sendmsg+0x48
  sockfs`socket_vop_write+0x6c            sockfs`socket_vop_write+0x6c
  genunix`fop_write+0x8b                  genunix`fop_write+0x8b
  genunix`write+0x250                     genunix`write+0x250
  genunix`write32+0x1e                    genunix`write32+0x1e
  unix`_sys_sysenter_post_swapgs+0x14     unix`_sys_sysenter_post_swapgs+0x14

我用了一些方法以及很多時間,反覆檢查我沒有弄錯,因為上面它們兩個是完全一樣的。的確,右邊顯示的棧的結果和左邊路徑一樣。

你也可以配置Zones,讓它又一些開銷,象一般的系統一樣。比如,啟動為網路I/O設定的防火牆,或者使用lofs掛載一個檔案系統而不用直接掛載。這些都是可選的操作,對於某些使用者案例也許會值得耗費一些額外的效能開銷。

Network I/O, KVM

顯示網路I/O的完整程式碼路徑非常複雜。

第一部分是guest程序寫到它自己的驅動裡。這種情況,我演示一個帶有  的 Linux Fedora guest,並且跟蹤 paravirt 驅動:

guest# dtrace -n 'fbt:virtio_net:start_xmit:entry { @[stack(100)] = count(); }'
dtrace: description 'fbt:virtio_net:start_xmit:entry ' matched 1 probe
^C
[...]
              kernel`start_xmit+0x1
              kernel`dev_hard_start_xmit+0x322
              kernel`sch_direct_xmit+0xef
              kernel`dev_queue_xmit+0x184
              kernel`eth_header+0x3a
              kernel`neigh_resolve_output+0x11e
              kernel`nf_hook_slow+0x75
              kernel`ip_finish_output
              kernel`ip_finish_output+0x17e
              kernel`ip_output+0x98
              kernel`__ip_local_out+0xa4
              kernel`ip_local_out+0x29
              kernel`ip_queue_xmit+0x14f
              kernel`tcp_transmit_skb+0x3e4
              kernel`__kmalloc_node_track_caller+0x185
              kernel`sk_stream_alloc_skb+0x41
              kernel`tcp_write_xmit+0xf7
              kernel`__alloc_skb+0x8c
              kernel`__tcp_push_pending_frames+0x26
              kernel`tcp_sendmsg+0x895
              kernel`inet_sendmsg+0x64
              kernel`sock_aio_write+0x13a
              kernel`do_sync_write+0xd2
              kernel`security_file_permission+0x2c
              kernel`rw_verify_area+0x61
              kernel`vfs_write+0x16d
              kernel`sys_write+0x4a
              kernel`sys_rt_sigprocmask+0x84
              kernel`system_call_fastpath+0x16
             2015

上面便是 Linux 3.2.6 網路傳輸的路徑。

控制部分由 KVM 傳給 qemu I/O proxy,然後用常見的方式(native driver)在host OS上傳輸。這裡是 SmartOS 棧的情況:

host# dtrace -n 'fbt::igb_tx:entry { @[stack()] = count(); }'
dtrace: description 'fbt::igb_tx:entry ' matched 1 probe
^C
[...]
              igb`igb_tx_ring_send+0x33
              mac`mac_hwring_tx+0x1d
              mac`mac_tx_send+0x5dc
              mac`mac_tx_single_ring_mode+0x6e
              mac`mac_tx+0xda
              dld`str_mdata_fastpath_put+0x53
              ip`ip_xmit+0x82d
              ip`ire_send_wire_v4+0x3e9
              ip`conn_ip_output+0x190
              ip`tcp_send_data+0x59
              ip`tcp_output+0x58c
              ip`squeue_enter+0x426
              ip`tcp_sendmsg+0x14f
              sockfs`so_sendmsg+0x26b
              sockfs`socket_sendmsg+0x48
              sockfs`socket_vop_write+0x6c
              genunix`fop_write+0x8b
              genunix`write+0x250
              genunix`write32+0x1e
              unix`_sys_sysenter_post_swapgs+0x149
             1195

上述兩個棧開始都非常得複雜。然後有一些相關的會執行在 Linux kernelillumos kernel 中,它們會更加複雜。基本上,paravirt 程式碼路徑讓這兩個 kernel stack 得以“緊密接觸”。

當 Joyent 的Robert Mustacchi 深入研究了上述的程式碼路徑後,他畫了如下非常形象的 ASCII 圖以幫助理解:

/*
 *                  GUEST                        #       QEMU
 * #####################################################################
 *                                               #
 *    +----------+                               #
 *    |  start_  | (1)                           #
 *    |  xmit()  |                               #
 *    +----------+                               #
 *         ||                                    #
 *         ||       +-----------+                #
 *         ||------>|free_old_  | (2)            #
 *         ||------>|xmit_skbs()|                #
 *         ||       +-----------+                #
 *         \/                        (3)         #
 *    +---------+        +-------------+     + - #--- PIO write to VNIC
 *    |  xmit_  |------->|virtqueue_add|     |   #    PCI config space (6)
 *    |  skb()  |------->|_buf_gfp()   |     |   #
 *    +---------+        +-------------+     |   #
 *        ||                                 |   # +- VM exit
 *        ||         +- iff interrupts       |   # |  KVM driver exit (7)
 *        \/         |  unmasked (4)         |   # |
 *    +---------+    |     +-----------+(5)  |   # |  +---------+
 *    |virtqueue|----*---->|vp_notify()|-----*---#-*->| handle  | (8)
 *    |_kick()  |----*---->|           |-----*---#-*->|PIO write|
 *    +---------+          +-----------+         #    +---------+
 *        ||                                     #        ||
 *        ||   (13)                              #        ||
 *        **-----+ iff avail ring                #        \/      (9)
 *        ||       capacity < 20                 # +-----------------+
 *        ||       else return                   # |virtio_net_handle|
 *        ||                                     # |tx_timer()       |
 *        \/   (14)                              # +-----------------+
 *    +----------+                               #  ||
 *    |netif_stop|                               #  ||             (10)
 *    |_queue()  |                               #  ||   +---------+
 *    +----------+                               #  ||-->|qemu_mod_|
 *        ||                                     #  ||-->|timer()  |
 *        ||     (15)                 (16)       #  ||   +---------+
 *    +----------------+     +----------+        #  ||
 *    |virtqueue_enable|---->|unmask    |        #  ||              (11)
 *    |_cb_delayed()   |---->|interrupts|        #  ||  +------------+
 *    +----------------+     +----------+        #  |+->|virtio_     |
 *        ||                   ||                #  +-->|queue_set_  |
 *        || (18)              ||       (17)     #      |notification|
 *        ||  +-return   +-------------------+   #      +------------+
 *        ||  | iff ---->|check if the number|   #       |
 *        **--+ is false |of unprocessed used|   #       |  disable host
 *        ||             |ring entries is >  |   #       +- interrupts
 *        ||             |3/4s of the avail  |   #          (12)
 *        \/   (19)      |ring index - the   |   #
 *   +-----------+       |last freed used    |   #
 *   |free_old_  |       |ring index         |   #
 *   |xmit_skbs()|       +-------------------+   #
 *   +-----------+                               #
 *        ||                                     #
 *        ||     (20)                            #
 *        **-----+ iff avail ring                #
 *        ||       capacity is                   #
 *        ||       now > 20                      #
 *        \/                                     #
 *   +-----------+                               #
 *   |netif_start| (21)                          #
 *   |_queue()   |                               #
 *   +-----------+                               #
 *        ||                                     #
 *        ||                                     #
 *        \/  (22)               (23)            #
 *   +------------+      +----------+            #
 *   |virtqueue_  |----->|mask      |            #
 *   |disable_cb()|----->|interrupts|            #
 *   +------------+      +----------+            #
 *                                               #
 *                                               #
 */
		  Figure II: Guest / Host Packet TX Part 1

我引用上圖只是讓你大概感覺裡面發生了些什麼。而且上面只是一部分(Part 1)。

簡單來說,它(KVM)使用在共享記憶體中的 ring buffer 傳輸資料,一個提醒機制會告知何時可以準備傳輸資料。當萬事如計劃開始工作時,效能就非常不錯。它沒有裸金屬那麼快(或者如Zones那麼快),但是也沒那麼差。我會在這篇後面引用一些數字來佐證。

CPU 開銷和降低的網路效能是需要注意的。此外因為上面介紹過的複雜性,使得分析和效能調查都比較困難。如果使用 Zones,那麼只用研究和調優一個核心 TCP/IP 棧(kernel TCP/IP stack)。因為其複雜性,一個就夠啦!如果用 KVM,那麼有兩個不同的核心 TCP/IP 棧,加上 KVM 和 paravirt。調研效能會耗時十倍於Zones。因為太長,所以一般都被禁止。這是為什麼在我的表格裡,我要引入“可觀察性(Observability)”這個概念作為一個重要的特性。因為越難看到的,就越難去調優。

Network I/O, Xen

Guest 傳輸和 I/O proxy 傳輸一樣,裡面的情況更加複雜。不能使用OS裡可觀察或除錯的工具對hypervisor進行檢查,因為它直接執行在裸金屬級別。有一個工具叫 xentrace,也許很有用,因為在 Xen 排程器中編寫的很多事件型別都使用靜態探針(static probes)。(但它不是如 DTrace 那樣實時觀測且可程式設計,而且需要我再去學另外一個 Tracer 工具)

/proc, Zones

當 I/O 路徑預設是0額外開銷時,作業系統虛擬化還有一些開銷,通常是因為管理或觀測需要,且它們並不在 CPU 或 I/O 的 “熱門路徑” 中。

比如,在同一個系統中用 prstat(1M),top(1) 之類的讀 /proc,一個 Zone 是看不到其他 guest 系統的 /proc 資訊。下面是 usr/src/uts/common/fs/proc/prvnops.c 的片段:

static int
pr_readdir_procdir(prnode_t *pnp, uio_t *uiop, int *eofp)
{
[...]
        /*
         * Loop until user's request is satisfied or until all processes
         * have been examined.
         */
        while ((error = gfs_readdir_pred(&gstate, uiop, &n)) == 0) {
                uint_t pid;
                int pslot;
                proc_t *p;

                /*
                 * Find next entry.  Skip processes not visible where
                 * this /proc was mounted.
                 */
                mutex_enter(&pidlock);
                while (n < v.v_proc &&
                    ((p = pid_entry(n)) == NULL || p->p_stat == SIDL ||
                    (zoneid != GLOBAL_ZONEID && p->p_zone->zone_id != zoneid) ||
                    secpolicy_basic_procinfo(CRED(), p, curproc) != 0))
                        n++;
[...]

從上看出,完整的程序資訊列表被掃描,但只有本地的 Zone 程序資訊被返回。聽上去有點低效,難道不能在 proc_t 上加個連結串列,這樣 Zone 程序就能直接得到了?當然可以,但讓我們用數字來說話。

下面是使用 prstat(1M) 命令從 Zone 裡讀 /proc ,讀取時間用DTrace來測算:

# dtrace -n 'fbt::pr_readdir_procdir:entry /execname == "prstat"/ {
    self->ts = timestamp; } fbt::pr_readdir_procdir:return /self->ts/ {
    @["ns"] = avg(timestamp - self->ts); self->ts = 0; }'
dtrace: description 'fbt::pr_readdir_procdir:entry ' matched 2 probes
^C
  ns                                                           544584

平均而言,需要 544 us (微秒)

現在在另一個 Zone 裡有額外的 1000 個程序(代表12個典型的額外的 guest ):

# dtrace -n 'fbt::pr_readdir_procdir:entry /execname == "prstat"/ {
   self->ts = timestamp; } fbt::pr_readdir_procdir:return /self->ts/ {
   @["ns"] = avg(timestamp - self->ts); self->ts = 0; }'
dtrace: description 'fbt::pr_readdir_procdir:entry ' matched 2 probes
^C
  ns                                                           594254

這樣增加了 50 微秒。對於一個 /proc 讀操作,算不上是熱路徑(hot path)。如果這樣的話,那 50 微秒的時間不算短,我們可以再來看看。(我還檢查了 pidlock global,現在沒什麼問題,DTrace也檢查過)

網路吞吐量結果

一般來說,我都會再三檢查數字是否有問題,再分享效能測試結果。但我現在沒有足夠的時間(因為這篇本來想寫的簡短點)。我會分享一些我幾個月前的資料,那時我仔細地做了測試,有詳細的效能結果:

這兒有一系列的網路吞吐量和用 iperf 測試 IOPS 的結果,用來測試預設安裝 1 Gbyte SmartOS Zones 和 CentOS KVM 例項的不同表現(沒有測試 Xen)。客戶機和伺服器都在同一個資料中心內,但是沒有在同一個物理主機,也就是說用到了所有的網路棧。

我可以明確這些測試並沒有為我們的雲做最優化的配置,實際上是個最低配置 minimum config (1 Gbyte instances)。如果這是個市場宣傳的行為,那麼我很可能將測試結果除錯到對我們最有利。也就是說,對於 SmartOS 核心,會做大量的工作,可以線性驅動多個 10 GbE 埠,需要客戶機生成大量的負載來測試。

對於這些結果,視負載、平臺核心型號、調優情況不同,每個人所得最終結果可能不盡相同。如果你要使用它們,請仔細思考如何應用它們到何種程度。如果你的負載是受限於 CPU 或檔案系統,那麼你最好不要測試它們的效能,可考慮使用網路的測試結果。

伺服器端一個典型的呼叫:

iperf -s -l 128k

客戶端

iperf -c server -l 128k -P 4 -i 1 -t 30

執行緒計數 (-P) 根據調查情況有所不同。最終結果(每個測試時間平均超過30秒)如下。

吞吐量

搜尋最高的 Gbits/sec:

sourcedestthreadsresultsuspected limiter
SmartOS 1 GBSmartOS 1 GB12.75 Gbits/secclient iperf @80% CPU, and network latency
SmartOS 1 GBSmartOS 1 GB23.32 Gbits/secdest iperf up to 19% LAT, and network latency
SmartOS 1 GBSmartOS 1 GB44.54 Gbits/secclient iperf over 10% LAT, hitting CPU caps
SmartOS 1 GBSmartOS 1 GB81.96 Gbits/secclient iperf LAT, hitting CPU caps
KVM CentOS 1 GBKVM CentOS 1 GB1400 Mbits/secnetwork/KVM latency (dest 60% of the 1 VCPU)
KVM CentOS 1 GBKVM CentOS 1 GB2394 Mbits/secnetwork/KVM latency (dest 60% of the 1 VCPU)
KVM CentOS 1 GBKVM CentOS 1 GB4388 Mbits/secnetwork/KVM latency (dest 60% of the 1 VCPU)
KVM CentOS 1 GBKVM CentOS 1 GB8389 Mbits/secnetwork/KVM latency (dest 70% of the 1 VCPU)

Zones 峰值效能是 4個執行緒,4.54 Gbits/sec。更多的執行緒會達到 1 Gbyte (小型例項)的 CPU 瓶頸,那麼 CPU 排程延遲會引發 TCP 故障。更大的 SmartOS 例項有更高的 CPU 瓶頸,能夠獲得更好的效能。

對於 KVM 測試,我們使用預設的 CentOS 例項。我知道有更新的 Linux 核心,對 網路棧的調優也會更好,不過我們可以之後再去提高相應的吞吐量。我能達到的最高值是對於 1 VCPU KVM Linux 可達到 900 Mbits/sec(這是我們用大量的 DTrace 分析後,對 KVM 從  調優後達到的)。即使達到了 900 Mbits/sec 的速度,還是隻能到 Zones 的 1/5。

請注意“suspected limiter”列(可能的限制因素)。這對於確認實際測試結果很關鍵,來源於 。這意味著我對於每個結果都做了效能分析(包括為了節省空間沒有列在這裡的)。如果你有疑問,你可以花上一整天來進行所有的測試並分析每一個結果(使用 DTrace)。

IOPS

尋找那些最高的 packets/sec:

sourcedestthreadsresultsuspected limiter
SmartOS 1 GBSmartOS 1 GB114000 packets/secclient/dest thread count (each thread about 18% CPU total)
SmartOS 1 GBSmartOS 1 GB223000 packets/secclient/dest thread count
SmartOS 1 GBSmartOS 1 GB436000 packets/secclient/dest thread count
SmartOS 1 GBSmartOS 1 GB860000 packets/secclient/dest thread count
SmartOS 1 GBSmartOS 1 GB1678000 packets/secboth client & dest CPU cap
KVM Centos 1 GBKVM Centos 1 GB11180 packets/secnetwork/KVM latency, thread count (client thread about 10% CPU)
KVM Centos 1 GBKVM Centos 1 GB22300 packets/secnetwork/KVM latency, thread count
KVM Centos 1 GBKVM Centos 1 GB44400 packets/secnetwork/KVM latency, thread count
KVM Centos 1 GBKVM Centos 1 GB87900 packets/secnetwork/KVM latency, thread count (threads now using about 30% CPU each; plenty idle)
KVM Centos 1 GBKVM Centos 1 GB1613500 packets/secnetwork/KVM latency, thread count (~50% idle on both)
KVM Centos 1 GBKVM Centos 1 GB3218000 packets/secCPU (dest >90% of the 1 VCPU)

以上情況下,Zones 比 KVM 快4倍。同理,受限因素是雲 CPU,我只測試了小型的 1 Gbyte 的伺服器。更大的伺服器有更高的 CPU 配額,那麼所有的結果會擴充套件得到的更高的值。

結論

在這篇文章裡,我總結了三種虛擬化技術(Zones, Xen, KVM)的效能特徵,進一步調研了它們的 I/O 路徑。Zones 沒有額外開銷,但是 Xen 和 KVM 都有。這些開銷可能會限制網路吞吐量到原有的1/4。

預設情況下,我們鼓勵使用者部署 Zones,為了效能、可觀察性、簡單(可調式性)。這意味著要為 SmartOS(我們基於 illumos 的作業系統,託管 Zones)編譯使用者的程式。萬一使用者必須要用 Linux 或者 Windows,或其之上應用程式,那麼可以使用硬體虛擬化(KVM)。

還有更多的效能特徵可以考慮,這裡我沒有探討,只是簡要地給了一些表格,包括 CPU如何分配,VCPU如何工作,記憶體分配如何工作,檔案系統如何快取等等。這些在後續的日誌中會繼續討論。

這篇文章本來想過多地討論 DTrace,但是它對於高效能運算是一個必備的工具,無法不提及。我們用它來提升 Zones 和 KVM 的整體效能、跟蹤延遲異常、解釋基準測試結果、研究多租戶的影響,並提高應用程式和作業系統的效能。