mongodb快速均衡导入数据

需求环境:

有一个项目需要将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写入效率.

 

posted @ 2015-12-07 15:18  simplelg17  阅读(2722)  评论(0编辑  收藏  举报