GFS架构启示 | Google File System
第一篇,GFS(Google File System)架構啟示。
GFS是什么?
Google早期研發的分布式文件系統。
畫外音:與分布式文件系統對應的,是單機文件系統,Windows和Linux操作系統都有文件系統。
?
GFS的設計目標是什么?
主要有四個目標:
(1)?高可用(availability);
(2)?高可靠(reliability);
(3)?高性能(performance);
(4)?可擴展(scalability);
畫外音:WaCaLe,這些詞都被架構師用爛了,簡單解釋一下。
高可用,是指7*24提供服務,任何一臺機器掛了或者磁盤壞了,服務不終止,文件不丟失;
高可靠,是指爭取的輸入,得到正確的輸出,讀取a文件,不會得到b文件;
高性能,是指吞吐量很牛逼,每秒響應幾十萬請求;
可擴展,是指加機器,就能提升性能,就能存更多文件;
額,希望這個解釋是通俗的。
?
GFS對外提供什么接口?
文件創建,刪除,打開,關閉,讀,寫,快照。
畫外音:
除了快照,接口和單機文件系統差不多。
快照其實是快速文件目錄樹的拷貝,并不是所有文件的快照。
GFS能夠成為分布式架構的經典案例,原因之一,就是接口簡單,但反映的架構理念不簡單。
?
GFS的系統架構如何?
系統里只有文件客戶端,主服務器,存儲服務器三個角色。
如上圖:
(1)?客戶端(GFS client),是以庫的形式提供的,提供的就是對外要用的接口;
(2)?主服務器(GFS master),是單點,存儲文件信息,目錄信息,文件服務器信息,那個文件存在哪些文件服務器上等元數據;
(3)?存儲服務器(GFS chunk-server),是集群,存儲文件;
畫外音:角色簡單,但反映的架構理念不簡單。
?
為什么要設計單點master?
單點master意味著有一個節點可以避免分布式鎖,可以擁有全局視野,能夠統一調度與監控,系統整體復雜度降低很多。
畫外音:鎖可以降級成本地鎖,分布式調度可以降級為單點調度。
?
更具體的:
(1) master擁有所有文件目錄結構,要操作某個文件,必須獲得相應的鎖;
畫外音:一般情況下,不會對同一個網頁進行并發寫操作,應用場景決定鎖沖突其實不大;
(2) master擁有全局視野,能夠避免死鎖;
(3) master知道chunk-server的信息,能夠很容易的做chunk-server監控,負載均衡;
(4) master知道所有文件的副本分布信息,能夠很容易的做文件大小的負載均衡;
畫外音:負載均衡分為請求量的均衡,文件存儲的容量均衡。
?
GFS的高可用是怎么保證的?
高可用又分為服務高可用,文件存儲高可用,均通過“冗余+自動故障轉移”的思路是實現。
(1)?master高可用:冗余了一臺影子master,平時不工作,master掛了工作,以保證master的高可用;
畫外音:master資源利用率只有50%。
(2)?chunk-server高可用:本身是集群,冗余服務;
畫外音:當有chunk-server掛掉,master能檢測到,并且知道哪些文件存儲在chunk-server上,就可以啟動新的實例,并復制相關文件。
(3)?文件存儲高可用:每一份文件會存三份,冗余文件;
?
GFS的高性能是怎么保證的?
多個chunk-server可以通過線性擴展提升處理能力和存儲空間,GFS的潛在瓶頸是單點master,所以GFS要想達到超高性能,主要架構優化思路在于,“提升master性能,減少與master交互”。
?
(1) 只存儲元數據,不存儲文件數據,不讓磁盤容量成為master瓶頸;
(2) 元數據會存儲在磁盤和內存里,不讓磁盤IO成為master瓶頸;
(3) 元數據大小內存完全能裝得下,不讓內存容量成為master瓶頸;
(4) 所有數據流,數據緩存,都不走master,不讓帶寬成為master瓶頸;
(5) 元數據可以緩存在客戶端,每次從客戶端本地緩存訪問元數據,只有元數據不準確的時候,才會訪問master,不讓CPU成為成為master瓶頸;
?
當然,chunk-server雖然有多個,也會通過一些手段提升chunk-server的性能,例如:
(1) 文件塊使用64M,避免太多碎片降低性能;
(2) 使用追加寫,而不是隨機寫,提升性能;
(3) 使用TCP長連接,提升性能;
?
GFS如何保證系統可靠性?
保證元數據與文件數據的可靠性,GFS使用了很多非常經典的手段。
(1) 元數據的變更,會先寫日志,以確保不會丟失;
畫外音:日志也會冗余,具備高可用。
(2) master會輪詢探測chunk-server的存活性,保證有chunk-server失效時,chunk-server的狀態是準確的;
畫外音:文件會存多份,短時間內chunk-server掛掉是不影響的。
(3) 元數據的修改是原子的,由master控制,master必須保證元數據修改的順序性;
(4) 文件的正確性,通過checksum保證;
(5) 監控,快速發現問題;
?
讀操作的核心流程?
文件讀取是最高頻的操作。
(1) client讀本地緩存,看文件在哪些chunk-server上;
(2) 如果client本地緩存miss,詢問master文件所在位置,并更新本地緩存;
(3) 從一個chunk-server里讀文件,如果讀取到,就返回;
?
寫操作的核心流程?
寫操作會復雜很多。
?
為了保證數據高可用,數據必須在多個chunk-server上寫入多個副本,首先要解決的問題是,如何保證多個chunk-server上的數據是一致的呢?
想想一個MySQL集群的多個MySQL實例,是如何保證多個實例的數據一致性的。bingo!確定一個主實例,串行化所有寫操作,然后在其他實例重放相同的操作序列,以保證多個實例數據的一致性。
?
GFS也采用了類似的策略,一個文件冗余3份,存在3個chunk-server上,如下圖步驟1-7:
(1) client訪問master,要發起文件寫操作;
畫外音:假設client本地緩存未生效;
(2) master返回數據存儲在ABC三個實例上,并且告之其中一個實例是主chunk-server;
(3) client將數據流傳遞給所有chunk-server;
(4) client將控制流產地給主chunk-server;
(5) 主chunk-server進行本地操作串行化,并將序列化后的命令發送給其他chunk-server;
(6) 其他chunk-server按照相同的控制流對數據進行操作,并將結果告訴主chunk-server;
(7) 主chunk-server收到其他所有chunk-server的成果執行結果后,將結果返回client;
畫外音:MySQL的主庫是寫瓶頸,GFS不會出現這樣的問題,每個文件的主chunk-server是不同的,所以每個實例的寫請求也是均衡的。
?
這里需要說明的是,GFS對于寫操作,執行的是最保守的策略,必須所有chunk寫成功,才會返回client寫成功(寫吞吐會降低);這樣的好處是,讀操作只要一個chunk讀取成功,就能返回讀成功(讀吞吐會提升)。
畫外音:這也符合R+W>N的定理,N=3份副本,W=3寫3個副本才算成功,R=1讀1個副本就算成功。R+W>N定理未來再詳述。
?
之所以這么設計,和文件操作“讀多寫少”的特性有關的,Google抓取的網頁,更新較少,讀取較多,這也是一個設計折衷的典型。
畫外音:任何脫離業務的架構設計都是耍流氓。
?
除此之外,這里還有一個“數據流與控制流分離”的設計準則:
(1) 控制流數據量小,client直接與主chunk-server交互;
(2) 數據流數據量大,client選擇“最近的路徑”發送數據;
畫外音:所謂“最近”,可以通過IP的相似度計算得到。
?
總結
GFS的架構,體現了很多經典的設計實踐:
-
簡化系統角色,單點master降低系統復雜度
-
不管是文件還是服務,均通過“冗余+故障自動轉移”保證高可用
-
由于存在單點master,GFS將“降低與單點master的交互”作為性能優化核心
-
通過寫日志,原子修改,checksum,快速監控快速恢復等方式保證可靠性與完整性
-
通過串行化保證多個副本數據的一致性
-
控制流與數據流分離,提高性能
畫外音:GFS還有一些優化細節也挺有意思,文章未能窮盡。
總結
以上是生活随笔為你收集整理的GFS架构启示 | Google File System的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 什么是线程安全,你真的了解吗?
- 下一篇: Google MapReduce到底解决