淺談MySQL、Hadoop、BigTable、Clickhouse數據讀寫機制
個人理解,歡迎指正
資料庫 | 引擎 | 寫數據 | 讀數據 | 補充 |
MySql |
InnoDB:支援事務,高速讀寫性能一般 Myisam:不支援事務,高速讀寫性能好 |
以InnoDB更新一條記錄為例 1、B+Tree搜索找到這行記錄,如果數據頁在記憶體直接返回給【執行器】,否則從磁碟讀入記憶體再返回 2、【執行器】更新數據,再調用【引擎】介面寫入這行新數據 3、【引擎】將舊數據備份到undo log,然後更新記憶體中數據頁的這行數據,同時將操作記錄寫到redo log里,此時redo log 處於prepare狀態 4、【執行器】記錄binlog日誌 5、【執行器】調用引擎介面,【引擎】將redo log改成commit狀態 6、此時更新就算完成了,【InnoBD引擎】會在適當的時候將操作記錄批量刷到磁碟,並清理redo log |
其基本流程是:先去快取頁查找,若沒有則通過B+Tree檢索到葉子節點對應的數據頁,然後加到快取頁並返回 |
redo log(重做日誌)和 binlog(歸檔日誌) 1、redo log 是 InnoDB 引擎特有的;binlog 是 MySQL 的 Server 層實現的,所有引擎都可以使用。 2、redo log 是物理日誌,記錄的是「在某個數據頁上做了什麼修改」;binlog 是邏輯日誌,記錄的是這個語句的原始邏輯,比如「給 ID=2 這一行的 c 欄位加 1 」。 3、redo log 是循環寫的,空間固定會用完;binlog 是可以追加寫入的。「追加寫」是指 binlog 文件寫到一定大小後會切換到下一個,並不會覆蓋以前的日誌。 |
Hadoop |
存儲:HDFS 計算:MapReduce |
HDFS寫數據 1、Client向NameNode請求上傳Block(文件塊) 2、NameNode向Client返回DataNode地址 3、Client以Package為單位向DataNode依次寫入,直到寫完整個Block 4、每傳輸完一個Package,DataNode會向Clent返回一個ack,若失敗會重試 |
HDFS讀數據 1、Client向NameNode請求下載文件 2、NameNode按負載均衡和節點距離返回DataNode給Client 3、Client讀取DataNode,以Package為單位拉取,先存入快取,最後生成文件,中間有checksum校驗 |
MapReduce運算 1、InputFormat會從DataNode拉取一個個Bolck塊 2、然後啟動若干個MapTask對Block數據做運算 3、運算後的結果經過Shuffer落到磁碟 4、然後啟動若干個ReduceTask從磁碟讀取數據進行聚合 5、最後通過OutputFormat把結果寫到HDFS或其他存儲介質里 |
BigTable | SSTable |
其實SSTable文件也是存在GFS上,但GFS不支援隨機寫【增刪改】,那麼BigTable是如何實現的呢? 1、其實BigTable在記憶體里維護了一個記憶體表(MemTable),每次數據【增刪改】都會增加一條記錄,並附帶版本。當容量到達閥值的時候會把MemTable轉成SSTable【順序寫】到GFS上,後續數據繼續寫新的MemTable 2、另外,會啟動一個後台進程(Major Compaction機制),不斷的合併SSTable,只保留【增刪改】的最終數據,老版本的數據被刪除 |
當查詢數據時,會去讀取索引數據,找到數據塊返回給Tablet Server,再從這個數據塊里提取出對應的 KV 數據返回給客戶端 1、記憶體里快取 BloomFilter,使得對於不存在於 SSTable 中的行鍵,可以直接過濾掉,無需訪問 SSTable 文件才能知道它並不存在 2、通過 Scan Cache 和 Block Cache 這兩層快取,利用局部性原理,使得查詢結果可以在快取中找到,而無需訪問 GFS 上的硬碟 3、經過前2步還沒找到,會通過SSTable索引來查找,底層是AVL紅黑樹或跳錶,隨機讀寫都是O(log n) |
1、SSTable 的文件格式是由兩部分組成: 數據塊(data block),就是實際要存儲的行鍵、列、值以及時間戳,這些數據會按照行鍵排序分成一個個固定大小的塊(block)來進行存儲。 元數據塊(meta block),是一系列的元數據和索引資訊,這其中包括用來快速過濾當前 SSTable 中不存在的行鍵的布隆過濾器,以及整個數據塊的一些統計指標。 另外還有針對數據塊和元數據塊的索引(index),這些索引內容,則分別是元數據索引塊(metaindex block)和數據索引塊(index block) 2、因為 SSTable 裡面的數據塊是順序存儲的,所以Major Compaction做的是一個有序鏈表的多路歸併,這個過程中在磁碟上是順序讀寫 |
Clickhouse | 表引擎主要是MergeTree系列,還有Log系列等其他引擎 |
1、一個Table是由多個Partition組成,一個Partition是由多個Part組成,Part里按column【列式存儲】 2、舊數據在一個Part,新數據會寫另一個Part,然後通過MergeTree引擎將多個Part非同步合併(按排序鍵歸併排序) |
因為是按排序鍵已經排好序了,所以索引結構不需要像其他引擎設計的那麼複雜; 底層是稀疏索引(默認8192為一個步長),通過【稀疏索引+標記的偏移量】就能很快找到Block的位置
|
1、Clickhouse通過【批處理+預排序】將數據提前排好序 2、Clickhouse能處理的最小單位是block,block就是一群行的集合,默認最大8192行組成一個block |
相關資料