一個偉大的問題誕生在 mechanical-sympathy Google郵件列表,或許已經(jīng)有許多其他的偉大的問題誕生在此了。問題如下:
我不斷地聽說Docker,就好像他是切片面包以來最偉大的發(fā)明一樣,但是我還聽說低延遲應用在使用它的時候遭受打擊。
沒有誰比Azul Systems的技術副總裁、首席技術官和聯(lián)合創(chuàng)始人Gil Tene更適合回答這個問題了。就像我們相信喬丹的三步上欄一樣,我們總能依靠Gil的洞察力,參見下面的文章:
系統(tǒng)地去除Linux操作系統(tǒng)抖動的黑魔法
你的載荷生成器可能騙了你——吃下紅藥丸然后找出原因
下面是Gil的答案:
拋開問題的品味和風格不說,單說延遲效果(原始的問題),從機制角度來分析,答案很簡單:Docker使用Linux容器作為執(zhí)行方式?jīng)]有對CPU和內(nèi)存的操作系統(tǒng)虛擬層,有可選的(即使缺省是打開的)對I/O的虛擬層。
CPU和內(nèi)存
從延遲的角度來說,Docker(和其他Linux容器)的CPU和內(nèi)存延遲特性不能夠和Linux自身區(qū)分出來,但是對Linux有效的控制遲延行為對Docker也有效。
如果你想要清楚和一致的低延遲,你必須做不用Docker和不用容器時相同的工作來獲得相同級別的一致性。例如,如果你想讓整個系統(tǒng)盡在掌握(沒有饑餓的鄰居),你也不得不在主機這個層次為Docker做工作。
如果你需要分隔套接字或者內(nèi)核和選擇哪些進程在哪里,對Docker容器或者其中的線程,你也要做相同的事。
如果你使用非統(tǒng)一內(nèi)存存?。∟UMA, Non-Uniform Memory Access),或者使用任何類型的直接的NUMA驅動的內(nèi)存分配,你也要做相同的事。
并且,你需要做的一些事情可能看起來違反一些人想要的部署Docker的模式。但是,如果你真正對一致性的低延遲感興趣,你或許需要擺脫現(xiàn)有工具集,使用不同的控制組(cgroups)、任務設置(tasksets)和其他酷的工具來確保事情的安排。然而,即使你做了這些事情,你也不能夠區(qū)分容器內(nèi)外的進程的CPU和內(nèi)存的延遲。
I/O
磁盤I/O
在不同配置下的I/O行為是許多延遲問題產(chǎn)生和解答的原因。對于磁盤I/O行為和選項我也所知甚少,不能談論太多。但我確定解決任何存儲吞吐量和延遲敏感問題的答案是“越過虛擬層和邏輯分區(qū),直接訪問磁盤和掛接點”。
網(wǎng)絡
網(wǎng)絡的情形相當清楚:如果你想要網(wǎng)絡地理位置無關、網(wǎng)絡地址翻譯(NAT, Network Address Translation)或橋接、自動生成的網(wǎng)絡等功能,你或許會為網(wǎng)絡延遲或吞吐量(相比Linux上直接真實物理網(wǎng)卡)付出代價。然而,也有為Docker配置低成本或基本上零延遲成本的網(wǎng)絡鏈路的選項(再一次,可能與一些人想要的部署方式不同)。使用宿主機的網(wǎng)絡或者專用IP地址和網(wǎng)卡,你將獲得比缺省的橋接網(wǎng)絡更好的性能。但你將會遇到配置Solarflare的網(wǎng)卡(在裸金屬低延遲環(huán)境中很普遍)、繞過內(nèi)核、專用自旋核心網(wǎng)絡協(xié)議棧等相關的事宜。這些延遲相關的行為與是在宿主機上還是用Docker沒有分別。
Docker(作為一個整體屬于用戶空間)不是把大雜燴裝進一個盒子,客機(guest OS)作為一個整體的虛擬化方案也不是。確實,他們都能夠這樣用(經(jīng)常是這樣),但是使用他們的最大益處是發(fā)布一致的精心選擇的配置,還有開發(fā)、測試和部署都使用相同配置的能力。后者可以容易地管理發(fā)布和版本(包括回滾),還有實現(xiàn)如“彈性大小”這樣的酷的事情。其他配置工具(puppet或者shef等)當然也能得到相同的結果(假定他們控制你的鏡像中的一切),但是把可以工作的東西打包在一起開箱即用確實是很誘人的事。
我知道有使用一個宿主機上只有一個客機這樣虛擬化方案的人們(例如,AWS r3.8加大實例類型目前大概就是這樣的)。也知道有采用相同方式使用Docker的人們(一個宿主機一個容器)。這兩種用例是為了配置控制和部署,不是為了節(jié)約成本而把東西打包。
低延遲這件事現(xiàn)在變成了“它更糟嗎?”這個問題。相比較基于宿主機和客機或KVM的虛擬化方案,在低延遲這個問題上,只要做正確的選擇(專用網(wǎng)卡、內(nèi)核和設備),Docker帶來的損害更少,真正的不可察覺。