《大規模分布式存儲系統》讀書筆記(一)


序言

與單機環境下編程相比,分布式環境下的編程有兩點不同:

  1. 分布式環境下,會出現一部分計算機工作正常,另一部分計算機工作不正常的情況,程序需要在這種情況下盡可能地正常工作,挑戰非常大。
  2. 單機環境下,大部分函數采用同步調用;在分布式環境下,函數調用的返回時間可能是單機環境下的100倍,所以分布式環境下的RPC通常采用異步調用

 


 

第一章  概述

 1、分布式存儲分類

數據的種類大致可以分為三類:

  1. 非結構化數據,比如圖像,音頻,視頻等。
  2. 機構化數據,儲存在關系數據庫中,可以用關系表結構來表示的。
  3. 半結構化數據,模式化結構和內容混在一起,比如 HTML 文檔,XML。

 根據儲存數據種類的不同,可以將儲存系統分為以下幾類:

  1. 分布式文件系統,存儲非結構化數據,典型的系統有 Facebook Haystack,Taobao File Systen。
  2. 分布式鍵值系統,存儲關系簡單的半結構化數據,典型的有 Memcache 。
  3. 分布式表格系統,存儲關系較為復雜的半結構化數據, 典型的有 Google Bigtable 。
  4. 分布式數據庫,存儲結構化數據。典型的系統有 MySQL 。

 


 

第二章  單機存儲系統

1、硬件基礎

  傳統的數據中心網絡拓撲為三層結構,該網絡拓撲下,同一接入層下服務器之間帶寬相同,不同接入層的服務器帶寬會出現不一致的情況,因此,設計系統時需要考慮服務器是否在一個機架內。

  為了減少系統對網絡拓撲結構的依賴,可以采用三級 CLOS 網絡,使得任何兩台服務器之間的帶寬都相同。

2、單機存儲引擎

2.1  哈希存儲引擎

  Bitcask 是基於哈希表結構的鍵值存儲系統,僅支持追加操作。內存中采用的是基於哈希表的索引,哈希表結構中的每一項包含文件編號(file_id),value 在文件中的位置(value_pos),value 長度(value_sz)。通過讀取 file_id 對應的文件,從 value_pos 開始的 value_sz 個字節,就可得到 value 值。

 

2.2  B 樹存儲引擎

  葉子節點保存每行的完整數據,非葉子節點保存索引信息。數據庫查詢時從根節點開始二分查找到葉子節點,每次讀取節點時,如果節點不在內存中,需要從磁盤中讀取並緩存。

  緩沖區管理器會決定哪些頁面淘汰,緩沖區的替換策略有以下兩種:

  1. LRU,淘汰最長事件沒有讀或者寫的塊。
  2. LIRS,將緩沖池分為兩級,數據首先進入第一級,如果數據在較短時間內被訪問兩次或者以上,則成為熱點數據進入第一級,每一級內部還是采用LRU 算法。

 

 2.3  LSM樹存儲引擎

  LSM 樹就是將對數據的修改增量保持在內存中,達到指定大小后將這些修改操作批量寫入磁盤,讀取時需要合並磁盤中的歷史數據和內存中最近的修改操作。

  LevelDB 存儲引擎包括:內存中的 MemTable 和不可變的 MemTable。寫入記錄時,LevelDB 會先將修改操作寫入操作日志,之后再將修改操作應用到 MemTable,這樣就完成了寫入操作。MemTable 的大小達到上限值后,LevelDB 會將原先的 MemTable 變成不可變 MemTable,並重新生成新的MemTable,之后的修改操作記錄在新的 MemTable 中。同時 LevelDB 后台線程會將不可變 MemTable 的數據轉儲到磁盤。

 

3、故障恢復

  分布式系統一般使用操作日志技術來實現故障恢復。操作日志可以分為回滾日志(undo log)重做日志(redo log)。回滾日志記錄的是事務修改前的狀態,重做日志記錄的是事務修改之后的狀態。

3.1  操作日志

  為了數據庫數據的一致性,數據庫操作需要持久化到磁盤,如果每次操作都更新磁盤上的數據,系統性能會較差。操作日志上面記錄的就是每個數據庫操作,並在內存中執行這些操作,內存中的數據定時刷新到磁盤,就可以實現隨機寫請求轉化為順序寫請求。

