最近在做 TiKV 的插入提速的時(shí)候遇到了一個(gè)非常奇怪的問(wèn)題泽艘。因?yàn)?TiKV 底層是使用 RocksDB欲险,RocksDB 會(huì)首先將數(shù)據(jù)寫(xiě)到 WAL,然后在寫(xiě)到 memtable悉盆,再在后臺(tái) flush 到 disk盯荤,然后進(jìn)行 compaction 處理。
因?yàn)槲覀冊(cè)趯?xiě)入 WAL 的時(shí)候并沒(méi)有打開(kāi) sync 標(biāo)記焕盟,照理寫(xiě) WAL 只會(huì)寫(xiě)到操作系統(tǒng)的 page cache,是一個(gè)異步寫(xiě)宏粤,這個(gè)速度應(yīng)該是非辰徘蹋快的。最開(kāi)始我們一直這么認(rèn)為绍哎,但當(dāng)我們將 WAL 放在另一個(gè)盤(pán)上面的時(shí)候来农,突然發(fā)現(xiàn),TiKV 的寫(xiě)入性能竟然提升了 10% 以上崇堰,這個(gè)發(fā)現(xiàn)讓我開(kāi)始思考沃于,寫(xiě) WAL 真的是異步的嗎涩咖。
通常,對(duì)于操作系統(tǒng)的 write 來(lái)說(shuō)繁莹,它首先會(huì)將數(shù)據(jù)寫(xiě)到 page cache檩互,當(dāng) page cache 的 dirty page 積累到一定程度,則開(kāi)始將其 flush 到磁盤(pán)咨演。如果 dirty page 超過(guò)了一個(gè)閾值闸昨,則 write 操作的進(jìn)程就會(huì)進(jìn)行強(qiáng)制刷 dirty page 的操作,即使這些 dirty page 并不是這個(gè)進(jìn)程產(chǎn)生的薄风。
在 Linux 里面饵较,控制 dirty flush 的就是 dirty_background_ratio
和 dirty_ratio
,然后我看了看我們自己系統(tǒng)的配置遭赂,發(fā)現(xiàn) background ratio 是 10循诉,而 dirty ratio 竟然只有坑爹的 20,也就是如果我們的寫(xiě)入壓力很大(主要是 RocksDB 做 compaction)撇他,那么就很容易超過(guò) dirty ratio打洼,自然寫(xiě) WAL 的時(shí)候就變成同步寫(xiě)了。
因?yàn)楝F(xiàn)代 Linux 已經(jīng)對(duì)不同盤(pán)的 dirty page 做了優(yōu)化逆粹,能保證一個(gè)盤(pán)的高 IO 操作不會(huì)過(guò)多的影響到另一個(gè)盤(pán)募疮,所以將 WAL 移到另一個(gè)盤(pán),明顯就能發(fā)現(xiàn)性能提升。
如果只有一個(gè)盤(pán),那就需要調(diào)整 dirty ratio 了砌函,我將 dirty ratio 調(diào)整到 50 之后响禽,發(fā)現(xiàn)寫(xiě)入性能也提升,但時(shí)不時(shí)會(huì)因?yàn)?compaction 導(dǎo)致 QPS 抖動(dòng)航瞭。
對(duì)于 RocksDB 來(lái)說(shuō),大量的 dirty page 是由 compaction 產(chǎn)生的,那么如果我們使用 direct IO退敦,就應(yīng)該能減少 dirty page,設(shè)置之后蚣抗,明顯發(fā)現(xiàn)寫(xiě)入 TiKV 的 QPS 曲線平滑了很多侈百。
這次調(diào)優(yōu)也算是誤打誤撞,至少讓我進(jìn)一步加深了對(duì) Linux 的理解翰铡,后面還需要惡補(bǔ)相關(guān)的操作系統(tǒng)知識(shí)钝域。