sstableloader工具使用及原理解析
sstableloader是cassandra提供的bulkload工具,可以將sstable文件導入到集群中。本文詳細介紹其用法和實現原理。
用法
sstableloader工具在cassandra的bin目錄下面,用法如下:
bin/sstableloader <options> <dir_path>具體的選項可以參考官方文檔的介紹,常見的選項有:
 -d, –nodes 目標集群的nodes
 -u, –username 用戶名
 -pw, –password 密碼
 -t, –throttle 限速,單位Mbits/s (默認不限制)
 -cph, –connections-per-host 和每個節點建立多少連接
<dir_path>參數指定要導入的sstable文件所在的目錄。需要注意的是sstableloader會把目錄名作為表名,上一級目錄名作為keyspace名稱。例如sstableloader /whatever/path/test/t ...這個命令會把數據導入到test.t這個表里面。
sstableloader常見的使用場景包括:
- bulkload批量寫入數據
- 跨集群數據遷移
- 從備份的snapshot文件恢復數據
bulkload批量寫入
cassandra中提供了SSTableWriter這個類來實現對sstable的寫入,使用這個類用戶可以不需要關心sstable的具體文件格式。需要注意的是使用這個類需要依賴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將生成的文件導入到cassandra中。使用這種方式寫入數據,減少了對服務器的請求量,而且寫入本地文件會比向服務器寫入數據要快,很適合大批量數據的離線導入。
集群間數據遷移
sstableloader也可以用來做集群間的數據遷移。具體步驟如下:
 1 在目標集群創建要同步的表的schema。
 2 停止源集群寫入(針對停機遷移),或是開啟增量數據的遷移(針對不停機遷移)。
 3 在源集群的每個節點執行flush:bin/nodetool flush。
 4 在源集群節點上執行sstableloader將數據文件導入到目標集群中。
原理
sstableloader會首先通過java客戶端與服務器建立連接,并讀取meta信息。之后在storage_port通過streaming協議將sstable文件發送到各個節點上。在這個過程中,sstableloader并不是簡單的把數據文件拷貝到每個節點,而是根據meta中的相關信息,給每個節點發送他所管理的那一段數據。
 下面簡單介紹一下cassandra中的streaming協議協議。
streaming協議
在Cassandra中,streaming協議用來在兩個節點之間同步sstable中的一段數據的過程,通常用于數據修復或移動的過程。除了sstableloader以外,如下場景中也可能會有streaming的過程:
- repair
- bootstrap過程
- gossip收到和本節點有關的REMOVED_TOKEN狀態變化
- nodetool里面會觸發數據移動或修復的命令,例如repair,rebuild,removenode,move
 Streaming過程中兩個節點的網絡交互如下圖所示:
這個過程大致可以分為如下四個階段:
 1 建立連接
 2 streaming準備階段
 3 streaming階段
 4 完成
1 建立連接
這個階段主要是建立連接并把連接和StreamSession關聯起來。
 stream的發起節點創建一個StreamSession對象,并建立兩個到遠端節點的連接,一個用于后續的發送消息, 一個用于接收消息。之后會通過這兩個連接向遠端發送StreamInit消息,通知遠端節點開啟一次streaming,并標明每個連接的用途。
 遠端收到StreamInit消息后,也會創建自己的StreamSession對象,并將收到StreamInit消息的兩個連接和StreamSession關聯起來。
 連接建立完成后,進入準備階段。
2 準備階段
這個階段主要用于協商節點之間需要傳輸的文件片段。
 發起節點首先發送一個PrepareMessage,其中包含當前節點會向遠端節點發送哪些文件或片段,以及需要對方提供哪些表的哪些range的數據。
 遠端節點收到請求后,會根據請求的range查找對應的sstable,然后向發起節點返回一個PrepareMessage,其中包含要發送哪些sstable的哪些片段,之后遠端節點進入streaming階段。
 發起節點收到PrepareMessage后,記錄要接收的sstable片段,然后進入streaming階段。
3 streaming階段
這個階段就開始進行文件傳輸了。發送端和接收端會分別建立相應的任務。
 發送端會針對要進行streaming的文件,按順序發送FileMessage。FileMessage由消息頭FileMessageHeader和文件內容的流組成。當所有文件發送完成后,StreamTransferTask標記為完成。
 接收端將收到的文件內容寫入sstable。當一個StreamReceiveTask中的所有文件都接收完成后,將sstable加入到ColumnFamilyStore中。
 如果接收過程中發生錯誤,接收端會發送一個SessionFailedMessage給發送端,并關閉StreamSession。
 當所有發送和接收任務都完成后,進入完成階段。
4 完成階段
當一個節點完成所有的發送和接收任務后,如果該節點已經收到了CompleteMessage,則會向對方發送CompleteMessage并關閉session;如果還沒有收到CompleteMessage,則會向對方發送CompleteMessage并等待對方返回。
原文鏈接
 本文為云棲社區原創內容,未經允許不得轉載。
總結
以上是生活随笔為你收集整理的sstableloader工具使用及原理解析的全部內容,希望文章能夠幫你解決所遇到的問題。
 
                            
                        - 上一篇: 深度 | 带领国产数据库走向世界,POL
- 下一篇: 对话阿里敏捷教练 | 成功辅导过淘宝、闲
