how we use RocksDB at Rockset

在這篇文章中砚蓬,我們將會(huì)講述我們?cè)赗ockset使如何使用RocksDB和對(duì)RocksDB進(jìn)行調(diào)優(yōu)從而達(dá)到更好的性能的。我們認(rèn)為讀者對(duì)基于LSM tree構(gòu)建的存儲(chǔ)引擎盆色,例如RocksDB 如何工作的已經(jīng)很熟悉了灰蛙。

在Rockset,我們想要我們的用戶能夠以次秒級(jí)的寫延遲速度將數(shù)據(jù)導(dǎo)入到Rockset里面隔躲,并能夠在10毫秒的速度進(jìn)行查詢摩梧,因此,我們需要一個(gè)既可以支持快速在線寫入又可以支持快速讀取的存儲(chǔ)引擎宣旱。RocksDB就是這樣一種高性能的存儲(chǔ)引擎仅父。RocksDB被很多大公司使用,例如Facebook浑吟、Linkedin笙纤、Uber等。還有些項(xiàng)目例如MongoRocks组力、Rocksandra省容、MyRocks等等都是使用RocksDB作為存儲(chǔ)引擎,并且已經(jīng)成功的減少了空間放大和寫延遲的問題燎字。RocksDB的KV模型很適合用來實(shí)現(xiàn)混合索引腥椒。混合索引是輸入一個(gè)文檔候衍,在RocksDB存三份數(shù)據(jù)笼蛛,行式數(shù)據(jù)、列式數(shù)據(jù)蛉鹿、和搜索索引滨砍。因此我們決定使用RocksDB作為我們的存儲(chǔ)引擎。我們團(tuán)隊(duì)在RocksDB上有很豐富的經(jīng)驗(yàn)妖异,我們的CTO-Dhruba Borthakur在facebook開發(fā)了RocksDB惋戏。對(duì)于每一個(gè)數(shù)據(jù)的文檔,產(chǎn)生一系列的KV對(duì)随闺,然后把他們寫入到RocksDB數(shù)據(jù)庫(kù)里面日川。

讓我快速描述一下RocksDB存儲(chǔ)節(jié)點(diǎn)在整個(gè)系統(tǒng)架構(gòu)中的位置。

當(dāng)用戶創(chuàng)建一個(gè)collection矩乐,系統(tǒng)內(nèi)部會(huì)創(chuàng)建N個(gè)分片龄句,每個(gè)分片會(huì)進(jìn)行K次復(fù)制(通常k=2)回论,以實(shí)現(xiàn)高讀取可用性,每一個(gè)分片副本被分配給葉結(jié)點(diǎn)分歇。每一個(gè)葉節(jié)點(diǎn)被分配了許多集合的許多分片副本傀蓉。在生產(chǎn)環(huán)境中,每個(gè)節(jié)點(diǎn)分配的大概100個(gè)分片副本职抡。葉節(jié)點(diǎn)為分配給他們的每個(gè)分片副本創(chuàng)建一個(gè)RocksDB實(shí)例葬燎。對(duì)于每個(gè)分片副本,葉結(jié)點(diǎn)不斷從DistributedLogStore提取更新數(shù)據(jù)缚甩,并將更新數(shù)據(jù)應(yīng)用在RocksDB實(shí)例中谱净,當(dāng)收到查詢請(qǐng)求的時(shí)候,給葉節(jié)點(diǎn)分配了查詢計(jì)劃片段擅威。更多細(xì)節(jié)請(qǐng)參考Aggregator Leaf Tailer 或者 Rockset White Paper.

為了實(shí)現(xiàn)在每個(gè)葉子節(jié)點(diǎn)在不斷更新的同時(shí)保持高效的查詢壕探,我們花費(fèi)了大量時(shí)間對(duì)RocksDB進(jìn)行調(diào)優(yōu),下面郊丛,我們將會(huì)描述如何對(duì)RocksDB進(jìn)行調(diào)用李请。

RocksDB-Cloud

