【分布式系統】-2-GFS

MIT的【分布式系統課程】學習記錄

內容純屬個人學習過程中的筆記記錄,如果有侵權現象請留言,會立刻刪除

分布式存儲系統的難點

設計大型存儲系統的出發點:利用數百臺計算機資源同時完成大量工作,達到性能加成

  • 如何做?數據分割,從并行的多臺服務器上讀取數據【分片(Sharding)】
  • 由于大量分片,故障會成常態。需要一個自動的容錯系統,而不是每次都人工介入【容錯(fault tolerance)】
  • 實現容錯的最有用方式之一就是復制,維護2-3個副本,其中一個故障了還能用另一個【復制(replication)】
  • 多份數據副本時,就會存在【不一致問題(inconsistency)】
  • 通過設計可避免不一致問題,但需要不同服務器之間網絡額外的交互,會降低性能,所以想要一致性,代價就是【低性能

如果想要好的一致性,就需犧牲一定性能,如果不想付出代價,就需要忍受一些不確定行為

GFS的設計目標:大型、快速的文件系統

  • 全局有效,這樣不同應用程序都可(申請權限)然后從中讀取數據【共享

  • 大容量、高速】,包含數據的文件會被GFS自動分割存放在多個服務器上,寫操作會很快

  • 可以【自我修復

  • 只在一個數據中心運行

  • 對大型順序文件的讀寫進行定制。GFS只順序處理,不支持隨機訪問,關注點在于吞吐量大

GFS Master:Active-Standby模式,只有一個Master節點在工作

  • Master節點保存了文件名和存儲位置的對應關系【Master管理文件和Chunk信息
  • 還有大量的Chunk服務器,每一個Chunk服務器上都有1-2塊磁盤【Chunk存儲實際數據

將兩類數據的管理問題完全隔離,Master節點知道每一個文件對應的所有的Chunk的ID,Chunk每個是64MB大小,共同構成了一個文件

如果我有一個1GB的文件,那么Master節點就知道文件的第一個Chunk存儲在哪,第二個Chunk存儲在哪,等等。當我想讀取這個文件中的任意一個部分時,我需要向Master節點查詢對應的Chunk在哪個服務器上,之后我可以直接從Chunk服務器讀取對應的Chunk數據

  • Master節點內保存的數據內容:主要是兩個表單

    • 第一個是文件名到Chunk ID或者Chunk Handle數組的對應。這個表單主要講文件對應了哪些Chunk ID

    • 第二個表單記錄了Chunk ID到Chunk數據的對應關系。這里的數據又包括:

      • 每個Chunk存儲在哪些服務器上

      • 每個Chunk當前的版本號

      • 所有對于Chunk的寫操作都必須在主Chunk(Primary Chunk)上順序處理,主Chunk是Chunk的多個副本之一。所以,Master節點必須記住哪個Chunk服務器持有主Chunk

      • 主Chunk只能在特定的租約時間內擔任主Chunk,Master節點要記住主Chunk的租約過期時間

以上數據都存儲在內存中,如果Master故障了,這些數據就都丟失了。為了能讓Master重啟而不丟失數據,Master節點會同時將數據存儲在磁盤上。所以Master節點讀數據只會從內存讀,但是寫數據的時候,至少有一部分數據會接入到磁盤中。更具體來說,Master會在磁盤上存儲log,每次有數據變更時,Master會在磁盤的log中追加一條記錄,并生成CheckPoint(類似于備份點)。

有些數據需要存在磁盤上,而有些不用:

  • Chunk Handle的數組(第一個表單)要保存在磁盤上
  • Chunk服務器列表不用保存到磁盤上。因為Master節點重啟之后可以與所有的Chunk服務器通信,并查詢每個Chunk服務器存儲了哪些Chunk,所以不用寫入磁盤
  • 版本號要不要寫入磁盤取決于GFS是如何工作的
  • 主Chunk的ID,幾乎可以確定不用寫入磁盤,因為Master節點重啟之后會忘記誰是主Chunk,它只需要等待60秒租約到期,那么它知道對于這個Chunk來說沒有主Chunk,這個時候,Master節點可以安全指定一個新的主Chunk
  • 租約過期時間也不用寫入磁盤

