mongodb移动chunks脚本
随着数据量的增加,可能需要把增加分片(shard),增加分片后,需要将部分的数据移动到新的分片上。本来mongodb是支持自动平衡的(balancer,也就是会根据各个分片的数据情况,自动分片、移动数据到分片上),但由于自动平衡需要大量的系统资源,而且容易导致程序卡死,所以在实际的应用中,我们是将自动平衡关掉的。
我们曾经遇到的问题是。原来2个分片,由于数据量的增加,准备添加一个分片。原来2个分片上,每个分片上有几百个chunks,单个网站(如:用tudou举例),在一个分片上就有近200个chunks。
问题:自动平衡已被停掉
手动移动,数据太多,费时费力。
方法:采用单个网站,使用脚本来移动。


var namespace = "tudou.video";
var cursor = db.chunks.find({ns:namespace});
var s1=0,s2=0,s3=0;
var allCnt = cursor.count();
var perCnt = parseInt(allCnt/3);
print("all-count:"+allCnt+" per-count:"+perCnt);
while (cursor.hasNext()) {
var chunk = cursor.next();
if(chunk.shard=="s1"){
s1++;
print("s1 "+chunk._id);
if(s1>perCnt && s3<perCnt){
print("s1 "+s1+" moveChunk "+chunk.min.md5id);
//printjson(chunk.min);
var ret = db.adminCommand({moveChunk :namespace, find : chunk.min, to : "s3"});
printjson(ret);
if(ret.ok==1){
s3++;
s1--;
}
}
}else if(chunk.shard=="s2"){
s2++;
print("s2 "+chunk._id);
if(s2>perCnt && s3<perCnt){
print("s2 "+s2+" moveChunk "+chunk.min.md5id);
var ret = db.adminCommand({moveChunk :namespace, find : chunk.min, to : "s3"});
printjson(ret);
if(ret.ok==1){
s3++;
s2--;
}
}
}else if(chunk.shard=="s3"){
print("s3 "+chunk._id);
s3++;
}
}

另外的问题:无论是手动还是脚本(其实就是手动,稍简化改移哪个而已)。都有可能程序卡死,可能是分片的某台机器,也可能导致路由mongos卡死。