RocksDB 是一個(gè)嵌入式的KV存儲(chǔ)。一個(gè)RocksDB實(shí)例的數(shù)據(jù)不會(huì)復(fù)制到另外一臺(tái)機(jī)器上厉熟。當(dāng)機(jī)器宕機(jī)导盅,RocksDB不能恢復(fù)。為了實(shí)現(xiàn)持久性揍瑟,我們開發(fā)了RocksDB-cloud這個(gè)項(xiàng)目白翻,RocksDB-cloud把所有RocksDB實(shí)例的數(shù)據(jù)和元數(shù)據(jù)傳到S3上。所有葉節(jié)點(diǎn)的SST文件都復(fù)制到S3里面月培,當(dāng)一個(gè)葉子節(jié)點(diǎn)宕機(jī)的時(shí)候嘁字,這臺(tái)節(jié)點(diǎn)的s3數(shù)據(jù)將會(huì)被分配給所有分片復(fù)制節(jié)點(diǎn)中的一個(gè)節(jié)點(diǎn)恩急。對(duì)于每一個(gè)新的分片復(fù)制杉畜,葉子節(jié)點(diǎn)將會(huì)讀取相對(duì)應(yīng)的失敗葉子節(jié)點(diǎn)的s3 Bucket里的RocksDB文件。

Disable WAL

RocksDB將會(huì)把所有的更新寫入一個(gè)write ahead Log 里和活躍的memtable里面衷恭。這個(gè)write ahead log 是當(dāng)進(jìn)程重啟的時(shí)候此叠,用來恢復(fù)memtables 里面的數(shù)據(jù)。在Rockset随珠,所有的對(duì)于collections的更新都會(huì)首先被寫入到DistributedLogStore灭袁。DistributedLogStore 本身的作用和write ahead log 的作用是一樣的,而且窗看,我們也不需要保證查詢之間的數(shù)據(jù)一致性茸歧。因此先丟失memtables的數(shù)據(jù)墨礁,然后在重新啟動(dòng)的時(shí)候履怯,從DistributedLogStore 里面重新獲取也是可以隘截。所以,禁用RocksDB的write ahead log疙咸,意味著所有RocksDB寫操作都會(huì)在內(nèi)存中進(jìn)行。

Writer rate Limit

正如上面所講的宙拉,葉節(jié)點(diǎn)主要復(fù)制更新和數(shù)據(jù)查詢例朱,相比于查詢,我們可以容忍更高的寫延遲只锭,我們盡可能多的用一小部分可用計(jì)算容量來處理寫請(qǐng)求著恩,用大部分計(jì)算用量來處理讀請(qǐng)求。我們限制葉結(jié)點(diǎn)上的RocksDB實(shí)例每秒寫入的數(shù)據(jù)量蜻展。我們也限制寫線程的數(shù)量喉誊。這有助于最小化RocksDB寫入對(duì)查詢延遲的影響。此外纵顾,通過這種方式限制寫操作裹驰,我們永遠(yuǎn)不會(huì)以LSM樹不平衡或觸發(fā)RocksDB內(nèi)置的不可預(yù)測(cè)的back-pressure或stall機(jī)制而結(jié)束。注意片挂,這兩個(gè)特性在RocksDB中都不可用幻林,但是我們?cè)赗ocksDB上實(shí)現(xiàn)了它們。RocksDB支持速率限制音念,它可以限制存儲(chǔ)設(shè)備的寫入速率沪饺,但是我們需要一種可以限制從應(yīng)用程序?qū)懭隦ocksDB實(shí)例的機(jī)制。

Sorted Write Batch

如果單個(gè)update 可以通過WriteBatch實(shí)現(xiàn)批處理更處理闷愤,更進(jìn)一步整葡,如果WriteBatch 中連續(xù)的keys 是按順序進(jìn)行,那么RocksDB可以實(shí)現(xiàn)更高的寫入吞吐量讥脐。我們可以充分利用這兩個(gè)優(yōu)勢(shì)遭居,我們首先將持續(xù)傳入的更新批量處理為100KB大小的微型批次,并對(duì)其進(jìn)行排序旬渠,然后將其寫入RocksDB中俱萍。

Dynamic Level Target Sizes

