大規模分佈式存儲系統筆記一二章 概述與單機存儲系統

第1章 概述

1.1 分佈式存儲概念

分佈式存儲系統的特性:
  • 可擴展
  • 低成本
  • 高性能
  • 易用
 
分佈式存儲系統的挑戰:
  • 數據分佈
  • 一致性
  • 容錯
  • 負載均衡
  • 事務與併發控制
  • 易用性
  • 壓縮/解壓縮

1.2 分佈式存儲分類

  • 非結構化數據,如辦公文檔、文本、圖片、圖像、音頻、視頻信息等。
  • 結構化數據,如關係數據庫
  • 半結構化數據,如HTML文檔
 
本書將分佈式存儲系統分爲四類:
  1. 分佈式文件系統,存儲圖片、視頻等非結構化數據對象,通常稱爲Blob(Binary Large Object,二進制大對象)數據。典型系統如facebook Haystack、Taobao File System(TFS)。整體上看,分佈式文件系統存儲三種類型的數據:Blob對象、定長塊以及大文件。
  2. 分佈式鍵值系統,存儲關係簡單的半結構化數據,典型系統有Amazon Dynamo以及Taobao Tair,通常用做緩存。
  3. 分佈式表格系統,存儲關係較爲複雜的半結構化數據,典型系統包括Google Bigtable以及Megastore,Microsoft Azure Table Storage。主要支持針對單張表格的操做,不支持如多表關聯、嵌套子查詢等。
  4. 分佈式數據庫,存儲結構化數據,提供SQL關係查詢語言,支持多表關聯、嵌套子查詢等複雜操做,並提供數據庫事務以及併發控制。典型系統包括MySQL數據庫分片(MySQL Sharding)集羣,Amazon RDS以及Microsoft SQL Azure。

第2章 單機存儲系統

2.1 硬件基礎

2.1.1 CPU架構
經典的多CPU架構爲對稱多處理結構(Symmetric Multi-Processing, SMP),爲提升可擴展性,如今主流服務器架構通常爲NUMA(Non-Uniform Memory Access,非一致存儲訪問)架構。
 
2.1.2 IO總線
以Intel x48爲例,是典型的南、北橋架構。
 
2.1.3 網絡拓撲
分爲傳統的數據中心網絡拓撲,Google在2008年將網絡改造爲扁平化拓撲結構,即三級CLOS網絡。
 
2.1.4 性能參數
存儲系統的性能瓶頸主要在於磁盤隨機讀寫。設計存儲引擎的時候會針對磁盤的特性作不少的處理,好比將隨機寫操做轉化爲順序寫,經過緩存減小磁盤隨機讀操做。
 
固態磁盤(SSD)特色是隨機讀取延遲小,可以提供很高的IOPS(每秒讀寫,Input/Output Per Second)性能。它的主要問題在於容量和價格,設計存儲系統的時候通常能夠用來作緩存或者性能要求較高的關鍵業務。
 
2.1.5 存儲層次架構
存儲系統的性能主要包括兩個維度:吞吐量以及訪問延時,設計系統時要求可以在保證訪問延時的基礎上,經過最低的成本實現儘量高的吞吐量。磁盤和SSD的訪問延時差異很大,但帶寬差異不大,所以磁盤適合大塊順序訪問的存儲系統,SSD適合隨機訪問較多或者對延時比較敏感的關鍵系統。兩者也經常組合在一塊兒進行混合存儲,熱數據(訪問頻繁)存儲到SSD中,冷數據(訪問不頻繁)存儲到磁盤中。
 

2.2 單機存儲引擎

存儲系統的基本功能包括:增、刪、讀、改,其中,讀取操做又分爲隨機讀取和順序讀取。哈希存儲引擎是哈希表的持久化實現,支持增、刪、改,以及隨機讀取操做,但不支持順序掃描,對應的存儲系統爲鍵值(Key-Value)存儲系統;B樹(B-Tree)存儲引擎是B樹的持久化實現,不只支持單條記錄的增、刪、讀、改操做,還支持順序掃描,對應的存儲系統是關係數據庫。固然,鍵值系統也能夠經過B樹存儲引擎實現;LSM樹(Log-Structured Merge Tree)存儲引擎和B樹存儲引擎同樣,支持增、刪、改、隨機讀取以及順序掃描。它經過批量轉儲技術規避磁盤隨機寫入問題,普遍應用於互聯網的後臺存儲系統,例如Google Bigtable, Google LevelDB以及Facebook開源的Cassandra系統。

2.2.1 哈希存儲引擎