這里在磁盤中維護log而不是數據庫的原因是,數據庫本質上來說是某種B樹(b-tree)或者hash table,相比之下,追加log會非常的高效,因為你可以將最近的多個log記錄一次性的寫入磁盤。因為這些數據都是向同一個地址追加,這樣只需要等待磁盤的磁碟旋轉一次。而對于B樹來說,每一份數據都需要在磁盤中隨機找個位置寫入。所以使用Log可以使得磁盤寫入更快一些

當Master節點故障重啟,需要重建它的狀態,所以Master節點會在磁盤中創建一些checkpoint點,這可能要花費幾秒甚至一分鐘。這樣Master節點重啟時,會從log中的最近一個checkpoint開始恢復,再逐條執行從Checkpoint開始的log,最后恢復自己的狀態

GFS 讀文件:

  • GFS客戶端會選擇一個網絡上最近的服務器發送 一個文件名 + 想從文件某個位置讀取的偏移量 給Master節點
  • Master節點從自己的file表單中查詢文件名,得到Chunk ID數組,每個Chunk是64MB,偏移量/64MB就是從數組中得到對應的Chunk ID
  • Master節點從Chunk表單中找Chunk服務器列表,返回給客戶端

GFS 寫文件:

  • 客戶端向Master節點發送請求,想向這個文件名對應的文件追加數據,請告訴我文件中最后一個Chunk的位置

    多個客戶端同時寫同一個文件時,客戶端不知道文件究竟多長。此時,客戶端可以向Master節點查詢哪個Chunk服務器保存了文件的最后一個Chunk

  • 讀文件可以從任何最新的Chunk副本讀取數據,但是寫文件必須要通過Chunk的主副本(Primary Chunk)來寫入。所以,寫文件時需要考慮Chunk的主副本不存在的情況

    對于Master節點來說,如果發現Chunk的主副本不存在,Master會找出所有存有Chunk最新副本的Chunk服務器

    如果你的一個系統已經運行了很長時間,那么有可能某一個Chunk服務器保存的Chunk副本是舊的,比如說還是昨天或者上周的。導致這個現象的原因可能是服務器因為宕機而沒有收到任何的更新。所以,Master節點需要能夠在Chunk的多個副本中識別出,哪些副本是新的,哪些是舊的。所以需要找出新的Chunk副本

? 當客戶端想要對文件進行追加,但是又不知道文件尾的Chunk對應的Primary在哪時,Master會等所有存儲了 最新Chunk版本的服務器集合完成,然后挑選一個作為Primary,其他的作為Secondary

  • 之后,Master會增加版本號,并將版本號寫入磁盤,這樣就算故障了也不會丟失這個數據

  • 接下來,Master節點會向Primary和Secondary副本對應的服務器發送消息并告訴它們,誰是Primary,誰是Secondary,Chunk的新版本是什么。Primary和Secondary服務器都會將版本號存儲在本地的磁盤中。這樣,當它們因為電源故障或者其他原因重啟時,它們可以向Master報告本地保存的Chunk的實際版本號

  • Primary可以接收來自客戶端的寫請求,并將寫請求應用在多個Chunk服務器中。之所以要管理Chunk的版本號,是因為這樣Master可以將實際更新Chunk的能力轉移給Primary服務器。并且在將版本號更新到Primary和Secondary服務器之后,如果Master節點故障重啟,還是可以在相同的Primary和Secondary服務器上繼續更新Chunk。

  • Master節點通知Primary和Secondary服務器,可以修改這個Chunk。它還給Primary一個租約,這個租約告訴Primary說,在接下來的60秒中,你將是Primary,60秒之后你必須停止成為Primary。這種機制可以確保我們不會同時有兩個Primary

    假設現在Master節點告訴客戶端誰是Primary,誰是Secondary,GFS提出了一種聰明的方法來實現寫請求的執行序列。客戶端會將要追加的數據發送給Primary和Secondary服務器,這些服務器會將數據寫入到一個臨時位置。所以最開始,這些數據不會追加到文件中。當所有的服務器都返回確認消息說,已經有了要追加的數據,客戶端會向Primary服務器發送一條消息說,你和所有的Secondary服務器都有了要追加的數據,現在我想將這個數據追加到這個文件中。Primary服務器或許會從大量客戶端收到大量的并發請求,Primary服務器會以某種順序,一次只執行一個請求。對于每個客戶端的追加數據請求(也就是寫請求),Primary會查看當前文件結尾的Chunk,并確保Chunk中有足夠的剩余空間,然后將客戶端要追加的數據寫入Chunk的末尾。并且,Primary會通知所有的Secondary服務器也將客戶端要追加的數據寫入在它們自己存儲的Chunk末尾。這樣,包括Primary在內的所有副本,都會收到通知將數據追加在Chunk的末尾。

  • Secondary可能可以執行成功,也可能會執行失敗,比如說磁盤空間不足,比如說故障了,比如說Primary發出的消息網絡丟包了。如果Secondary實際真的將數據寫入到了本地磁盤存儲的Chunk中,它會回復“yes”給Primary。如果所有的Secondary服務器都成功將數據寫入,并將“yes”回復給了Primary,并且Primary也收到了這些回復。Primary會向客戶端返回寫入成功。如果至少一個Secondary服務器沒有回復Primary,或者回復了,但是內容卻是:抱歉,一些不好的事情發生了,比如說磁盤空間不夠,或者磁盤故障了,Primary會向客戶端返回寫入失敗。

