- LSM-tree(Log-Structured Merge tree)
- RocksDB 採用的分層結構:一個記憶體緩衝區,加上一連串由不可變有序檔案組成的層級,新資料從頂端進入、靠合併逐層往下遷移。它把隨機更新轉換成大塊的循序檔案寫入,代價是每次查找可能得走訪多層。
- MemTable
- 記憶體中的寫入緩衝區,以 skiplist 實作,讓 key 保持有序並提供 O(log n) 的插入與搜尋。當它達到設定大小就改為不可變、flush 成 SSTable,然後連同對應的 write-ahead log 一起丟棄。
- SSTable(Sorted String Table)
- 磁碟上不可變的檔案,內部依 key 排序、切成大小一致的 block,並帶有一個索引 block(每個資料 block 一筆索引項)與通常會有的 Bloom filter。LSM-tree 的每一層都是由這種檔案組成。
- 寫入放大(write amplification)
- 本文的定義是:SSTable 檔案寫出的總位元組數,除以 MemTable flush 出去的位元組數,且不計 WAL 的寫入。它之所以重要,是因為 flash 的 program/erase 次數有限;而且在軟體產生的放大之上,SSD 自己還會再乘上 1.1 到 3 倍。
- 空間放大(space amplification)
- 資料庫實際佔用的空間,超出「完全 compact 後有效資料所需空間」的部分,本文以空間額外開銷的百分比呈現。當機隊量測顯示真正的瓶頸是磁碟空間而非 IOPS 或壽命之後,它就成了 RocksDB 的主要最佳化目標。
- Leveled、Tiered 與 FIFO compaction
- RocksDB 提供的三種 compaction 風格:leveled 每層維持一個 sorted run,各層容量目標呈指數成長;tiered(此處稱 Universal,做法近似 Cassandra 與 HBase)採懶惰合併以壓低寫入放大;FIFO 則在超過容量上限時直接刪掉最舊的檔案,專門服務快取類負載。
- Dynamic Leveled Compaction
- leveled compaction 的一種變體:每層的容量目標不再由設定靜態指定,而是由實際量測到的最後一層大小推導出來。它把空間額外開銷維持在 13% 上下,更重要的是隨著資料庫成長依然穩定。
- Handoff checksum(交遞校驗和)
- 對即將寫出的資料先算好 checksum,並隨資料一起往下傳,讓下層在寫入當下就驗證,而不是等到讀取時才發現。RocksDB 想用它保護 WAL 的追加寫入,但本機檔案系統很少提供這種寫入 API。
- 使用者自訂時間戳(user-defined timestamp)
- 由應用選定、以中繼資料形式掛在鍵值對上的版本標記,與 RocksDB 內部的 56 位元 sequence number 不同,而且既不放進 key 也不放進 value。它保住了 point lookup 與 Bloom filter 的效用,同時讓時點讀取與跨分片一致版本成為可能。