1. 程式人生 > >RocksDB系列一:RocksDB基礎和入門

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的基本概念和知識。