背景
hugegraph使用jraft+rocksdb的checkpoint實(shí)現(xiàn)了快照栏豺,這樣能保證服務(wù)重啟或者有新節(jié)點(diǎn)加入時(shí)快速同步狀態(tài)機(jī)的數(shù)據(jù)困后。但是由于目前實(shí)現(xiàn)的只是多副本版,所以每一個(gè)服務(wù)都是存儲(chǔ)著全部的數(shù)據(jù)数冬。
當(dāng)服務(wù)導(dǎo)入較多數(shù)據(jù)后节槐,每生成一次快照耗時(shí)幾分鐘,再把快照壓縮又需要幾分鐘拐纱,在這期間占用了較多的CPU資源,并且隨著數(shù)據(jù)量的持續(xù)增長(zhǎng)哥倔,很容易出現(xiàn)上一次的快照還未生成完秸架,又要生成新一波的快照了。很容易導(dǎo)致服務(wù)不可用咆蒿。
在之前的一片文章《定位rocksdb生成快照慢問(wèn)題》中东抹,已經(jīng)提到:生成快照慢是因?yàn)楸4婵煺瘴募拇疟P(pán)和保存原始數(shù)據(jù)的盤(pán)不是同一個(gè)盤(pán),跨盤(pán)是不能進(jìn)行硬鏈接的沃测,所以rocksdb的checkpoint就走了copy file的分支缭黔,這樣自然就慢了。所以解決方法就是:將快照目錄設(shè)置為原始數(shù)據(jù)的兄弟目錄蒂破,這樣能保證是同一塊磁盤(pán)馏谨,checkpoint一定會(huì)走硬鏈接。
生成快照
優(yōu)化前保存快照的目錄結(jié)構(gòu)如下:
disk1/raftlog/snapshot/_128/ss.zip
/snapshot_meta
/ss/g/{md5}/sst,manifest,log
/m/{md5}/sst,manifest,log
/s/{md5}/sst,manifest,log
這里為什么會(huì)存在 md5 這一級(jí)目錄呢附迷?因?yàn)槊總€(gè)store(g/m/s)都可以配置多個(gè)數(shù)據(jù)目錄用來(lái)保存其不同類(lèi)型的數(shù)據(jù)惧互,比如對(duì)于 store g,vertex 和 edge 可以配置成不同的目錄喇伯,所以這里就會(huì)對(duì) vertex 和 edge 的目錄各自做 md5 運(yùn)算喊儡,然后加載的時(shí)候通過(guò)遍歷的方式進(jìn)行目錄匹配,代碼風(fēng)格實(shí)在是不太好稻据。
優(yōu)化后保存快照的目錄結(jié)構(gòu)如下:
# 原始數(shù)據(jù)目錄
disk1/rocksdb_data/g
/m
/s
# 對(duì)應(yīng)的快照目錄
disk1/snapshot_rocksdb_data/g
/m
/s
# 原始數(shù)據(jù)目錄
disk2/rocksdb_vertex/g
/m
/s
# 對(duì)應(yīng)的快照目錄
disk2/snapshot_rocksdb_vertex/g
/m
/s
結(jié)構(gòu)很清晰艾猜,就是在每一個(gè)原始數(shù)據(jù)目錄的父級(jí)目錄下,放置一個(gè)帶snapshot前綴的快照目錄捻悯,然后目錄內(nèi)部的結(jié)構(gòu)與原始數(shù)據(jù)目錄完全相同匆赃。這樣能保證快照目錄與原始數(shù)據(jù)目錄一定是同一個(gè)磁盤(pán)上的,能夠使用硬鏈接的方式快速生成快照秋度。
所以設(shè)置好快照目錄結(jié)構(gòu)后炸庞,代碼就很簡(jiǎn)單了,因?yàn)楹诵牡恼{(diào)用 checkpoint 的部分已經(jīng)實(shí)現(xiàn)過(guò)了荚斯,只需要將目錄的層級(jí)關(guān)系配置好即可埠居。具體實(shí)現(xiàn)中使用 Path 類(lèi)做相關(guān)的操作比用字符串或 File 都方便一些查牌。
加載快照
上面已經(jīng)實(shí)現(xiàn)了秒極生成快照,但還有一個(gè)問(wèn)題就是:如何加載快照滥壕?
為什么加載快照會(huì)成為一個(gè)問(wèn)題呢纸颜,直接把原始數(shù)據(jù)刪除,然后把快照目錄重命名為原始數(shù)據(jù)目錄不就可以了嗎绎橘?核心步驟當(dāng)然是這樣胁孙,但是這樣存在的一個(gè)問(wèn)題是:如果本次啟動(dòng)服務(wù)刪除了快照目錄,并且在下次生成快照前服務(wù)就宕掉了称鳞,那下次啟動(dòng)服務(wù)的時(shí)候可就沒(méi)有快照目錄供重命名了涮较。所以在raft模式下,不能在加載快照時(shí)把快照目錄刪除冈止。
既然不能刪除狂票,又必須得加載快照,怎么辦呢熙暴?很簡(jiǎn)單闺属,再做一次硬鏈接不就可以了嗎。
話不多說(shuō)周霉,看下面的示意圖即可掂器。
# 原始數(shù)據(jù)目錄
disk1/rocksdb_data/g
/g_link <--------+
/m |
/m_link |
/s |
/s_link |
# 對(duì)應(yīng)的快照目錄 |
disk1/snapshot_rocksdb_data/g -------+
/m
/s
# 原始數(shù)據(jù)目錄
disk2/rocksdb_vertex/g
/g_link
/m
/m_link
/s
/s_link
# 對(duì)應(yīng)的快照目錄
disk2/snapshot_rocksdb_vertex/g
/m
/s
加載快照時(shí)的日志
2021-03-26 11:23:24 11696 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.raft.StoreStateMachine [] - The node 127.0.0.1:8281 start snapshot loading
2021-03-26 11:23:24 11896 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStdSessions [] - Delete origin data directory /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/m
2021-03-26 11:23:24 11903 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStdSessions [] - Move snapshot directory /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/m_link to /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/m
2021-03-26 11:23:24 11936 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - The store 'm' resume snapshot successfully
2021-03-26 11:23:24 11970 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStdSessions [] - Delete origin data directory /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/g
2021-03-26 11:23:24 11973 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStdSessions [] - Move snapshot directory /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/g_link to /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/g
2021-03-26 11:23:24 11989 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStdSessions [] - Delete origin data directory /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-vertex/g
2021-03-26 11:23:24 11991 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStdSessions [] - Move snapshot directory /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-vertex/g_link to /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-vertex/g
2021-03-26 11:23:24 11997 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - The store 'g' resume snapshot successfully
2021-03-26 11:23:24 12020 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStdSessions [] - Delete origin data directory /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/s
2021-03-26 11:23:24 12023 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStdSessions [] - Move snapshot directory /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/s_link to /Users/liningrui/IdeaProjects/baidu/xbu-data/hugegraph/node1/rocksdb-data/s
2021-03-26 11:23:24 12037 [JRaft-FSMCaller-Disruptor-0] [INFO ] com.baidu.hugegraph.backend.store.rocksdb.RocksDBStore [] - The store 's' resume snapshot successfully