在具有分層壓縮策略的LSM樹中,直到超過當(dāng)前l(fā)evel的目標(biāo)大小的時(shí)候告丢,才會(huì)使用下一個(gè)level的文件壓縮策略枪蘑。每個(gè)level的目標(biāo)大小是根據(jù)level 1 的目標(biāo)大小 和 level 系數(shù)(通常為10)確定的。當(dāng)last level達(dá)到RocksDB的博客所說的目標(biāo)大小的時(shí)候岖免,將會(huì)導(dǎo)致一個(gè)比預(yù)期的更高的空間放大系數(shù)岳颇。為了緩解這個(gè)現(xiàn)象,RocksDB可以根據(jù)上一個(gè)level的目標(biāo)大小動(dòng)態(tài)的設(shè)置每一個(gè)level的目標(biāo)大小颅湘。無論RocksDB中存儲(chǔ)的數(shù)據(jù)量為多少话侧,我們都將通過使用此特性來實(shí)現(xiàn)RocksDB預(yù)期的1.111的空間放大系數(shù)。這個(gè)特性可以通過設(shè)置dvancedColumnFamilyOptions::level_compaction_dynamic_level_bytestrue開啟闯参。

Shared Block Cache

如上所訴瞻鹏,葉結(jié)點(diǎn)分配了許多集合的分片副本术羔,每個(gè)分片副本都有一個(gè)RocksDB實(shí)例,我們沒有為每個(gè)RocksDB實(shí)例分配單獨(dú)的塊緩存乙漓,而是為一個(gè)葉結(jié)點(diǎn)上的所有RocksDB實(shí)例分配了一個(gè)全局的塊緩存级历。通過將所有分片副本中未使用的塊踢出葉子內(nèi)存,有助于提升內(nèi)存的利用率叭披。我們?yōu)閴K緩存分配葉子容器大約25%的可用內(nèi)存寥殖。即使有多余的可用內(nèi)存,我們也不增加塊緩存大小涩蜘。這是因?yàn)槲覀兿M僮飨到y(tǒng)的頁(yè)緩存可以使用這部分內(nèi)存嚼贡。頁(yè)緩存緩存所有的壓縮塊,而塊緩存緩存未壓縮塊同诫。因此頁(yè)緩存可以更密集的緩存那些不經(jīng)常用的文件塊粤策。正如Optimizing Space Amplification in RocksDB 這篇論文所講的那樣,F(xiàn)aceBook 部署了三個(gè)RocksDB實(shí)例误窖,頁(yè)緩存使文件系統(tǒng)的讀取減少了52%叮盘。頁(yè)緩存由計(jì)算機(jī)上的所有容器共享,因此頁(yè)緩存為計(jì)算機(jī)上運(yùn)行的所有頁(yè)容器提供服務(wù)霹俺。

No Compression For L0 & L1

根據(jù)RocksDB的設(shè)計(jì)原則柔吼,與其他level相比,LSM 樹中的L0 和 L1級(jí)別包含的數(shù)據(jù)非常少丙唧。因此愈魏,在L0和L1級(jí)別上壓縮數(shù)據(jù)沒有什么效果。但是只要不在這些級(jí)別上進(jìn)行壓縮想际,就可以節(jié)省一些CPU培漏。從L0到L1的每次壓縮都需要訪問所有L1文件。同樣胡本,range scan 不使用布隆過濾器牌柄,而是查找L0中所有文件。如果L0和L1的數(shù)據(jù)在讀取的時(shí)候進(jìn)行解壓縮打瘪,在寫入的時(shí)候進(jìn)行壓縮友鼻,那么這兩個(gè)頻繁的CPU密集型操作將使用CPU傻昙。這就是RocksDB小組不推薦壓縮L0和L1中的數(shù)據(jù)闺骚,而推薦使用LZ4壓縮其他級(jí)別數(shù)據(jù)的原因。

Bloom Filters ON key Prefixes

正如在converged indexing 中描述的那樣妆档,我們將以三種不同的方式和三鐘不同的key ranges 將每個(gè)文檔的每一列存到RocksDB中僻爽。對(duì)于查詢,我們對(duì)每個(gè)key ranges的讀取方法不同贾惦,具體來說胸梆,我們不會(huì)使用一個(gè)具體的key來在這些key ranges里面查找key敦捧。我們通常使用較小的共享key 前綴來查找key。因此碰镜,通過設(shè)置BlockBasedTableOptions::whole_key_filtering為false兢卵,整個(gè)keys就不會(huì)用來填充,進(jìn)而導(dǎo)致為每個(gè)sst文件創(chuàng)建布隆過濾器绪颖。我們也可以設(shè)置ColumnFamilyOptions::prefix_extractor秽荤,這樣只會(huì)為有用的key的前綴,創(chuàng)建布隆過濾器柠横。