如果客戶端從Primary得到寫入失敗,那么客戶端應該重新發起整個追加過程。客戶端首先會重新與Master交互,找到文件末尾的Chunk;之后,客戶端需要重新發起對于Primary和Secondary的數據追加操作。

GFS 一致性:

追加數據時,面對Chunk的三個副本,當客戶端發送了一個追加數據的請求,要將數據A追加到文件末尾,所有的三個副本,包括一個Primary和兩個Secondary,都成功的將數據追加到了Chunk,所以Chunk中的第一個記錄是A,假設第二個客戶端加入進來,想要追加數據B,但是由于網絡問題發送給某個副本的消息丟失了。所以,追加數據B的消息只被兩個副本收到,一個是Primary,一個是Secondary。這兩個副本都在文件中追加了數據B,所以,現在我們有兩個副本有數據B,另一個沒有。之后,第三個客戶端想要追加數據C,并且第三個客戶端記得下圖中左邊第一個副本是Primary。Primary選擇了偏移量,并將偏移量告訴Secondary,將數據C寫在Chunk的這個位置。三個副本都將數據C寫在這個位置。

對于數據B來說,客戶端會收到寫入失敗的回復,客戶端會重發寫入數據B的請求。所以,第二個客戶端會再次請求追加數據B,或許這次數據沒有在網絡中丟包,并且所有的三個副本都成功追加了數據B。現在三個副本都在線,并且都有最新的版本號。

之后,如果一個客戶端讀文件,讀到的內容取決于讀取的是Chunk的哪個副本。客戶端總共可以看到三條數據,但是取決于不同的副本,讀取數據的順序是不一樣的。如果讀取的是第一個副本,那么客戶端可以讀到A、B、C,然后是一個重復的B。如果讀取的是第三個副本,那么客戶端可以讀到A,一個空白數據,然后是C、B。所以,如果讀取前兩個副本,B和C的順序是先B后C,如果讀的是第三個副本,B和C的順序是先C后B。所以,不同的讀請求可能得到不同的結果。

或許最壞的情況是,一些客戶端寫文件時,因為其中一個Secondary未能成功執行數據追加操作,客戶端從Primary收到寫入失敗的回復。在客戶端重新發送寫文件請求之前,客戶端就故障了。所以,可能進入這種情形:數據D出現在某些副本中,而其他副本則完全沒有。

在GFS的這種工作方式下,如果Primary返回寫入成功,那么一切都還好,如果Primary返回寫入失敗,就不是那么好了。Primary返回寫入失敗會導致不同的副本有完全不同的數據。

