這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。
boltdb
boltdb是一款golang實現的嵌入式K-V儲存引擎。在boltdb的源碼中的doc.go對其有一個簡要的說明。其提供事務、ACID語言、無鎖MVCC支援。資料提供零拷貝、B-TREE索引。其主要設計源於Howard Chu的LMDB。
持久化
boltdb採用一個單獨的檔案作為持久化儲存。其將不同的檔案部分劃分為不同的page,不同的page儲存不同類型的資料(meta、key、value)等。當經過反覆的增刪改查後,檔案中可能出現沒有資料的部分。此時boltdb並不打算搬移資料、截斷檔案來將多餘的空間返還給作業系統。而是將這些部分,加入內部的FreeList來維護,當有新的資料寫入時,複用這些空間。因此從使用者視角來看,boltdb的持久化檔案只會增大,而不會因為資料的刪除而減少。
boltdb在寫入資料時,為了提高效率,採用unsafe的方法直接獲得相關struct的系統記憶體layout,而沒有使用一些序列化工具。因此持久化檔案裡記錄的資料格式是作業系統相關的。因此不能將一個大端系統中的持久化檔案複製到一個小端系統中使用。
由於boltdb採用B-TREE索引,會帶來隨機寫入,所以在有寫入瓶頸的情境中,只能通過使用SSD來提高。
當使用者寫入一個key-value對時,boltdb根據key寫入相關的B-TREE索引指定的檔案位移量中去。
其零拷貝的特性主要體現在它將持久化檔案以唯讀模式通過mmap映射到記憶體空間中,然後通過索引找到記憶體中key對應的value所指向的空間,然後將這段記憶體返回給使用者。因此在database儲存資料比較多時,可能會顯示程式的記憶體使用量量很高。boltdb在做檔案mmap映射時的策略比較簡單,即將檔案整體映射到記憶體空間中,完全利用作業系統的虛擬記憶體空間與實體記憶體動態映射、換出的機制,而沒有去做動態映射變更,在地址空間比較小的32bit系統中可能會帶來一些限制。
用唯讀預設來映射也保護了持久化檔案,防止使用者程式出現記憶體越界,將持久化檔案汙染。
這也帶來一個問題,boltdb返回的記憶體切片是一段唯讀記憶體,使用者不能對其進行修改。而且該記憶體的生命週期只存在於相關事務持續周期內。