//场景
a.机器的磁盘不够用了
b.某张表的数据很大,查询效率很慢,需要分片来保存,提高查询效率
一般来说,先要从不分片开始,然后在需要的时候将其转换成分片.
c 单个mongod已经无法满足写数据的性能需要了(这里复习一下,如果想要增加读性能,较好的方案是采用搭建主从结构,且让从节点可以响应查询请求)
d 想将大量的数据放到内存中提高性能,一台机器的内存大小永远有极限(这就是纵向扩展和横向扩展的区别)
//关键字
客户端: 客户端说,你数据库分片不分片跟我没关系,我只需要连接mongos,然后查询完事
mongos: 就是一个路由服务器,它会根据管理员设置的“片键”将数据分摊到自己管理的mongod集群,数据和片的对应关系以及相应的配置信息保存在"config服务器"上。它路由所有的请求,然后将结果聚合.它本身并不存储数据或者配置信息【分片所有的后台命令都在路由中敲定】
ConfigServer:存储了集群的配置信息:数据和片的对应关系
mongod: 我们要分片的mongodb服务器,每个mongodb都可以做
//实际操作
参考 http://blog.csdn.net/irelandken/article/details/8003203
1:创建存储目录
mkdir -p /scmgt/data/shard/s1
mkdir -p /scmgt/data/shard/s2
mkdir -p /scmgt/data/shard/s3
2:启动Config配置服务器
mkdir -p /scmgt/shard/config/
/scmgt/mongodb/mongodb/bin/mongod --dbpath=/scmgt/shard/config --logpath=/scmgt/shard/info.log --logappend --port=9334 --fork
3.启动mongs路由服务器
【只需要--configdb配置服务器地址】
【mongos启动参数中,chunkSize这一项是用来指定chunk的大小的,单位是MB,默认大小为200MB,为了方便测试Sharding效果,我们把chunkSize指定为 1MB。意思是当这个分片中插入的数据大于1M时开始进行数据转移】
/scmgt/mongodb/mongodb/bin/mongos --configdb=localhost:9334 --chunkSize 1 --logpath=/scmgt/shard/route.log --logappend --port 9333 --fork
4:启动分片服务器
/scmgt/mongodb/mongodb/bin/mongod --dbpath=/scmgt/data/shard/s1 --logpath=/scmgt/shard/s1.log --logappend --port=9335 --fork
/scmgt/mongodb/mongodb/bin/mongod --dbpath=/scmgt/data/shard/s2 --logpath=/scmgt/shard/s2.log --logappend --port=9336 --fork
/scmgt/mongodb/mongodb/bin/mongod --dbpath=/scmgt/data/shard/s3 --logpath=/scmgt/shard/s3.log --logappend --port=9337 --fork
5:连接mongos路由服务器配置Sharding
/scmgt/mongodb/mongodb/bin/mongo --port 9333 [注意,必须登陆路由服务器]
use admin
//添加分片节点,每个分片都是一个副本集【allowLocal:true仅仅开发时才将分片配置到本地,生产时不能这样】
db.runCommand({addshard:"localhost:9335",allowLocal:true})
db.runCommand({addshard:"localhost:9336",allowLocal:true})
db.runCommand({addshard:"localhost:9337",allowLocal:true,”maxSize”:20000})
注意:还可以为不同分片设置大小”maxSize”:20000(20gb)
//要分片的数据库
db.runCommand({enablesharding:"mydb"})
//设置要分片的集合:users集合,name字段为key来分片
db.runCommand({shardcollection:"mydb.users",key:{name:1}})
//db.runCommand({shardcollection:"mydb.users",key:{_id:1,name:1,name:1}})
【如果出现"errmsg" : "please create an index that starts with the shard key before sharding.",请创建索引】
6:开始导入数据
略过
7:查看结果
/scmgt/mongodb/mongodb/bin/mongo --port 9333
查看分区情况
use mydb
db.users.getShardDistribution()
db.users.stats();
查看分区情况
use admin
db.printShardingStatus()
9.向已经分片的数据中,再次添加分片
db.runCommand({addshard:"localhost:9337",allowLocal:true})
会自动平衡数据
10。自动平衡数据
还需要说明的是,一开始插入数据时,数据是只插入到其中一块分片上的,插入完毕后,mongodb内部开始在各片之间进行数据的移动,这个过程可能不是立即的,mongodb足够智能会根据当前负载决定是立即进行移动还是稍后移动。
在插入数据后,立马执行db.users.stats();两次可以验证如上所说。
路由服务器设置了chunkSize为1M,分区会在10倍也就是10M范围内分区
11.删除节点 时间很久,要慢慢等待,
db.runCommand({removeshard:"localhost:9335"})
db.runCommand({removeshard:"localhost:9336"})
db.runCommand({removeshard:"localhost:9337"})
【如果删除的是主节点,还需要】
db.runCommand({"moveprimary" : "mydb","to" : "localhost:9336"})
【删除完后还需要在执行一次db.runCommand({removeshard:"localhost:xxxx"}) 才能完整删除】
【观察删除情况:】
use admin
db.printShardingStatus()
或者
看表里面数据
【这种方式不能删除所有分片,最后一个分片是不能删除的】
12.完全删除所有分片和集合,重新建立新的
杀掉进程
ps -ef| grep mong
kill -2
删除数据
cd /scmgt/data/shard/s1 rm -rf /scmgt/data/shard/s1/*
cd /scmgt/data/shard/s2 rm -rf /scmgt/data/shard/s2/*
cd /scmgt/data/shard/s3 rm -rf /scmgt/data/shard/s3/*
删除配置服务器配置
rm -rf /scmgt/shard/config/*
//片建选择【必须有索引,推荐组合键,键值的变化大】
参考http://www.cnblogs.com/spnt/archive/2012/07/27/2611540.html
片键应该有较多变化的值,如果片键设定为性别,只有“男”和“女”两种值,则这个集合就最多被分为两片,如果集合太大,这种分片不会最终解决效率的问题!这里我们可以看出,片键的选择和创建索引时键的选择原则是相似的,实际使用中,通常片键就是创建索引使用的键
一个片键包含两个字段,并确保第二个字段有非常多不同的值供MongoDB用来进行分割,比如大部分的查询都和时间关联,可以用时间字段做第二个字段,又可以减轻负载。
//需要验证
1:将已有数据的集合分片,是否会分片
原来的数据会自动分片,【最好跟oracle分区一样,重新导入】
2:设置不同的键,分区是否平衡
根据键值的浮动区间,分片大小会不平衡,如果递增的键值,大部分数据后会保存在最后一个分区里面。
3:程序查询是否是查询路由ip地址即可
是的,用户只需要跟路由打交道,不需要知道路由跟分片的事
4:新增或者删除分片,是否会平衡移动数据
删除分片会先移动数据再删除分片,过程很慢
新增分片后,mogondb后台会自动平衡移动数据
//优化知识扩展
1:永远不要再分片将要满的时候再扩容,必须未雨绸缪
2:如果选错了片建,想取消片键
可以把所有分片数据放到1个分片上,然后导出分片数据到另外一个集合里面,删除配置服务器配置,删除分片,重新做分片
3:分片时使用mapreduce,每个分片都会执行自己的mapreduce
//Replica Sets + Sharding 方案 及 chunks块 和 片键分析
参考
http://blog.csdn.net/irelandken/article/details/8003195
http://www.cnblogs.com/spnt/archive/2012/07/26/2610070.html
架构如下:
1,shard服务器:使用Replica Sets确保每个数据节点都具有备份、自动容错转移、自动恢复的能力。
2,配置服务器:使用使用3个配置服务器确保元数据完整性
3,路由进程:使用3个路由进程实现平衡,提高客户端接入性能,架构如下
【启动多个路由来平衡客户端访问】
因为路由不保存配置只是个连接点,所有只需要指向一样的配置即可
【启动多个配置服务器】
/Apps/mongo/bin/mongos --port 50000 --configdb 127.0.0.1:40000,127.0.0.1:40001,127.0.0.1:40002 --chunkSize 1
【副本集分片【其中shard里面的都是同一副本集的】】
db.runCommand({addshard:"replset1/127.0.0.1:18010,127.0.0.1:18011,127.0.0.1:18012",allowLocal:true})
分类: MongoDB2012-09-21 10:49