Iterator Freepool

當(dāng)處理查詢的時(shí)候窃款,從RocksDB讀取數(shù)據(jù),我們需要?jiǎng)?chuàng)建一個(gè)或者多個(gè) rocksdb::Iterators牍氛。對(duì)于查詢來說晨继,需要執(zhí)行range scan 或者 檢索多個(gè)字段,因此需要?jiǎng)?chuàng)建多個(gè)iterators搬俊。但是創(chuàng)建這些迭代器是非常昂貴的和浪費(fèi)資源的紊扬。我們可以使用這些迭代器的空閑池,并嘗試在一次查詢中重復(fù)使用用迭代器唉擂。 但是我們不能在多次查詢中重復(fù)使用迭代器珠月。因?yàn)槊總€(gè)迭代器都引用特定的RocksDB快照。對(duì)于一次查詢來說楔敌,我們使用相同的RocksDB快照啤挎。

最后,這里有一些我們?cè)O(shè)置的RocksDB具體配置文件卵凑。

Options.max_background_flushes: 2
Options.max_background_compactions: 8
Options.avoid_flush_during_shutdown: 1
Options.compaction_readahead_size: 16384
ColumnFamilyOptions.comparator: leveldb.BytewiseComparator
ColumnFamilyOptions.table_factory: BlockBasedTable
BlockBasedTableOptions.checksum: kxxHash
BlockBasedTableOptions.block_size: 16384
BlockBasedTableOptions.filter_policy: rocksdb.BuiltinBloomFilter
BlockBasedTableOptions.whole_key_filtering: 0
BlockBasedTableOptions.format_version: 4
LRUCacheOptionsOptions.capacity : 8589934592
ColumnFamilyOptions.write_buffer_size: 134217728
ColumnFamilyOptions.compression[0]: NoCompression
ColumnFamilyOptions.compression[1]: NoCompression
ColumnFamilyOptions.compression[2]: LZ4
ColumnFamilyOptions.prefix_extractor: CustomPrefixExtractor
ColumnFamilyOptions.compression_opts.max_dict_bytes: 32768</pre>

來源:https://rockset.com/blog/how-we-use-rocksdb-at-rockset/

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末庆聘,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子勺卢,更是在濱河造成了極大的恐慌伙判,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件黑忱,死亡現(xiàn)場(chǎng)離奇詭異宴抚,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)甫煞,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門菇曲,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人抚吠,你說我怎么就攤上這事常潮。” “怎么了楷力?”我有些...
    開封第一講書人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵喊式,是天一觀的道長(zhǎng)孵户。 經(jīng)常有香客問我,道長(zhǎng)岔留,這世上最難降的妖魔是什么夏哭? 我笑而不...
    開封第一講書人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮献联,結(jié)果婚禮上方庭,老公的妹妹穿的比我還像新娘。我一直安慰自己酱固,他們只是感情好械念,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著运悲,像睡著了一般龄减。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上班眯,一...
    開封第一講書人閱讀 49,764評(píng)論 1 290
  • 那天希停,我揣著相機(jī)與錄音,去河邊找鬼署隘。 笑死宠能,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的磁餐。 我是一名探鬼主播违崇,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼诊霹!你這毒婦竟也來了羞延?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬榮一對(duì)情侶失蹤脾还,失蹤者是張志新(化名)和其女友劉穎伴箩,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體鄙漏,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡嗤谚,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了怔蚌。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片巩步。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖媚创,靈堂內(nèi)的尸體忽然破棺而出渗钉,到底是詐尸還是另有隱情,我是刑警寧澤钞钙,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布鳄橘,位于F島的核電站,受9級(jí)特大地震影響芒炼,放射性物質(zhì)發(fā)生泄漏瘫怜。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一本刽、第九天 我趴在偏房一處隱蔽的房頂上張望鲸湃。 院中可真熱鬧,春花似錦子寓、人聲如沸暗挑。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽炸裆。三九已至,卻和暖如春鲜屏,著一層夾襖步出監(jiān)牢的瞬間烹看,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來泰國(guó)打工洛史, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留惯殊,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓也殖,卻偏偏與公主長(zhǎng)得像土思,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子忆嗜,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容