需求環境:
有一個項目需要將mongodb sharding從2.6升級到3.0 並使用wt引擎,其中2.6環境很多collectiong開啟了Sharding,且數據量很大.
選擇mongodump,mongorestore方式
問題:
在restore步驟出現了2個問題
1)大數量數據導入緩慢時間花費長
2)chunks分配不均勻,需要很長時間做balance.
分析原因:
針對以上問題我對mongodb的進行了初步的學習和研究,同時也查看了一些優秀的博客,發現部分原因:
mongodb導入大量數據,會涉及到chunks的分裂和新chunk文件分配這個過程耗費時間,並且自動均衡策略不能均勻分配chunks到每個shard這在數據導入時也會引起不同的shard io使用差距大,無法合理使用整個集群的io。
解決辦法:
可以提前預先分配chunks並且均勻的移動到每個shard,針對這個場景我寫了一個簡單的python腳本實現
#! /usr/bin/python #input basic info ns = "crawler.logsData" shard_key = "_id" shards= ["shard01","shard02","shard03","shard04"] min_key = 237223617 max_key = 264171274 avg_doc_size = 2340 #byte chunk_size = 64*1024*1024 #byte 64MB fragment = 0.9 def split_chunk(ns,shard_key,shards,min_key,max_key,avg_doc_size,chunk_size,fragment ): fname='./'+ns+'.js' f=open(fname,'a') f.write("db = db.getSiblingDB('admin')"+'\n') docs_per_chunk = int(chunk_size*fragment/avg_doc_size) key_value=min_key+docs_per_chunk shard_counter = 0 shardlen = len(shards) while key_value < max_key: str_split_chunk=('db.runCommand( { split : "%s", middle : {%s:%d} } )')% (ns,shard_key,key_value) str_move_chunk=('db.runCommand({moveChunk: "%s", find: {%s:%d}, to: "%s"})')%(ns,shard_key,key_value,shards[shard_counter]) shard_counter = shard_counter + 1 if shard_counter == shardlen: shard_counter = 0 key_value=key_value+docs_per_chunk f.write(str_split_chunk+'\n') f.write(str_move_chunk+'\n') # print(str_split_chunk) # print(str_move_chunk) f.closed split_chunk(ns,shard_key,shards,min_key,max_key,avg_doc_size,chunk_size,fragment)
step1
編輯以上腳本填寫參數運行 會生成一個分配和move chunks的js文件文件名是crawler.logsData.js
step2
使用以下命令運行可以實現chunks的均勻預分配
time mongo admin -u username -p'passwd' < /home/user/crawler.logsData.js
step3
運行以下命令實現collection crawler.logsData的數據導入
time mongorestore --host *** --port ** --db crawler --collection logsData -u username -p "passwd" /home/user/crawler/logsData.bson
注意:
step1&2可以預先處理不必等到遷移時,這樣分配chunks和 chunks balance的時間就可以在實際遷移時節約出來了,這樣做還可減少導入數據發生chunk split.
以下是我的測試結果 mongorestore 時間花費 26GB數據 14分鍾
發散:
針對以上測試,我們進一步思考,是否可以把這個方式使用到維護方面,如果我們預先知道collection的每月的數據增長量,那么就可以提前為下一個月的數據做chunks的預分配,
這樣就不必使用mongodb balance因為在寫入數據時就已經按照我們的規划均勻寫入數據,這樣可以均衡sharding的io使用率,提高整個sharding寫入效率.