Bitcask是一個基於哈希表結構的鍵值存儲系統,它僅支持追加操做(Append-only)。
1 數據結構
內存中採用基於哈希表的索引數據結構,哈希表的做用是經過主鍵快速地定位到value的位置。
Bitcask在內存中存儲了主鍵和value的索引信息,磁盤文件中存儲了主鍵和value的實際內容。
2 按期合併
3 快速恢復
Bitcask經過索引文件(hint file)來提升重建哈希表的速度。簡單來講,索引文件就是將內存中的哈希索引錶轉儲到磁盤生成的結果文件。

2.2.2 B樹存儲引擎

1 數據結構
MySQL InnoDB按照頁面(Page)來組織數據,每一個頁面對應B+樹的一個節點。其中,葉子節點保存每行的完整數據,非葉子節點保存索引信息。數據在每一個節點中有序存儲,數據庫查詢時須要從根節點開始二分查找直到葉子節點,每次讀取一個節點,若是對應的頁面不在內存中,須要從磁盤中讀取並緩存起來。B+樹的根節點是常駐內存的,所以,B+樹一次檢索最多須要h-1次磁盤IO,複雜度爲O(h)=O(logd^N)(N爲元素個數,d爲每一個節點的出席,h爲B+樹高度)。修改操做首先須要記錄提交日誌,接着修改內存中的B+樹。若是內存中的被修改過的頁面超過必定的比率,後臺線程會將這些頁面刷到磁盤中持久化。
2 緩衝區管理
緩衝區管理器負責將可用的內存劃分紅緩衝區,緩衝區是與頁面同等大小的區域,磁盤塊的內容能夠傳送到緩衝區中。緩衝區管理器的關鍵在於替換策略,即選擇將哪些頁面淘汰出緩衝池。常見的算法有如下兩種。
(1)LRU,LRU算法淘汰最長時間沒有讀或者寫過的塊。
(2)LIRS,解決全表掃描污染緩衝池的問題。現代數據庫通常採用LIRS算法,將緩衝池分爲兩級,數據首先進入第一級,若是數據在較短的時間內被訪問兩次或者以上,則成爲熱點數據進入第二級,每一級內部仍是採用LRU替換算法。
 

2.2.3 LSM樹存儲引擎

LSM樹(Log Structured Merge Tree)的思想很是樸素,就是將對數據的修改增量保持在內存中,達到指定的大小限制後將這些修改操做批量寫入磁盤,讀取時須要合併磁盤中的歷史數據和內存中最近的修改操做。
 
1 存儲結構
LevelDB存儲引擎主要包括:內存中的MemTable和不可變MemTable(Immutable MemTable, 也稱爲Frozen MemTable,即凍結MemTable)以及磁盤上的幾種主要文件:當前(Current)文件、清單(Manifest)文件、操做日誌(Commit Log, 也稱爲提交日誌)文件以及SSTable文件。當應用寫入一條記錄時,LevelDB會首先將修改操做寫入到操做日誌文件,成功後再將修改操做應用到MemTable,這樣就完成了寫入操做。
當MemTable佔用的內存達到一個上限值後,須要將內存的數據轉儲到外存文件中。
SSTable中的文件是按照記錄的主鍵排序的,每一個文件有最小 的主鍵和最大的主鍵。
2 合併
LevelDB的Compaction操做分爲兩種:minor compaction和major compaction。minor compaction是內存中的MemTable轉儲到SSTable。major compaction是合併多個SSTable文件。

2.3 數據模型

2.3.1 文件模型算法

POSIX(Portable Operation System Interface)是應用程序訪問文件系統的API標準,它定義了文件系統存儲接口及操做集。

2.3.2 關係模型數據庫

每一個關係是一個表格,由多個元組(行)構成,而每一個元組又包含多個屬性(列)。關係名、屬性名以及屬性類型稱做該關係的模式(schema)。
數據庫語言SQL用於描述查詢以及修改操做。

2.3.3 鍵值模型緩存

大量的NoSQL系統採用了鍵值模型(也稱爲Key-Value模型),每行記錄由主鍵和值兩個部分組成,支持基於主鍵的以下操做:Put, Get, Delete
NoSQL系統中使用比較普遍的模型是表格模型。表格模式弱化了關係模型中的多表關聯,支持基於單表的簡單操做,典型的系統是Google Bigtable以及其開源Java實現HBase。主要操做以下:Insert, Delete, Update, Get, Scan。

2.3.4 SQL與NoSQL服務器

關係數據庫在海量數據場景面臨以下挑戰:
  • 事務
  • 聯表
  • 性能