3.2  重做日志

  使用 REDO 日志進行故障恢復,必須確保,在修改內存中的數據之前,把這一修改相關的操作日志刷新到磁盤上。這么做的原因在於,假設是先修改內存數據,如果在完成內存修改和寫入日志之間發生故障,那么最近的修改操作沒有辦法通過 REDO 日志恢復,用戶可能讀取到修改后的結果,出現不一致的情況。

3.3  成組提交

  之前說過,數據庫操作需要先寫入操作日志,但是如果每次操作都立即將操作日志刷人磁盤,系統性能會降低。因此可以先將 REDO 日志儲存在緩沖區,定期刷入磁盤。但這樣做,可能會丟失最后一部分數據庫操作。

3.4  檢查點 

  當內存不足,或者 REDO 日志的大小達到上限時,需要將內存中修改后的數據刷新到磁盤上,這種技術就是 checkpoint(檢查點)技術。同時系統會加入 checkpoint 時刻,以后的故障恢復只需要回放 checkpoint 時刻之后的 REDO 日志。

 


 第三章  分布式系統

1、基本概念

1.1  “超時”

  在分布式系統中,如果一個節點發起 RPC 調用,RPC 執行結果有三種:“成功”,“失敗”,“超時”。當出現超時狀態時,不能簡單的認為 RPC 操作失敗,只能通過不斷讀取之前操作的狀態來驗證 RPC 操作是否成功。當然,可以將系統設計為冪等性

 

1.2  一致性

  保證多個副本之間的一致性是分布式系統的核心。例如有 A,B,C 同時操作存儲系統,可以將一致性大致分別三種:

  1. 強一致性,A 寫入值,后續  A,B,C 讀取的都是最新值。
  2. 弱一致性,A 寫入值,不能保證后續  A,B,C 讀取的都是最新值。
  3. 最終一致性,A 寫入值,在后續沒有更新該值,則后續  A,B,C 讀取的都是最新值。有一個“不一致窗口”的概念。

2、數據分布

  分布式系統不同於傳統的單機系統,分布式系統能夠將數據分布到多個節點,在多個節點間實現負載均衡。以下介紹的是數據分布的兩種方式。

2.1  哈希分布

  哈希分布就是根據數據的某一特征計算哈希值,哈希值與服務器有映射關系,以此實現數據的分布。哈希分布的優劣取決於散列函數的特征,容易出現“數據傾斜”的問題。而且,當有服務器上線或者下線時,哈希映射會被打亂,會帶來大量的數據遷移。

  一致性哈希可以避免集群擴容造成的大量數據遷移問題。其思想是:系統中的每個節點都分配一個 token,這些 token 構成哈希環。儲存數據時,先計算數據的哈希值,然后存放到順時針第一個大於或者等於該哈希值的節點。這樣在增加、刪除節點時,只會影響到哈希環中相鄰的節點。一致性哈希可以采用虛擬節點的發放來實現負載均衡。

 

2.2  順序分布

  哈希分布實現數據分布時,不能支持順序掃描。順序分布可以提供連續的范圍掃描,一般做法是將大表順序分為連續的范圍,每個范圍一個子表。Bigtable 系統將索引分為兩級,Root 表和元數據 Meta 表,由 Meta 表維護 User 表的位置信息, Root 表維護 Meta 表的位置信息。

 

3、復制

3.1  復制的概念

  在分布式系統中,同一份數據有多個副本,其中一個副本為主副本,其他為備副本。復制時,由主副本將數據復制到備份副本。復制協議可以分為強同步復制和異步復制。

  強同步復制要求主備成功后才可以返回成功,可以保證強一致性,但是,復制時是阻塞寫操作,系統可用性較差。

  異步復制就是主副本不需要等待備副本的回應,只需要本地修改成功就可以返回成功。

  上述兩種復制協議都是主副本將數據發送給其他副本,當主副本出現故障時,需要選擇新的主副本。經典的選舉協議為 Paxos 協議。

 

