mongodb的分片

//场景

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();两次可以验证如上所说。

路由服务器设置了chunkSize1M,分区会在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

 

 

  架构如下:

      1shard服务器:使用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 

 

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值