RocksDB系列一:RocksDB基礎和入門

1、簡介

       RocksDB是FaceBook起初作爲實驗性質開發的一個高效數據庫軟件,旨在充分實現快存上存儲數據的服務能力。RocksDB是一個c++庫,可以用來存儲keys和values,且keys和values可以是任意的字節流,支持原子的讀和寫。除此外,RocksDB深度支持各種配置,可以在不同的生產環境(純內存、Flash、hard disks or HDFS)中調優,支持不同的數據壓縮算法、和生產環境debug的完善工具。 RocksDB的主要設計點是在快存和高服務壓力下性能表現優越,所以該db需要充分挖掘Flash和RAM的讀寫速率。RocksDB需要支持高效的point lookup和range scan操作,需要支持配置各種參數在高壓力的隨機讀、隨機寫或者二者流量都很大時性能調優。

2、High Level Architecture

       RocksDB是一個嵌入式的K-V(任意字節流)存儲。所有的數據在引擎中是有序存儲,可以支持Get(key)、Put(Key)、Delete(Key)和NewIterator()。RocksDB的基本組成是memtable、sstfile和logfile。memtable是一種內存數據結構,寫請求會先將數據寫到memtable中,然後可選地寫入logfile。logfile是一個順序寫的文件。當內存表溢出的時候,數據會flush到sstfile中,然後這個memtable對應的logfile也會安全地被刪除。sstfile中的數據也是有序存儲以方便查找。

3、Features

Column Families

      RocksDB支持將一個數據庫實例分片爲多個列族。每個DB新建時默認帶一個名爲"default"的列族,如果一個操作沒有攜帶列族信息,則默認使用這個列族。如果WAL開啓,當實例crash再恢復時,RocksDB可以保證用戶一個一致性的視圖。通過WriteBatch API,可以實現跨列族操作的原子性。

Updates

      Put 接口可以把一對k-v數據寫入DB,如果k已經存在的話,則已有的v會被新的v覆蓋。Write接口可以實現將多個k-v對寫入DB,RockdDB可以保證要麼所有的k-v對都寫入DB,要麼一個都不寫入。同理,不管哪個k在DB中已經存在,舊值都會被覆蓋。

Gets、Iterators、Snapshots

      RocksDB中的key和value完全是byte stream,key和value的大小沒有任何限制。Get接口提供用戶一種從DB中查詢key對應value的方法,MultiGet提供批量查詢功能。DB中的所有數據都是按照key有序存儲,其中key的compare方法可以用戶自定義。Iterator方法提供用戶RangeScan功能,首先seek到一個特定的key,然後從這個點開始遍歷。Iterator也可以實現RangeScan的逆序遍歷,當執行Iterator時,用戶看到的是一個時間點的一致性視圖。Snapshot接口可以創建數據庫在某一個時間點的快照。Get和Iterator接口也可以執行在某一個Snapshot上。某種意義上,Iterator和Snapshot提供了DB在某個時間點的一個一致性視圖,但是其實現原理卻不一樣。快速短期/前臺的scan操作比較適合用Iterator,長期/後臺操作適合用Snapshot。當使用Iterator時,會對數據庫相應時間點的所有底層文件增加引用計數,直到Iterator結束或者釋放了引用計數後,這些文件才允許被刪除。Snapshot不關注數據文件是否被刪除的問題,Compation進程會感知Snapshot的存在,會保證對應視圖的數據不會被刪除。當實例重啓時,Snapshot會丟失,這是因爲RocksDB不會持久化Snapshot相關數據。

Transations

    RocksDB提供了多個操作的事務性,支持悲觀和樂觀模式。

Prefix Iterator

     大部分的LSM引擎都不支持高效的RangeScan操作,這是由於執行RangeScan操作時都要訪問所有的數據文件導致。但是大部分用戶並不僅僅是完全scan所有的數據,相反,很多情況下僅僅需要按照key的前綴字符串區遍歷。RocksDB根據這些應用場景,優化了對應的底層實現。用戶可以prefix_extractor來聲明一個key_prefix,然後RocksDB爲每一個key_prefix存儲相應的blooms。配置了key_prefix的Iterator操作可以通過對應的bloom bits來避免檢索不含有特定key prefix的數據文件,依次可以提高Iterator性能。

Persistence

     RocksDB有事物日誌,所有的寫操作首先寫入內存表內,然後可選地寫入到事物日誌中。當DB重啓時會重新執行事物日誌中的所有操作,然後恢復到特定的數據狀態。事物日誌數據可以與DB數據文件配置成不同的目錄下,這種情況適用於將數據文件寫到一致性、性能高的快存中,同時可以將事物日誌保存在讀寫性能相對比較慢的持久化存儲上來保證數據的安全性。當寫數據時可以配置WriteOption,來支持是否將寫操作記錄在事物日誌中或者當用戶執行commit時是否需要執行事物日誌記錄的sync操作。

Fault Torlerance

     RocksDB通過checksum來檢測磁盤數據損壞。每個sst file的數據塊(4k-128k)都有相應的checksum值。寫入存儲的數據塊內容不允許被修改。

Multi-Threaded Compactions

     當用戶重複寫入一個key時,在DB中會存在這個key的多個value,compaction操作就是來刪除這個key的冗餘數據。當一個key被刪除時,compation也可以用來真正執行這個底層數據的刪除工作,如果用戶配置合適的話,compation操作可以多線程執行。DB的數據都存儲在sstfile中,當內存表的數據滿的時候,會將內存數據(去重、刪除無效數據後)寫入到L0 文件中。每隔一段時間小文件中的數據會重新merge到更大的文件中,這就是compation。LSM引擎的寫吞吐直接依賴於compation的性能,特別是數據存儲在SSD或者RAM的情況。RocksDB也支持多線程並行compaction。

Avoiding Stalls

     後臺的compaction線程用來將內存數據flush到存儲,當所有的後臺線程都正在執行compaction時,瞬時大量寫操作會很快將內存表寫滿,這就會引起寫停頓。可以配置少一些的線程用於執行數據flush操作,

Full Backups, Incremental Backups and Replication

     RocksDB支持增量備份,增量複製需要能夠查找到所有的DB修改記錄。GetUpdatesSince接口可以提供tail DB transction log的功能。RocksDB的tranction log記錄在數據庫目錄中,當日志文件不再需要時就會move到歸檔目錄。歸檔目錄之所以存在是因爲數據複製流比較落後時有可能需要檢索過去某一個時間點的日誌。GetSortedWalFiles可以返回所有的transction log文件列表。

Block Cache -- Compressed and Uncompressed Data

     RocksDB使用LRU cache提供block的讀服務。block cache partition爲兩個獨立的cache,其中一塊可以cache未壓縮RAM數據,另一塊cache 壓縮RAM數據。如果壓縮cache配置打開的話,用戶一般會開啓direct io,以避免OS的也緩存重新cache相同的壓縮數據。

Table Cache

  Table cache緩存了所有已打開的文件句柄,這些文件都是sstfile。用戶可以設置table cache的最大值。

Merge Operator

  RocksDB原生地就支持三種記錄類型,分別爲Put、Delete和Merge。Merge可以合併多個Put和Merge記錄爲一個單獨的記錄。

本文先介紹了一下RocksDB的基本概念和知識。


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章