3.2  一致性和可用性

  CAP 理論就是:一致性(Consistency),可用性(Availability),分區可容忍性(Tolerance of network Partition)三者不能同時滿足。

  分區可容忍性指的是在機器故障、網站故障等異常情況下仍然滿足一致性和可用性。

  設計存儲系統時需要在一致性和可用性之間權衡。如果采用強同步復制,保證系統的一致性,當主備副本之間出現故障時,寫操作被阻塞,系統的可用性將無法滿足。如果采用異步復制,保證了可用性,但無法做到一致性。

  Oracle 數據庫的 DataGuard 復制組件有三種模式,可以借鑒:

  1. 最大保護模式:即強同步模式
  2. 最大性能模式:即異步復制模式
  3. 最大可用模式:正常情況是最大保護模式,主備間出現故障時,切換為最大性能模式。

4、容錯

4.1  故障檢測

  故障檢測可以使用心跳的方式來做,但並不能保證機器一定出現了故障,可能是機器 A 和機器 B 之間的網絡發生問題。

  通常使用租約機制來進行故障檢測。租約機制就是:機器 A 向 機器 B 發放租約,機器 B 在持有租約的有效期內才允許提供服務,否則主動停止服務,機器 B 可以再租約快要到期的時候向機器 A 重新申請租約。

4.2  故障恢復

  總控節點檢測到工作機器出現故障時,需要將服務遷移到其他工作機節點。總控節點本身可有可能出現故障,也需要將自身狀態實行同步到備機。

 

  分布式存儲系統的總控節點只需要維護數據的位置信息,通常不會成為瓶頸。如果成為瓶頸,可以采用兩級結構:

 

5、可擴展性

5.1  數據庫擴容

  數據庫擴容的手段有:

  • 通過主從復制提高系統的讀寫能力
  • 通過垂直拆分和水平拆分將數據分布到多個節點

 

  

  傳統的數據庫為同構系統,在擴容上不夠靈活。同一組內的節點存儲相同的數據,在增加副本時需要遷移的數據量太大。

 

  異構系統將數據划分為很多大小接近的分片,每個分片的多個副本可以分布 到集群中的任何一個存儲節點。如果某個節點發生故障,原有的服務將由整個集群而不 是某幾個固定的存儲節點來恢復。如圖3-9所示,系統中有五個分片(A, B, C, D, E),每個分片包含三個副本, 如分片A的三個副本分別為Al, A2以及A3。假設節點1發生永久性故障,那么可以 從剩余的節點中任意選擇健康的節點來增加A, B以及E的副本。由於整個集群都參與 到節點1的故障恢復過程,故障恢復時間很短,而且集群規模越大,優勢就會越明顯。

 

 

6、分布式協議

6.1  兩階段提交協議

  兩階段提交協議(2PC)用來保證跨節點操作的原子性。該協議中,將系統節點分為:協調者事務參與者。正常執行過程如下:

  1. 請求階段協調者通知事務參與者准備提交(事務參與者本地執行成功)或者取消(事務參與者本地執行失敗)事務。
  2. 提交階段,協調者根據請求階段的結果進行決策:提交或者取消。只有所有事務參與者都同意提交時,協調者才會通知所有的參與者提交事務,否則取消事務

  兩階段提交協議可能面臨的故障:

  1. 事務參與者發生故障。給事務設置超時時間,達到超時時間后整個事務失敗。
  2. 協調者發生故障。可以備用協調者。

  兩階段提交協議是阻塞協議,執行期間要鎖住其他更新,且不能容錯。大多數分布式存儲系統都對之避而遠之。

6.2  Paxos 協議

  Paxos 協議用來解決多個節點之間的一致性問題。當主節點出現故障時,Paxos 協議可以在多個備節點中選舉出唯一的主節點。

  Paxos 協議的兩種用法:

  1. 用它來實現全局的鎖服務或者命名和配置服務
  2. 用它來將用戶數據復制到多個數據中心

  paxos 協議怎么做的???待填坑!!!

6.3 Paxos 與 2PC

  2PC 可以和 Paxos 協議結合起來,通過 2PC 保證多個數據分片上的操作的原子性,通過 Paxos 協議實現同一數據分片的多個副本之間的一致性。另外,通過 Paxos 協議解決 2PC 協議中協調者出現故障的問題。當 2PC 協議中的協調者出現故障時,通過 Paxos 協議選舉出新的協調者繼續提供服務。

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM