sstableloader工具使用及原理解析
sstableloader是cassandra提供的bulkload工具,可以將sstable文件導(dǎo)入到集群中。本文詳細(xì)介紹其用法和實(shí)現(xiàn)原理。
用法
sstableloader工具在cassandra的bin目錄下面,用法如下:
bin/sstableloader <options> <dir_path>具體的選項(xiàng)可以參考官方文檔的介紹,常見(jiàn)的選項(xiàng)有:
-d, –nodes 目標(biāo)集群的nodes
-u, –username 用戶(hù)名
-pw, –password 密碼
-t, –throttle 限速,單位Mbits/s (默認(rèn)不限制)
-cph, –connections-per-host 和每個(gè)節(jié)點(diǎn)建立多少連接
<dir_path>參數(shù)指定要導(dǎo)入的sstable文件所在的目錄。需要注意的是sstableloader會(huì)把目錄名作為表名,上一級(jí)目錄名作為keyspace名稱(chēng)。例如sstableloader /whatever/path/test/t ...這個(gè)命令會(huì)把數(shù)據(jù)導(dǎo)入到test.t這個(gè)表里面。
sstableloader常見(jiàn)的使用場(chǎng)景包括:
- bulkload批量寫(xiě)入數(shù)據(jù)
- 跨集群數(shù)據(jù)遷移
- 從備份的snapshot文件恢復(fù)數(shù)據(jù)
bulkload批量寫(xiě)入
cassandra中提供了SSTableWriter這個(gè)類(lèi)來(lái)實(shí)現(xiàn)對(duì)sstable的寫(xiě)入,使用這個(gè)類(lèi)用戶(hù)可以不需要關(guān)心sstable的具體文件格式。需要注意的是使用這個(gè)類(lèi)需要依賴(lài)cassandra-all而不是cassandra的java driver。如下代碼示意了如何使用SSTableWriter在本地生成sstable文件:
final String KS = "cql_keyspace7";final String TABLE = "table7";final String schema = "CREATE TABLE " + KS + "." + TABLE + " ("+ " k int,"+ " c1 int,"+ " c2 int,"+ " v blob,"+ " PRIMARY KEY (k, c1, c2)"+ ")";File tempdir = Files.createTempDir();File dataDir = new File(tempdir.getAbsolutePath() + File.separator + KS + File.separator + TABLE);assert dataDir.mkdirs();CQLSSTableWriter writer = CQLSSTableWriter.builder().inDirectory(dataDir).forTable(schema).using("INSERT INTO " + KS + "." + TABLE + " (k, c1, c2, v) VALUES (?, ?, ?, textAsBlob(?))").build();writer.addRow(1, 2, 3, "abc");writer.addRow(4, 5, 6, "efg");writer.close();生成文件之后,可以使用sstableloader將生成的文件導(dǎo)入到cassandra中。使用這種方式寫(xiě)入數(shù)據(jù),減少了對(duì)服務(wù)器的請(qǐng)求量,而且寫(xiě)入本地文件會(huì)比向服務(wù)器寫(xiě)入數(shù)據(jù)要快,很適合大批量數(shù)據(jù)的離線(xiàn)導(dǎo)入。
集群間數(shù)據(jù)遷移
sstableloader也可以用來(lái)做集群間的數(shù)據(jù)遷移。具體步驟如下:
1 在目標(biāo)集群創(chuàng)建要同步的表的schema。
2 停止源集群寫(xiě)入(針對(duì)停機(jī)遷移),或是開(kāi)啟增量數(shù)據(jù)的遷移(針對(duì)不停機(jī)遷移)。
3 在源集群的每個(gè)節(jié)點(diǎn)執(zhí)行flush:bin/nodetool flush。
4 在源集群節(jié)點(diǎn)上執(zhí)行sstableloader將數(shù)據(jù)文件導(dǎo)入到目標(biāo)集群中。
原理
sstableloader會(huì)首先通過(guò)java客戶(hù)端與服務(wù)器建立連接,并讀取meta信息。之后在storage_port通過(guò)streaming協(xié)議將sstable文件發(fā)送到各個(gè)節(jié)點(diǎn)上。在這個(gè)過(guò)程中,sstableloader并不是簡(jiǎn)單的把數(shù)據(jù)文件拷貝到每個(gè)節(jié)點(diǎn),而是根據(jù)meta中的相關(guān)信息,給每個(gè)節(jié)點(diǎn)發(fā)送他所管理的那一段數(shù)據(jù)。
下面簡(jiǎn)單介紹一下cassandra中的streaming協(xié)議協(xié)議。
streaming協(xié)議
在Cassandra中,streaming協(xié)議用來(lái)在兩個(gè)節(jié)點(diǎn)之間同步sstable中的一段數(shù)據(jù)的過(guò)程,通常用于數(shù)據(jù)修復(fù)或移動(dòng)的過(guò)程。除了sstableloader以外,如下場(chǎng)景中也可能會(huì)有streaming的過(guò)程:
- repair
- bootstrap過(guò)程
- gossip收到和本節(jié)點(diǎn)有關(guān)的REMOVED_TOKEN狀態(tài)變化
- nodetool里面會(huì)觸發(fā)數(shù)據(jù)移動(dòng)或修復(fù)的命令,例如repair,rebuild,removenode,move
Streaming過(guò)程中兩個(gè)節(jié)點(diǎn)的網(wǎng)絡(luò)交互如下圖所示:
這個(gè)過(guò)程大致可以分為如下四個(gè)階段:
1 建立連接
2 streaming準(zhǔn)備階段
3 streaming階段
4 完成
1 建立連接
這個(gè)階段主要是建立連接并把連接和StreamSession關(guān)聯(lián)起來(lái)。
stream的發(fā)起節(jié)點(diǎn)創(chuàng)建一個(gè)StreamSession對(duì)象,并建立兩個(gè)到遠(yuǎn)端節(jié)點(diǎn)的連接,一個(gè)用于后續(xù)的發(fā)送消息, 一個(gè)用于接收消息。之后會(huì)通過(guò)這兩個(gè)連接向遠(yuǎn)端發(fā)送StreamInit消息,通知遠(yuǎn)端節(jié)點(diǎn)開(kāi)啟一次streaming,并標(biāo)明每個(gè)連接的用途。
遠(yuǎn)端收到StreamInit消息后,也會(huì)創(chuàng)建自己的StreamSession對(duì)象,并將收到StreamInit消息的兩個(gè)連接和StreamSession關(guān)聯(lián)起來(lái)。
連接建立完成后,進(jìn)入準(zhǔn)備階段。
2 準(zhǔn)備階段
這個(gè)階段主要用于協(xié)商節(jié)點(diǎn)之間需要傳輸?shù)奈募巍?br /> 發(fā)起節(jié)點(diǎn)首先發(fā)送一個(gè)PrepareMessage,其中包含當(dāng)前節(jié)點(diǎn)會(huì)向遠(yuǎn)端節(jié)點(diǎn)發(fā)送哪些文件或片段,以及需要對(duì)方提供哪些表的哪些range的數(shù)據(jù)。
遠(yuǎn)端節(jié)點(diǎn)收到請(qǐng)求后,會(huì)根據(jù)請(qǐng)求的range查找對(duì)應(yīng)的sstable,然后向發(fā)起節(jié)點(diǎn)返回一個(gè)PrepareMessage,其中包含要發(fā)送哪些sstable的哪些片段,之后遠(yuǎn)端節(jié)點(diǎn)進(jìn)入streaming階段。
發(fā)起節(jié)點(diǎn)收到PrepareMessage后,記錄要接收的sstable片段,然后進(jìn)入streaming階段。
3 streaming階段
這個(gè)階段就開(kāi)始進(jìn)行文件傳輸了。發(fā)送端和接收端會(huì)分別建立相應(yīng)的任務(wù)。
發(fā)送端會(huì)針對(duì)要進(jìn)行streaming的文件,按順序發(fā)送FileMessage。FileMessage由消息頭FileMessageHeader和文件內(nèi)容的流組成。當(dāng)所有文件發(fā)送完成后,StreamTransferTask標(biāo)記為完成。
接收端將收到的文件內(nèi)容寫(xiě)入sstable。當(dāng)一個(gè)StreamReceiveTask中的所有文件都接收完成后,將sstable加入到ColumnFamilyStore中。
如果接收過(guò)程中發(fā)生錯(cuò)誤,接收端會(huì)發(fā)送一個(gè)SessionFailedMessage給發(fā)送端,并關(guān)閉StreamSession。
當(dāng)所有發(fā)送和接收任務(wù)都完成后,進(jìn)入完成階段。
4 完成階段
當(dāng)一個(gè)節(jié)點(diǎn)完成所有的發(fā)送和接收任務(wù)后,如果該節(jié)點(diǎn)已經(jīng)收到了CompleteMessage,則會(huì)向?qū)Ψ桨l(fā)送CompleteMessage并關(guān)閉session;如果還沒(méi)有收到CompleteMessage,則會(huì)向?qū)Ψ桨l(fā)送CompleteMessage并等待對(duì)方返回。
原文鏈接
本文為云棲社區(qū)原創(chuàng)內(nèi)容,未經(jīng)允許不得轉(zhuǎn)載。
總結(jié)
以上是生活随笔為你收集整理的sstableloader工具使用及原理解析的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 深度 | 带领国产数据库走向世界,POL
- 下一篇: 对话阿里敏捷教练 | 成功辅导过淘宝、闲