GFS這樣設計的理由是足夠的簡單,但是同時也給應用程序暴露了一些奇怪的數據。這里希望為應用程序提供一個相對簡單的寫入接口,但應用程序需要容忍讀取數據的亂序。如果應用程序不能容忍亂序,應用程序要么可以通過在文件中寫入序列號,這樣讀取的時候能自己識別順序,要么如果應用程序對順序真的非常敏感那么對于特定的文件不要并發寫入。例如,對于電影文件,你不會想要將數據弄亂,當你將電影寫入文件時,你可以只用一個客戶端連續順序而不是并發的將數據追加到文件中。

如果想要將GFS升級成強一致系統,需要考慮的事情:

  • 需要讓Primary來探測重復的請求,這樣第二個寫入數據B的請求到達時,Primary就知道,我們之前看到過這個請求,可能執行了也可能沒執行成功。Primay要嘗試確保B不會在文件中出現兩次。所以首先需要的是探測重復的能力。
  • 對于Secondary來說,如果Primay要求Secondary執行一個操作,Secondary必須要執行而不是只返回一個錯誤給Primary。對于一個嚴格一致的系統來說,是不允許Secondary忽略Primary的請求而沒有任何補償措施的。所以我認為,Secondary需要接受請求并執行它們。如果Secondary有一些永久性故障,例如磁盤被錯誤的拔出了,你需要有一種機制將Secondary從系統中移除,這樣Primary可以與剩下的Secondary繼續工作。但是GFS沒有做到這一點,或者說至少沒有做對。
  • 當Primary要求Secondary追加數據時,直到Primary確信所有的Secondary都能執行數據追加之前,Secondary必須小心不要將數據暴露給讀請求。所以對于寫請求,你或許需要多個階段。在第一個階段,Primary向Secondary發請求,要求其執行某個操作,并等待Secondary回復說能否完成該操作,這時Secondary并不實際執行操作。在第二個階段,如果所有Secondary都回復說可以執行該操作,這時Primary才會說,好的,所有Secondary執行剛剛你們回復可以執行的那個操作。這是現實世界中很多強一致系統的工作方式,這被稱為兩階段提交(Two-phase commit)。
  • 另一個問題是,當Primary崩潰時,可能有一組操作由Primary發送給Secondary,Primary在確認所有的Secondary收到了請求之前就崩潰了。當一個Primary崩潰了,一個Secondary會接任成為新的Primary,但是這時,新Primary和剩下的Secondary會在最后幾個操作有分歧,因為部分副本并沒有收到前一個Primary崩潰前發出的請求。所以,新的Primary上任時,需要顯式的與Secondary進行同步,以確保操作歷史的結尾是相同的。
  • 最后,時不時的,Secondary之間可能會有差異,或者客戶端從Master節點獲取的是稍微過時的Secondary。系統要么需要將所有的讀請求都發送給Primary,因為只有Primary知道哪些操作實際發生了,要么對于Secondary需要一個租約系統,就像Primary一樣,這樣就知道Secondary在哪些時間可以合法的響應客戶端。

為了實現強一致,需要增加了系統的復雜度,增加了系統內部組件的交互

許多Google的基礎架構,例如BigTable和MapReduce是構建在GFS之上,所以GFS在Google內部廣泛被應用。它最嚴重的局限可能在于,它只有一個Master節點,會帶來以下問題:

  • Master節點必須為每個文件,每個Chunk維護表單,隨著GFS的應用越來越多,這意味著涉及的文件也越來越多,最終Master會耗盡內存來存儲文件表單。你可以增加內存,但是單臺計算機的內存也是有上限的。所以,這是人們遇到的最早的問題。
  • 除此之外,單個Master節點要承載數千個客戶端的請求,而Master節點的CPU每秒只能處理數百個請求,尤其Master還需要將部分數據寫入磁盤,很快,客戶端數量超過了單個Master的能力。
  • 另一個問題是,應用程序發現很難處理GFS奇怪的語義
  • 最后一個問題是,GFS論文中,Master節點的故障切換不是自動的。GFS需要人工干預來處理已經永久故障的Master節點,并更換新的服務器,這可能需要幾十分鐘甚至更長的而時間來處理。對于某些應用程序來說,這個時間太長了。

(所以我們才需要多副本,多活,高可用,故障自修復的分布式系統啊)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/74078.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/74078.shtml
英文地址,請注明出處:http://en.pswp.cn/web/74078.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