NoSQL系統面臨以下問題:
  • 缺乏統一標準
  • 使用以及運維複雜

2.4 事務與併發控制

2.4.1 事務

事務的四個基本屬性:
(1)原子性(Atomicity)
(2)一致性(Consistency)
(3)隔離性(Isolation)
(4)持久性(Durability)
 
SQL定義了4種隔離級別:
  • Read Uncommitted(RU):讀取未提交的數據
  • Read Committed(RC):讀取已提交的數據
  • Repeatable Read(RR):可重複讀取
  • Serialization(S):可序列化,即數據庫的事務是可串行化執行的。這是最高的隔離級別。
 
隔離級別的下降可能致使讀到髒數據或者事務執行異常,例如:
  • Lost Update(LU):丟失更新
  • Dirty Reads(DR):髒讀
  • Non-Repeatable Reads(NRR):不可重複讀
  • Second Lost Updates problem(SLU): 第二類丟失更新
  • Phantom Reads(PR): 幻讀

2.4.2 併發控制

1 數據庫鎖
事務分爲幾種類型:讀事務,寫事務以及讀寫混合事務。相應地,鎖也分爲兩種類型:讀鎖以及寫鎖,容許對同一個元素加多個讀鎖,但只容許加一個寫鎖,且寫事務將阻塞讀事務。
 
2 寫時複製(Copy-On-Write,COW)
寫時複製讀操做不用加鈔,極大地提升了讀取性能。
圖2-10中寫時複製B+樹執行寫操做的步驟以下:
(1)拷貝:將從葉子到根節點路徑上的全部節點拷貝出來。
(2)修改:對拷貝的節點執行修改。
(3)提交:原子地切換根節點的指針,使之指向新的根節點。
 
寫時複製技術原理簡單,問題是每次寫操做都須要拷貝從葉子到根節點路徑上的全部節點,寫操做成本高,另外,多個寫操做之間的互斥的,同一時刻只容許一個寫操做。
 
3 多版本併發控制(MVCC,Multi-Version Concurrency Control)
也可以實現讀事務不加鎖。以MySQL InnoDB存儲引擎爲例,InnoDB對每一行維護了兩個隱含的列,其中一列存儲行被修改的"時間",另一列存儲行被刪除的"時間"。注意,InnoDB存儲的並非絕對時間,而是與時間對應的數據庫系統的版本號。
 
MVCC讀取數據的時候不用加鎖,每一個查詢都經過版本檢查,只得到本身須要的數據版本,從而大大提升了系統的併發度。

2.5 故障恢復

數據庫系統以及其餘的分佈式存儲系統通常採用操做日誌(有時也稱爲提交日誌,即Commit Log)技術來實現故障恢復。操做日誌分爲回滾日誌(UNDO Log)、重作日誌(REDO Log)以及UNDO/REDO日誌。
 
2.5.1 操做日誌
關係數據庫系統通常採用UNDO/REDO日誌。
 
2.5.2 重作日誌
 
2.5.3 優化手段
1 成組提交(Group Commit)
2 檢查點(Checkpoint)
須要將內存中的數據按期轉儲(Dump)到磁盤,這種技術稱爲checkpoint(檢查點)技術。系統按期將內存中的操做以某種易於加載的形式(checkpoint文件)轉儲到磁盤中,並記錄checkpoint時刻的日誌回放點,之後故障恢復只須要回放checkpoint時刻的日誌回放點以後的REDO日誌。
 

2.6 數據壓縮

2.6.1 壓縮算法

壓縮的本質就是找數據的重複或者規律,用盡可能少的字節表示。
 
1 Huffman編碼
前綴編碼要求一個字符的編碼不能是另外一個字符的前綴。
 
2 LZ系列壓縮算法
LZ系列壓縮算法是基於字典的壓縮算法。
 
3 BMDiff與Zippy
在Google的Bigtable系統中,設計了BMDiff和Zippy兩種壓縮算法。
 

2.6.2 列式存儲

OLTP(Online Transaction Processing,聯機事務處理)應用適合採用行式數據庫。OLAP類型的查詢可能要訪問幾百萬甚至幾十億數據行,且該查詢每每只關心少數幾個數據列,列式數據庫能夠大大提升OLAP大數據量查詢的效率。列組(column group)是一種行列混合存儲械,這種模式可以同時知足OLTP和OLAP的查詢需求。
 
因爲同一個數據列的數據重複度很高,所以,列式數據庫壓縮時有很大的優點,如位圖索引等。
相關文章
相關標籤/搜索