分佈式系統的問題

本文內容翻譯自《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所示):

  1. 你的請求可能已經丟失(多是某人拔掉了網線)。
  2. 你的請求可能正在隊列中等待,稍後會被髮送(也許網絡或收件人過載)。
  3. 遠程節點可能失敗(可能崩潰或掉電)。
  4. 遠程節點可能暫時中止了響應(可能正在經歷長時間的垃圾回收暫停;請參閱第295頁上的「進程暫停」),但稍後它會再次開始響應。
  5. 遠程節點可能處理了你的請求,但響應在網絡上丟失了(多是網絡交換機配置錯誤)。
  6. 遠程節點可能已經處理了你的請求,但響應已經延遲而且將稍後發送(多是網絡或你本身的機器過載)。

圖8-1 若是你發送了一個請求沒有獲得響應,沒法區分是發生瞭如下哪一種狀況:(a)請求丟失了(b)對方節點宕機(c)響應丟失了

發送方甚至沒法知道數據包是否已經被髮送:惟一的選擇是讓接收方發送響應消息,這可能會丟失或延遲。這些問題在異步網絡中難以區分:你擁有的惟一信息是你還沒有收到響應。若是你向另外一個節點發送請求而且未收到回覆,也沒法知道是什麼緣由。

處理該問題一般的方法是使用超時:一段時間後就放棄等待並假設響應不會送達。可是,當發生超時時,你仍然不知道遠程節點是否收到了你的請求(若是請求仍然在某個地方排隊,它仍然可能會被傳送給接收方,即便發送方已經放棄了)。

網絡故障實踐

幾十年來咱們一直在創建計算機網絡——人們可能但願如今咱們已經知道了如何使它們變得可靠。可是,彷佛咱們尚未成功。

有一些系統的研究和大量的軼事證據代表,即便在由公司運營的數據中心那樣的受控環境中,網絡問題也可能很是廣泛。在一家中等規模的數據中心進行的一項研究發現,每月大約發生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所示)。在繁忙的網絡鏈路上,數據包可能須要等待一段時間才能得到一個槽(這稱爲網絡擁塞)。若是傳入的數據太多以致於交換機隊列填滿,數據包將被丟棄,所以須要從新發送數據包,即便網絡運行良好。

圖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頁的「響應時間保證」)。更高的硬件利用率也是使用虛擬機的重要動機。

若是資源是靜態分區的(例如,專用硬件和專用帶寬分配),則在某些環境中可實現延遲保證。可是,這是以下降利用率爲代價的。換句話說,它是更昂貴的。另外一方面,動態資源分配下的多租戶提供了更好的利用率,因此它更便宜,但它具備可變延遲的缺點。

網絡中的可變延遲不是天然規律,而僅僅是成本/收益折衷的結果。

可是,此類服務質量目前還沒有在多租戶數據中心和公有云或經過互聯網進行通訊時可用。當前部署的技術沒法讓咱們對網絡的延遲或可靠性作出任何保證:咱們必須假定網絡擁塞,排隊和無限延遲可能發生。所以,超時時間沒有「正確」的值,須要經過實驗肯定。

未完待續。。。

歡迎關注公衆號: FullStackPlan 獲取更多幹貨
相關文章
相關標籤/搜索