黑盒測試的場景法(能對項目業務進行設計測試點)

定義: 通過運用場景來對系統的功能點或業務流程的描述,設計用例遍歷場景,驗證軟件系統功能的正確性從而提高測試效果的一種方法。 場景法一般包含基本流和備用流。 基本流:軟件功能的正確流程,通常一個業務只存在一個基本流且基本流有一個…

22 安裝第三方包

一、什么是第三方包 在 Python 的世界里,包就像是一個個功能強大的工具箱,它將多個 Python 模塊收納其中,而每個模塊又蘊含著豐富多樣的具體功能。可以說,一個包就是一系列同類功能的集合體,它們就像緊密協作的團隊&a…

MyBatisPlus不等于如何使用

在 MyBatis Plus 中&#xff0c;ne 方法用于構建不等于條件的 SQL 查詢。以下是 ne 方法的詳細用法&#xff1a; 基本用法 ne 方法可以用于 QueryWrapper 或 LambdaQueryWrapper 中&#xff0c;用于指定某個字段的值不等于指定的值。它對應于 SQL 中的 ! 或 <> 操作符。 …

[學術][人工智能] 001_什么是神經網絡?

神經網絡是一種模擬生物神經系統的計算模型&#xff0c;具有廣泛的應用和重要的研究價值。以下將從不同方面詳細介紹神經網絡。 一、神經網絡的發展歷程 20 世紀 60 年代&#xff0c;Hubel 和 Wiesel 在研究貓腦皮層中發現了用于局部敏感和方向選擇的神經元結構&#xff0c;卷積…

Unity3D仿星露谷物語開發32之地面屬性決定角色動作

1、目標 根據地面屬性&#xff08;diggable, canDropItem, canPlaceFurniture, isPath, isNPCObstacle&#xff09;決定角色進行何種操作。比如沒有canDropItem屬性的地面&#xff0c;則不能放置物體。 2、優化保存Item數據 PS&#xff1a;這個是對已有代碼的優化&#xff0…

031-valgrind

valgrind 以下是從原理到代碼實現、參數優化及結果分析的Valgrind技術調研報告&#xff0c;結合C示例和可視化工具使用說明&#xff1a; 一、Valgrind核心原理與架構 1.1 系統架構 #mermaid-svg-xIgV3fg90dGhEEq4 {font-family:"trebuchet ms",verdana,arial,sans-…

C/C++藍橋杯算法真題打卡(Day12)

一、P8752 [藍橋杯 2021 省 B2] 特殊年份 - 洛谷 算法代碼&#xff1a; #include<bits/stdc.h> using namespace std; int cnt;int main() {int i1;while(i<5){int num;cin>>num;string string_numto_string(num);if(string_num[0]string_num[2]&&str…

MySQL 復制與主從架構(Master-Slave)

MySQL 復制與主從架構&#xff08;Master-Slave&#xff09; MySQL 復制與主從架構是數據庫高可用和負載均衡的重要手段。通過復制數據到多個從服務器&#xff0c;既可以實現數據冗余備份&#xff0c;又能分擔查詢壓力&#xff0c;提升系統整體性能與容錯能力。本文將詳細介紹…

《大模型部署》——ollama下載及大模型本地部署(詳細快速部署)

ollama Ollama 是一款開源跨平臺的大語言模型&#xff08;LLM&#xff09;運行工具&#xff0c;旨在簡化本地部署和管理 AI 模型的流程。 下載ollama 進入官網下載https://ollama.com/ 選擇需要的系統下載 下載完成后直接進行安裝 下載大模型 選擇想要部署的模型&#…

Java關于包和final

什么是包&#xff1f; 包就是文件夾。用來管理等各種不同功能的java類&#xff0c;方便后期代碼維護 包名的規則&#xff1a;公司域名反寫包的作用&#xff0c;需要全部英文小寫&#xff0c;見名知意。例如&#xff1a;com.pdsu.domain package com.pdsu.demain;public class…

數據層的基本操作

1.數據層的更名: Arcmap內容列表中,數據框所包含的每個圖層及每個圖層所包含的一系列地理要素,都有相應的描述字符與之對應.默認情況下,添加進地圖的圖層是以其數據源的名字命名的,而地理要素的描述就是要素類型字段取值.由于這些命名影響到用戶對數據的理解和地圖輸出時的圖例…

