本文內容翻譯自《Designing Data-Intensive Applications》一書的第8章。
近幾章主要介紹系統如何處理錯誤。例如,我們討論了副本故障轉移,複製滯後和事務的併發控制。當我們理解實際系統中可能出現的各種邊界情況時,我們就能更好地處理它們。
前幾章雖然談論了很多關於錯誤的問題,但是還是太樂觀了。在本章中,我們將最悲觀地假設“任何可能出故障的,最終都會出故障”。
分散式系統程式設計與在單機上編寫軟體有本質區別——主要區別在於分散式系統中有很多新奇的可能出故障的方式。 本章中,我們將瞭解在實踐中出現的問題,並瞭解哪些我們可以依賴,哪些不行。
最後,作為工程師,我們的任務是構建能夠完成工作的系統(即滿足使用者所期望的保證),儘管各個部件都出錯了。 在第9章中,我們將看看可以在分散式系統中提供這種保證的演算法的一些示例。 但首先,在本章中,我們必須瞭解我們面臨的挑戰。
本章是對分散式系統中可能出現的問題的悲觀和沮喪的概述。 我們將研究網路問題(第277頁的“不可靠的網路”); 時鐘和時序問題(第287頁上的“不可靠的時鐘”); 我們將討論它們可以避免的程度。 所有這些問題造成的後果都會讓人迷惑,因此我們將探討如何思考分散式系統的狀態以及如何推理已發生的事情(第300頁的“知識,真相和謊言”)。
錯誤和部分故障
當你在單機上寫程式時,它通常會以一種可預測的方式執行:要麼正常工作,要麼無法工作。有bug的軟體可能會讓人覺得電腦出問題了(通常重新啟動就能解決問題),但大部分還是軟體寫得不好的後果。
沒有什麼根本原因能讓單機上的軟體表現得奇怪:當硬體正常工作時,相同的操作總是產生相同的結果(這是確定性的)。如果存在硬體問題(例如,記憶體損壞或聯結器鬆動),其後果通常是整個系統失效(例如“藍屏當機”,無法啟動)。具有良好軟體的單機通常功能完好或完全損壞,而不在兩者之間。
這是計算機設計中的一個慎重選擇:如果發生內部故障,我們寧願計算機完全崩潰,而不是返回錯誤的結果,因為錯誤的結果很難處理,並且令人困惑。因此,計算機隱藏了它們實現所依賴的模糊物理現實,並提出了一個理想化的系統模型,它可以與數學完美結合起來。CPU指令總是做同樣的事情; 如果你將一些資料寫入記憶體或磁碟,則該資料保持完好並且不會隨機損壞。 這種始終正確計算的設計目標可以追溯到第一臺數字計算機。
當你編寫執行在多臺計算機上並通過網路連線的軟體時,情況完全不同。 在分散式系統中,我們不再處於理想系統模型中 - 我們別無選擇,只能面對物理世界的混亂現實。 而在現實世界中,正如這個軼事所示,各種各樣的事情可能會出錯:
在我有限的經驗中,我處理過單個資料中心(DC)中的長時間網路分割槽,PDU(配電單元)故障,交換機故障,整個機架的意外電源故障,全DC主幹故障,全DC 電力故障和一位低血糖駕駛員將他的福特皮卡撞進空調系統。我甚至不是一個運維人員。——Coda Hale
在分散式系統中,可能出現這樣的情況,儘管系統的其他部分工作正常,但系統的某些部分可能會以某種不可預知的方式出故障。這就叫做部分故障。該問題的難點在於部分故障是不確定的:如果你試圖做任何包含多個節點和網路的事情,它可能有時工作正常,有時出現不可預知的故障。正如我們將要看到的,你可能甚至不知道某件事是否成功,因為訊息在網路中傳播所花費的時間也是不確定的!
這種不確定性和部分故障的可能性是分散式系統難以處理的原因。
雲端計算和超級計算
關於如何構建大型計算系統有一系列哲學:
-
規模的一端是高效能運算(HPC)領域。擁有數千個CPU的超級計算機通常用於計算密集型科學計算任務,如天氣預報或分子動力學(模擬原子和分子的運動)。
-
另一端是雲端計算,雲端計算沒有非常明確的定義,但通常與多租戶資料中心,連線IP網路的商品計算機(通常是乙太網),彈性/按需資源分配以及按時計費聯絡在一起。
有了這些哲學,處理錯誤的方法就非常不同了。在超級計算機中,作業通常會對其計算狀態不時地做檢查點到持久儲存上。如果一個節點發生故障,通常的解決方案是簡單地停止整個叢集工作負載。故障節點修復後,從上一個檢查點重新開始計算。因此,超級計算機更像是一臺單節點計算機而不是分散式系統:它通過升級為完全故障來處理部分故障 - 當系統的任何部分發生故障,簡單地讓整個系統崩潰(就像單機上的核心恐慌一樣)。
在本書中,我們重點介紹實現網際網路服務的系統,這些系統通常看起來與超級計算機有很大不同:
-
許多與網際網路有關的應用程式都是線上的,在某種意義上它們需要能夠隨時為使用者提供低延遲服務。服務不可用(例如,停止群集以進行修復)是不可接受的。相比之下,像天氣模擬這樣的離線(批處理)作業可以停止並重啟,而且影響很小。
-
超級計算機通常由專用硬體構建,其中每個節點都非常可靠,並且節點通過共享記憶體和遠端直接記憶體訪問(RDMA)進行通訊。另一方面,雲服務中的節點是由普通機器構建的,它們能以較低的成本提供相同的效能,但也具有較高的故障率。
-
大型資料中心網路通常基於IP和乙太網,以Clos拓撲排列來提供高對分頻寬。超級計算機通常使用專門的網路拓撲結構,例如多維網格和toruses,這為具有已知通訊模式的HPC工作負載提供了更好的效能。
-
系統越大,系統中有元件出故障的概率越高。隨著時間的推移,故障被修復,新的元件又出故障,但是在一個有數千個節點的系統中,認為系統中總是在發生故障是一個合理的假設。當錯誤處理策略不夠有效時,一個大型系統最終會花費大量的時間從故障中恢復,而不是做有用的工作。
-
如果系統可以容忍失敗的節點並且仍然作為一個整體繼續工作,這對於操作和維護是一個非常有用的特性:例如,可以執行滾動升級(參閱第4章),一次重啟一個節點,系統繼續為使用者提供服務而不中斷。在雲環境中,如果一臺虛擬機器執行不佳,可以將其殺死並請求一臺新的虛擬機器(希望新的虛擬機器速度更快)。
-
在地理分散式部署中(保持資料在地理位置上接近使用者以減少訪問延遲),通訊很可能通過網際網路進行,與本地網路相比,速度慢且不可靠。超級計算機通常假設它們的所有節點都靠近在一起。
如果我們想讓分散式系統工作,就必須接受部分故障的可能性,並在軟體中建立容錯機制。換句話說,我們需要從不可靠的元件中構建可靠的系統。(正如在第6頁的“可靠性”中所討論的那樣,沒有完美的可靠性,所以我們需要了解我們可以實際承諾的極限。)
即使在只有少數節點的小型系統中,考慮部分故障也很重要。在一個小型系統中,很可能大部分元件在大多數時間都正常工作。但是,遲早會有一部分系統出現故障,軟體將不得不以某種方式處理它。故障處理必須是軟體設計的一部分,並且軟體的操作員需要知道發生故障時軟體會出現什麼行為。
假定錯誤很少發生,並只往好的想是不明智的。考慮各種可能的錯誤(甚至是不太可能的錯誤),並在測試環境中人為地建立這些情況以檢視會發生什麼是非常重要的。在分散式系統中,抱著懷疑,悲觀和偏執的態度才能取得成功。
從不可靠的元件中構建可靠的系統
你可能會懷疑這是否有道理——直覺上,一個系統只能和其最不可靠的元件(它最薄弱的環節)一樣可靠。事實並非如此:事實上,從不太可靠的基礎構建更可靠的系統,這在計算中是一個古老的想法。 例如:
-
糾錯碼允許數字資料在通訊通道上準確傳輸,偶爾會出現某些位錯誤,例如由於無線網路上的無線電干擾。
-
IP(網際網路協議)是不可靠的:資料包可能丟失,延遲,重複或亂序。TCP(傳輸控制協議)在IP之上提供了一個更可靠的傳輸層:它確保丟失的資料包被重傳,消除重複,並且資料包被重新組裝為它們的傳送順序。
雖然系統可能比其基礎部分更可靠,但它的可靠性總是有限的。例如,糾錯碼可以處理少量的單位元錯誤,但是如果訊號被干擾所淹沒,那麼通過通訊通道可以獲得的資料量就有一個基本限制。TCP可以對我們隱藏資料包丟失,重複和亂序,但它不能在網路中奇蹟般地消除延遲。
雖然更可靠的更高階別的系統並不完美,但它仍然很有用,因為它可以處理一些棘手的低階故障,因此通常也可以更輕鬆地解決和處理其餘的故障。
不可靠的網路
正如在第二部分的介紹中所討論的,我們在本書中關注的分散式系統是shared-nothing系統:即一堆機器通過網路連線。網路是這些機器可以通訊的唯一方式。我們假設每臺機器有自己的記憶體和磁碟,一臺機器無法訪問另一臺機器的記憶體或磁碟(除了通過網路向服務發出請求外)。
shared-nothing並不是構建系統的唯一方式,但它已經成為構建網際網路服務的主要方式,原因有幾個:它相對便宜,因為它不需要特殊的硬體,可以利用商品化的雲端計算服務, 可以通過跨多個地理分佈的資料中心進行冗餘來實現高可靠性。
網際網路和資料中心的大部分內部網路(通常是乙太網)都是非同步分組網路。 在這種網路中,一個節點可以向另一個節點傳送一個訊息(一個資料包),但是網路不能保證它何時到達,甚至是否能到達。如果你傳送請求並期待響應,很多事情可能會出錯(其中一些如圖8-1所示):
- 你的請求可能已經丟失(可能是某人拔掉了網線)。
- 你的請求可能正在佇列中等待,稍後會被髮送(也許網路或收件人過載)。
- 遠端節點可能失敗(可能崩潰或掉電)。
- 遠端節點可能暫時停止了響應(可能正在經歷長時間的垃圾回收暫停;請參閱第295頁上的“程式暫停”),但稍後它會再次開始響應。
- 遠端節點可能處理了你的請求,但響應在網路上丟失了(可能是網路交換機配置錯誤)。
- 遠端節點可能已經處理了你的請求,但響應已經延遲並且將稍後傳送(可能是網路或你自己的機器過載)。
傳送方甚至無法知道資料包是否已經被髮送:唯一的選擇是讓接收方傳送響應訊息,這可能會丟失或延遲。這些問題在非同步網路中難以區分:你擁有的唯一資訊是你尚未收到響應。如果你向另一個節點傳送請求並且未收到回覆,也無法知道是什麼原因。
處理該問題通常的方法是使用超時:一段時間後就放棄等待並假設響應不會送達。但是,當發生超時時,你仍然不知道遠端節點是否收到了你的請求(如果請求仍然在某個地方排隊,它仍然可能會被傳送給接收方,即使傳送方已經放棄了)。
網路故障實踐
幾十年來我們一直在建立計算機網路——人們可能希望現在我們已經知道了如何使它們變得可靠。但是,似乎我們還沒有成功。
有一些系統的研究和大量的軼事證據表明,即使在由公司運營的資料中心那樣的受控環境中,網路問題也可能非常普遍。在一家中等規模的資料中心進行的一項研究發現,每個月大約發生12次網路故障,其中一半單臺機器斷開連線,一半整個機架斷開連線。另一項研究測量了架頂式交換機,匯聚交換機和負載平衡器等元件的故障率,發現新增冗餘網路裝置不會像你所希望的那樣減少故障,因為它不能防範人為錯誤(例如,配置錯誤的交換機),這是造成網路中斷的主要原因。
公共雲服務(如EC2)因頻繁出現短暫的網路故障而臭名昭著,管理良好的專用資料中心網路會比較穩定。儘管如此,沒有人能夠避免網路問題的干擾:例如,交換機軟體升級期間的問題可能會觸發網路拓撲重新配置,在此期間網路資料包可能會延遲超過一分鐘。鯊魚可能咬住海底電纜並損壞它們。其他令人驚訝的故障包括網路介面有時會丟棄所有入站資料包,但成功傳送出站資料包。因此,僅僅因為網路連結在一個方向上正常工作並不能保證它也在相反的方向也正常工作。
網路分割槽 當網路的一部分由於網路故障而與其餘部分斷開時,有時稱為網路分割槽或網路分割。 在本書中,我們使用更一般的術語網路故障,以避免與如第6章所述的儲存系統的分割槽(碎片)混淆。
即使你的環境中很少發生網路故障,但可能發生故障的事實意味著你的軟體需要能夠處理它們。網路上的通訊總有可能會失敗,這是沒有辦法的。
如果網路故障的錯誤處理未經過定義和測試,則可能會發生反覆無常的錯誤:例如,即使網路恢復,群集也可能會死鎖並永久無法為請求提供服務,甚至可能會刪除你的所有資料。如果軟體不在受控的情況下,可能會有意想不到的行為。
處理網路故障並不一定意味著容忍它們:如果你的網路通常相當可靠,則有效的方法可能是在網路遇到問題時向使用者簡單顯示錯誤訊息。但是,你需要知道你的軟體會對網路問題做出什麼反應,並確保系統能夠從中恢復。刻意地觸發網路問題並測試系統響應是有意義的(這是Chaos Monkey背後的想法;請參閱第6頁的“可靠性”)。
檢測故障
很多系統都需要自動檢測故障節點。 例如:
- 負載平衡器需要停止向死節點傳送請求。
- 在single-leader複製的分散式資料庫中,如果leader發生故障,需要提升一個follower成為新的leader(參閱第152頁的“處理節點故障”)。
不幸的是,網路的不確定性使得判斷一個節點是否正常工作變得很困難。在某些特定情況下,你可能會收到一些反饋資訊,以明確告訴你某些元件不正常工作:
-
如果你可以到達執行節點的機器,但沒有程式正在監聽目標埠(例如,因為程式崩潰),作業系統將通過傳送RST或FIN資料包來幫助關閉或拒絕TCP連線。但是,如果節點在處理請求過程中崩潰,你將無法知道遠端節點實際已經處理了多少資料。
-
如果節點程式崩潰(或被管理員殺死)但節點的作業系統仍在執行,指令碼可以通知其他節點有關崩潰的資訊,以便另一個節點可以快速接管而無需等待超時。
-
如果你有許可權訪問資料中心網路交換機的管理介面,則可以查詢它們以檢測硬體級別的鏈路故障(例如,遠端機器是否關閉電源)。如果你通過網際網路連線,或者你處於共享資料中心但無許可權無法訪問交換機,或者由於網路問題而無法訪問管理介面,則無法使用該選項。
-
如果路由器確定你嘗試連線的IP地址無法訪問,它可能會用ICMP目標無法訪問的資料包回覆你。但是,路由器不具備神奇的故障檢測能力——它受到與網路其他組成部分相同的限制。
-
遠端節點當機的快速反饋很有用,但你不能指望它。即使TCP確認資料包已傳送,應用程式在處理資料之前可能已崩潰。如果你想確認一個請求是成功的,需要在應用程式本身積極響應。
-
相反,如果出現問題,你可能會在某個層次上得到錯誤響應,但通常你必須假設根本得不到響應。你可以重試幾次(TCP重試是透明的,但您你可以在應用程式級別重試),等待超時過去,並且如果在超時範圍內沒有收到響應,才最終宣佈節點失效。
超時和無限延遲
如果超時是檢測故障的唯一可靠方法,那麼超時時間應該多長?不幸的是沒有簡單的答案。
超時時間長意味著需要長時間等待才能宣告一個節點死亡(並且在此期間,使用者可能不得不等待或看到錯誤訊息)。超時時間短可以更快地檢測到故障,但是會帶來更高的誤判的風險,例如節點可能只是暫時變慢(比如由於工作或網路負載高峰)就被誤判為死亡。
過早地宣告一個節點已經死亡是有問題的:如果節點實際上處於活動狀態並且正在執行一些操作(例如,傳送電子郵件),然後另一個節點接管,那麼該操作最終可能會執行兩次。我們將在第300頁的“知識,真相和謊言”以及第9章和第11章中更詳細地討論該問題。
當一個節點被宣告死亡時,其職責需要轉移到其他節點,這會給其他節點和網路帶來額外的負擔。如果系統已經處於高負載狀態,過早宣告節點死亡會使問題變得更糟。特別地,可能節點實際上並未死亡,只是由於負載太高而響應緩慢。將其負載轉移到其他節點可能會導致瀑布式的失敗(在極端情況下,所有節點都宣告對方死亡,然後一切都停止工作)。
假設一個虛擬系統的網路可以保證資料包的最大延遲——每個資料包要麼在一段時間內送達,要麼丟失,但時間永遠不會超過d。此外,假設可以保證非故障節點在總是在一段時間r內處理請求。在這種情況下,可以保證每個成功的請求都會在2d + r的時間內收到響應,並且如果在此時間內沒有收到響應,則知道網路或遠端節點不工作。如果情況真如上述那樣,2d + r將是一個合理的超時時間。
不幸的是,我們所使用的大多數系統都沒有這些保證:非同步網路具有無限的延遲(即它們儘可能快地傳送資料包,但資料包到達所需的時間沒有上限) ,並且大多數伺服器實現不能保證它們可以在特定時間內處理請求(請參閱“響應時間保證”(第298頁))。對於故障檢測,大部分時間內快是不夠的:如果超時時間較短,則往返時間只需要瞬間上升就會導致系統失去平衡。
網路擁塞和排隊
在開車汽車時,由於交通堵塞,在路上花的時間往往不盡相同。類似的,計算機網路上的資料包延遲的可變性通常也是由於排隊:
- 如果多個不同的節點同時嘗試向相同的目的地傳送資料包,則網路交換機必須將它們排隊並將它們逐個送入目標網路鏈路(如圖8-2所示)。在繁忙的網路鏈路上,資料包可能需要等待一段時間才能獲得一個槽(這稱為網路擁塞)。如果傳入的資料太多以至於交換機佇列填滿,資料包將被丟棄,因此需要重新傳送資料包,即使網路執行良好。
-
當資料包到達目標機器時,如果所有CPU核心當前都處於繁忙狀態,則來自網路的傳入請求將被作業系統排隊,直到應用程式準備好處理它為止。根據機器的負載情況,這可能需要一段任意長度的時間。
-
在虛擬化環境中,當另一個虛擬機器正在使用CPU核的時候,正在執行的作業系統通常會暫停幾十毫秒。在此期間,虛擬機器無法使用網路中的任何資料,因此輸入資料被虛擬機器監視器排隊(緩衝),這進一步增加了網路延遲的可變性。
-
TCP執行流量控制(也稱為擁塞避免或背壓),節點限制自己的傳送速率以避免網路鏈路或接收節點過載。這意味著甚至在資料進入網路之前,傳送者也會讓資料排隊。
此外,如果TCP在某個超時時間內未得到確認(根據觀察的往返時間計算),則認為資料包丟失,並且丟失的資料包將自動重新傳送。儘管應用程式沒有看到資料包丟失和重傳,但它確實會看到由此產生的延遲(等待超時過期,然後等待重傳的資料包得到確認)。
TCP與UDP
一些對延遲敏感的應用程式(如視訊會議和IP語音(VoIP))使用UDP而不是TCP。這是延遲的可靠性和可變性之間的折衷:由於UDP不執行流量控制並且不重傳丟失的資料包,所以它避免了一些可變網路延遲的原因(儘管它仍然易受交換機佇列和排程延遲的影響)。
在延遲資料毫無價值的情況下,UDP是一個不錯的選擇。例如,在VoIP電話呼叫中,可能沒有足夠的時間在其資料將在揚聲器上播放之前重新傳輸丟失的資料包。在這種情況下,重傳資料包沒有意義——應用程式必須用無聲填充丟失資料包的時隙(導致聲音短暫中斷),然後在資料流中繼續。相反,重試發生在人類層面。(“你能再說一遍嗎?剛剛沒聲音了。”)
所有這些因素都會造成網路延遲的變化。當系統接近其最大容量時,排隊延遲的範圍很大:擁有大量備用容量的系統可以輕鬆消化佇列,而在高度使用的系統中,很快就會排起長佇列。
在公有云和多租戶資料中心中,資源被許多客戶共享:網路鏈路和交換機,甚至每臺計算機的網路介面和CPU(在虛擬機器上執行時)都是共享的。批處理工作負載(如MapReduce)(請參閱第10章)可以輕鬆地使網路連結飽和。由於你無法控制或瞭解其他客戶對共享資源的使用情況,如果你身邊的某個人正在使用大量資源,網路延遲可能會變化無常。
在這樣的環境中,你只能通過實驗來選擇超時時間:在一個延長的週期中測試和多臺機器的網路往返時間分佈,以確定延遲可變性的期望。然後,考慮應用程式的特性,你可以在故障檢測延遲與過早超時風險之間確定一個適當的折衷。
更好的是,系統不是使用配置的常量超時,而是能夠連續測量響應時間及其變化(抖動),並根據觀察到的響應時間分佈自動調整超時。這可以用Phi Accrual故障檢測器完成,該檢測器在Akka和Cassandra中被使用。TCP重傳超時執行原理類似。
同步與非同步網路
如果我們可以依賴網路來傳遞具有固定最大延遲的資料包,而不是丟棄資料包,那麼分散式系統就會簡單得多。為什麼我們不能在硬體級別解決這個問題,並使網路可靠,以便軟體不必考慮這些問題?
為了回答這個問題,將資料中心網路與非常可靠的傳統固定電話網路(非蜂窩,非VoIP)進行比較是很有趣的:延遲音訊幀和掉話是非常罕見的。電話呼叫需要始終較低的端到端延遲和足夠的頻寬來傳輸語音的音訊樣本。在計算機網路中擁有類似的可靠性和可預測性不是很好嗎?
當你通過電話網路撥打電話時,它會建立一條線路:沿著兩個呼叫者之間的整個路由為呼叫分配固定的有保證的頻寬量。該線路保持佔用,直到通話結束。例如,ISDN網路以每秒4000幀的固定速率執行。呼叫建立後,每個幀內(每個方向)分配16位空間。因此,在通話期間,每一方都保證能夠每250微秒傳送一個精確的16位音訊資料。
這種網路是同步的:即使資料通過多個路由器,也不會受到排隊的影響,因為呼叫的16位空間已經在網路的下一跳中保留下來了。而且由於沒有排隊,網路的最大端到端延遲是固定的。我們稱之為有限的延遲。
我們不能簡單地使網路延遲可預測嗎?
請注意,電話網路中的線路與TCP連線非常不同:線路是固定數量的預留頻寬,線上路建立時沒有人可以使用,而TCP連線的資料包有機會使用任何可用的網路頻寬。你可以為TCP提供可變大小的資料塊(例如電子郵件或網頁),TCP會盡可能在最短的時間內傳輸它。當TCP連線空閒時,不使用任何頻寬。如果資料中心網路和網際網路是線路交換網路,那麼建立線路後可以確保最大往返時間。然而,它們並不是:乙太網和IP是分組交換協議,它們受到排隊的影響,從而導致網路無限延遲。這些協議沒有線路的概念。
為什麼資料中心網路和網際網路使用分組交換?答案是,它們針對突發流量進行了優化。一個電路適用於音訊或視訊通話,在通話期間需要每秒傳送相當恆定的位元數。另一方面,請求網頁,傳送電子郵件或傳輸檔案沒有任何特定的頻寬需求,我們只是希望它儘快完成。
如果你想通過線路傳輸檔案,則必須猜測頻寬分配。如果你猜的太低,傳輸速度會不必要的太慢,導致網路容量沒有使用。如果你猜得太高,線路就無法建立(因為如果無法保證其頻寬分配,網路不能建立線路)。因此,使用線路進行突發資料傳輸會浪費網路容量,並導致傳輸不必要的緩慢。相比之下,TCP會動態調整資料傳輸速率以適應可用的網路容量。
已經有一些嘗試構建支援線路交換和分組交換的混合網路,例如ATM。例如InfiniBand:它實現了鏈路層的端到端流量控制,減少了網路排隊的概率,儘管它仍然可能因鏈路擁塞而遭受延遲。通過謹慎使用服務質量(QoS,資料包的優先順序和排程)和准入控制(限速傳送器),可以模擬分組網路上的線路交換,或提供統計上有界的延遲。
延遲和資源使用
更一般地說,你可以將可變延遲視為動態資源分割槽的結果。
假設兩臺電話交換機之間有一條線路,可以同時進行10,000個呼叫。通過此線路切換的每個電路都佔用其中一個呼叫插槽。因此,你可以將線路視為可由多達10,000個併發使用者共享的資源。資源以靜態方式分配:即使你現在是線路上唯一的電話,並且所有其他9,999個插槽都未使用,你的線路仍將分配跟線路被充分利用時相同的固定數量的頻寬。
相比之下,網際網路動態分享網路頻寬。傳送者競爭以儘可能快地通過網路獲得它們的分組,並且網路交換機決定傳送哪個分組(即,頻寬分配)。這種方法有排隊的缺點,但優點是它最大限度地利用了線路。線路成本固定,所以如果你更充分地利用它,通過該線路傳送的每個位元組都更便宜。
CPU也會出現類似的情況:如果你在多個執行緒之間動態共享每個CPU核,則有時候一個執行緒必須在另一個執行緒執行時等待作業系統的執行佇列,因此執行緒可能被暫停不同的時間長度。但是,與為每個執行緒分配靜態數量的CPU週期相比,這會更充分地利用硬體(請參閱第298頁的“響應時間保證”)。更高的硬體利用率也是使用虛擬機器的重要動機。
如果資源是靜態分割槽的(例如,專用硬體和專用頻寬分配),則在某些環境中可實現延遲保證。但是,這是以降低利用率為代價的。換句話說,它是更昂貴的。另一方面,動態資源分配下的多租戶提供了更好的利用率,所以它更便宜,但它具有可變延遲的缺點。
網路中的可變延遲不是自然規律,而僅僅是成本/收益折衷的結果。
但是,此類服務質量目前尚未在多租戶資料中心和公有云或通過網際網路進行通訊時可用。當前部署的技術無法讓我們對網路的延遲或可靠性做出任何保證:我們必須假定網路擁塞,排隊和無限延遲可能發生。因此,超時時間沒有“正確”的值,需要通過實驗確定。
未完待續。。。