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

序言

與單機環境下編程相比,分佈式環境下的編程有兩點不一樣:算法

  1. 分佈式環境下,會出現一部分計算機工做正常,另外一部分計算機工做不正常的狀況,程序須要在這種狀況下儘量地正常工做,挑戰很是大。
  2. 單機環境下,大部分函數採用同步調用;在分佈式環境下,函數調用的返回時間多是單機環境下的100倍,因此分佈式環境下的RPC一般採用異步調用

 


 

第一章  概述

 一、分佈式存儲分類

數據的種類大體能夠分爲三類:數據庫

  1. 非結構化數據,好比圖像,音頻,視頻等。
  2. 機構化數據,儲存在關係數據庫中,能夠用關係表結構來表示的。
  3. 半結構化數據,模式化結構和內容混在一塊兒,好比 HTML 文檔,XML。

 根據儲存數據種類的不一樣,能夠將儲存系統分爲如下幾類:編程

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

 


 

第二章  單機存儲系統

一、硬件基礎

  傳統的數據中心網絡拓撲爲三層結構,該網絡拓撲下,同一接入層下服務器之間帶寬相同,不一樣接入層的服務器帶寬會出現不一致的狀況,所以,設計系統時須要考慮服務器是否在一個機架內。緩存

  爲了減小系統對網絡拓撲結構的依賴,能夠採用三級 CLOS 網絡,使得任何兩臺服務器之間的帶寬都相同。服務器

二、單機存儲引擎

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 的數據轉儲到磁盤。函數

 

三、故障恢復

  分佈式系統通常使用操做日誌技術來實現故障恢復。操做日誌能夠分爲回滾日誌(undo log)重作日誌(redo log)。回滾日誌記錄的是事務修改前的狀態,重作日誌記錄的是事務修改以後的狀態。

3.1  操做日誌

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

3.2  重作日誌

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

3.3  成組提交

  以前說過,數據庫操做須要先寫入操做日誌,可是若是每次操做都當即將操做日誌刷人磁盤,系統性能會下降。所以能夠先將 REDO 日誌儲存在緩衝區,按期刷入磁盤。但這樣作,可能會丟失最後一部分數據庫操做。

3.4  檢查點 

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

 


 第三章  分佈式系統

一、基本概念

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.1  哈希分佈

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

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

 

2.2  順序分佈

  哈希分佈實現數據分佈時,不能支持順序掃描。順序分佈能夠提供連續的範圍掃描,通常作法是將大表順序分爲連續的範圍,每一個範圍一個子表。Bigtable 系統將索引分爲兩級,Root 表和元數據 Meta 表,由 Meta 表維護 User 表的位置信息, Root 表維護 Meta 表的位置信息。

 

三、複製

3.1  複製的概念

  在分佈式系統中,同一份數據有多個副本,其中一個副本爲主副本,其餘爲備副本。複製時,由主副本將數據複製到備份副本。複製協議能夠分爲強同步複製和異步複製。

  強同步複製要求主備成功後才能夠返回成功,能夠保證強一致性,可是,複製時是阻塞寫操做,系統可用性較差。

  異步複製就是主副本不須要等待備副本的迴應,只須要本地修改爲功就能夠返回成功。

  上述兩種複製協議都是主副本將數據發送給其餘副本,當主副本出現故障時,須要選擇新的主副本。經典的選舉協議爲 Paxos 協議。

 

3.2  一致性和可用性

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

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

  設計存儲系統時須要在一致性和可用性之間權衡。若是採用強同步複製,保證系統的一致性,當主備副本之間出現故障時,寫操做被阻塞,系統的可用性將沒法知足。若是採用異步複製,保證了可用性,但沒法作到一致性。

  Oracle 數據庫的 DataGuard 複製組件有三種模式,能夠借鑑:

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

四、容錯

4.1  故障檢測

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

  一般使用租約機制來進行故障檢測。租約機制就是:機器 A 向 機器 B 發放租約,機器 B 在持有租約的有效期內才容許提供服務,不然主動中止服務,機器 B 能夠再租約快要到期的時候向機器 A 從新申請租約。

4.2  故障恢復

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

 

  分佈式存儲系統的總控節點只須要維護數據的位置信息,一般不會成爲瓶頸。若是成爲瓶頸,能夠採用兩級結構:

 

五、可擴展性

5.1  數據庫擴容

  數據庫擴容的手段有:

  • 經過主從複製提升系統的讀寫能力
  • 經過垂直拆分和水平拆分將數據分佈到多個節點

 

  

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

 

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

 

 

六、分佈式協議

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 協議選舉出新的協調者繼續提供服務。

相關文章
相關標籤/搜索