Vue舞臺劇

Vue 的舞臺劇比喻 &#x1f3ad;&#xff08;完整表格版&#xff09; Vue 結構及路由管理 Vue 結構比喻&#xff08;舞臺劇&#xff09;&#x1f3ad;作用index.html空白場地 &#x1f3df;?Vue 負責填充內容&#xff0c;提供 #app 容器&#xff0c;等待演出開始。main.js導…

【Windows】win10系統安裝.NET Framework 3.5(包括.NET 2.0和3.0)失敗 錯誤代碼:0×80240438

一、.NET3.5(包括.NET 2.0和3.0)安裝方式 1.1 聯網安裝(需要聯網,能訪問微軟,簡單,很可能會失敗) 1.2 離線安裝-救急用(需要操作系統iso鏡像文件,復雜,成功幾率大) 二、聯網安裝 通過【控制面板】→【程序】→【程序和功能】→【啟用或關閉Windows功能】 下載過程…

Android學習總結之RecyclerView補充篇

在 Android 開發中&#xff0c;列表數據更新的性能一直是關鍵痛點。傳統的 notifyDataSetChanged() 會觸發全量刷新&#xff0c;導致不必要的界面重繪。而 DiffUtil 作為 Android 提供的高效差異計算工具&#xff0c;能精準識別數據變化&#xff0c;實現局部更新&#xff0c;成…

Miniforge3高效管理 Python環境:2025年最新實踐指南

Miniforge3 高效管理 Python 環境:2025 年最新實踐指南 在現代開發中,靈活高效地管理 Python 環境至關重要。Miniforge3 作為一款輕量級 Conda 管理工具,不僅默認采用更新更快的 conda-forge 軟件源,還對 ARM 架構(例如 Apple M1/M2/M3)有著出色的適配性。相比于傳統的 …

山東大學軟件學院項目創新實訓開發日志(4)之中醫知識問答數據存儲、功能結構、用戶界面初步設計

目錄 數據庫設計&#xff1a; 功能設計&#xff1a; 用戶界面: 數據庫設計&#xff1a; --對話表 (1個對話包含多條消息) CREATE TABLE conversations ( conv_id VARCHAR(36) PRIMARY KEY, -- 對話ID user_id VARCHAR(36) NOT NULL, -- 所屬用戶 title VARCHAR(100), -- 對話…

交換機、路由器、VLAN、單臂路由、三層交換、STP

華為模擬安裝 1.依次安裝wincap 2.wireshark 3.virtual box 4.ensp 一、設置 1.virtual box設置 2.計算機防火墻允許以上程序 3.eNSP設置 路由器&#xff1a;AR2240 交換機&#xff1a;S5700、CE12800 防火墻USG6000V 交換機 一、交換機工作原理 1、回顧 二層交換機…

【藍橋杯】每日練習 Day15

目錄 前言 奶牛選美 分析 代碼 大臣的旅費 分析 代碼 飛機降落 分析 代碼 母親的牛奶 分析 代碼 掃雷 分析 代碼 前言 雖為誕辰&#xff0c;但也不忘完成每日的訓練。 今天給大家帶來五道dfs的題目&#xff0c;包括組合數&#xff0c;連通塊&#xff0c;數的…

ipconfig、ping、ipconfig/all 4個常用 **Windows終端(CMD)命令** 的詳細解釋

ipconfig、ping、ipconfig/all 4個常用 Windows終端&#xff08;CMD&#xff09;命令 的詳細解釋、用途分析和使用示例 1. ipconfig 作用 快速查看本地網絡連接的 IP地址、子網掩碼、默認網關 等基礎信息。 示例輸出 Windows IP 配置無線局域網適配器 WLAN:IPv4 地址 . . .…

@emotion/css + react+動態主題切換

1.下載插件 npm install --save emotion/css 2.創建ThemeContext.tsx // src/ThemeContext.tsx import React, { createContext, useContext, useState } from "react";// 定義主題類型 export type Theme "light" | "dark";// 定義主題上下…