最近在测试mongodb分片,边看深入学习mongodb,边结合项目在测试,遇到部分问题,写下来作为参考。
1 创建分片
首先创建文件夹,为配置服务器、路由服务器创建配置文件,本文在本地创建3个分片:
db.runCommand({addshard:”localhost:20000”})
db.runCommand({addshard:”localhost:20001”})
db.runCommand({addshard:”localhost:20002”})
执行的操作过程为:
设置test数据库支持分片
db.runCommand({enablesharding:”test”})
向test的users中插入200,000条数据
use test
for(var i=0;i<200000;i++){
db.device.insert({user_id:i%200,time:ISODate(),size:1,type:2})
}到admin中设置该集合支持分片
db.runCommand({shardcollection:”test.users”,key:{time:1,user_id:1}})
没错,使用的是组合片键,时间与设备id作为片键,OK,问题1来了:
please create an index that starts with the shard key before sharding
告诉我们在分片前请先设置索引,我们回到了test数据库中,然后创建索引。成功了,使用printShardingStatus() 看到正在开始不断的均衡各个分片数据。
期间,因为一般都是查询最后的时间,所以,在创建索引的时候使用的是
db.users.ensureIndex({time:-1,user_id:1})
创建的片键的时候我也用这种方式来创建,提示为:
Unsupported shard key pattern. Pattern must either be a single hashed field, or a list of ascending fields
所以,在选择索引的时候需要慎重的考虑索引的个数,升降序等问题。
2 删除分片
在正式的生成环境中很可能会存在需要删除分片等各种操作
1.删除普通分片
use admin
db.runCommand({removeshard:{“localhost:20001”}})
把第二个分片删除了,期间需要不断的执行这个过程,会看到这个分片中的chunk数量不断的减少,最后会出现一个complete提示,那么我们删除成功了。
因为再次将这个分片加入,此时出现问题2
can’t add shard ‘localhost:20001’ because a local database ’test ’ exists in another shard0000
提示告诉我们还有数据,解决方案
- 进入mongo –port 20001
- 找到该集合 drop users
再次执行添加的操作,添加成功!
2.删除基片数据
每个数据库都会有一个基片,数据首先会存在基片中,然后再平衡的过程中不断的移动数据到其他的分片中.
db.runCommand({removeshard:”localhost:20000”})
问题3来了,命令行中提示:
you need to drop or movePrimary these databases
因为这是一个基片,所以,我们需要修改基片,使用命名:
db.runCommand({“moveprimary”:”test”,”to”:”localhost:20001”})
再次删除,成功了,然后我们再加入这个2000的分片,好吧,在这里我测了N多次,发现了这样的提示:
remote client 127.0.0.1:43368 tried to initialize this host as shard shard0002, but shard name was previously initialized as shard0000
问题4 提示分片的初始名字为shard0000,没有好好的研究过整个迁移的过程到底是怎么的情况,根据什么来迁移的,但是我觉得很可能是名字的原因,我尝试从config数据库中得到解决,不过全部崩溃了。后来我全部删除,然后试着在创建分片的时候使用:
db.runCommand({addshard:”localhost:20000”,name:”shard_01”})
ok,恭喜自己,没有再出现了,查了一遍,我以为可以从config的shards集合中修改名称,不过很可惜,是id,无法更改。
3 更新数据
设计集合的时候是先根据我们的需求,结合查询等来设计索引等结果,分片测试完了之后,查询数据没有问题,更新数据,比如:
does not contain shard key for pattern { time: 1.0, user_id: 1.0 }
问题5来了,mongodb它在更新的时候无法具体到哪个分片上,所以在更新的时候,其条件一定要有片键。
总结:
- 选择索引需要综合考虑实际的需求还有片键的问题,索引过多将会影响插入数据的效率