Mongodb分片实践

Mongodb分片实践

分片简介:

分片(sharding)是指将数据拆分,将其分散存在不同的机器上的过程。将数据分散到不同的机器上,不需要功能强大的大型计算机就可以存储更多的数据,处理更大的负载。

手动分片:几乎所有的数据库软件都能进行手动分片。应用需要维护与不同数据库服务器的链接,管理不同服务器上的数据,存储、查询都在不同服务器上进行。这种方法可以很好地工作,但是不易维护,从集群中增删节点困难,调整数据分布和负载模式也不轻松。

自动分片:mongodb支持自动分片,集群自动切分数据,做负载均衡。可以摆脱手动分片的管理困扰。

Mongo的自动分片:

Mongodb分片的基本思想就是将集合切分成小块。这些块分散到若干片里面,每个片只负责总数据的一部分。应用程序不必知道哪片对应哪些数据,甚至不需要知道数据已经被拆分了,所以之前需要启动一个路由进程,即mongos

Mongos知道所有数据的存放位置,所以应用可以连接它来正常发送请求。对应用来说,它仅知道连接了一个普通的mongodMongos隐藏了分片的细节,对客户端来说是透明的。跟普通的mongod没什么两样。

几个概念:

Mongod-servermongodb进程服务器,一般指具体分片的服务器

mongoConfig-server:配置服务器,存储了集群的配置信息:数据和片的对应关系。Mongos不永久存放数据,所以需要个地方存放分片配置。它会从配置服务器获取同步数据。

Mongs-server:路由进程,一般客户端连接的是这个。它路由所有请求,然后将结果聚合。它本身并不存储数据或者配置信息(但会缓存配置服务器的信息)。

分片逻辑图:

何时分片:

1. 机器的磁盘不够用了

2. 单个mongod已经不能满足写数据的性能需求了

3. 湘江大量数据放在内存中提高性能。

一般来说,先要从不分片开始,然后在需要时将其转换成分片的。

片键

分片时,需要从集合里选一个键,用该键的值作为数据拆分的依据,这个键被称为片键(shard key)。

如:用name作为片键,第一片可能会存放名字以A-F开头的文档,第二片存储G-P开头的名字,第三片存储Q-Z的名字。随着添加、删除片,MongoDB会重新平衡数据,使每片的流量都比较均衡,数据量也在合理范围内。

建立分片

建立分片有两步:启动实际的服务器,然后决定怎么切分数据.

分片一般会有3个组成部分:

a.

片就是保存子集合数据的容器,片可是单个的mongod服务器(开发和测试用),也可以是副本集(生产用).所以一片

有多台服务器,也只能有一个主服务器,其他的服务器保存相同的数据.

b.mongos

mongos就是MongoDB配的路由器进程.它路由所有的请求,然后将结果聚合.它本身并不存储数据或者配置信息

但会缓存配置服务器的信息.

c.配置服务器

配置服务器存储了集群的配置信息:数据和片的对应关系.mongos不永久存房数据,所以需要个地方存放分片的配置.

它会从配置服务器获取同步数据.


实例

目标:192.168.229.79 192.168.229.80 两台服务器作为mongod服务器,分别为shard1shard2. 192.168.229.80 作为配置和路由服务器。

前提:下载mongo包,解压,安装目录为:/export/servers/mongodb-linux-x86_64-2.0.4

1. 在79上启动mongod进程

mkdir -p ./data/shard1

bin/mongod -shardsvr -port 27017 -dbpath=./data/shard1/ -logpath=./data/shard1.log --fork

2. 在80上启动mongod进程

mkdir -p ./data/shard2

bin/mongod -shardsvr -port 27017 -dbpath=./data/shard2/ -logpath=./data/shard2.log --fork

通过ps命令查看下进程,如图:


如果没启动成功看下data目录的权限,设为root权限:

sudo chmod -R 777 /data/shard11

3. 在80上启动mongconfig进程

mkdir /data/config

bin/mongod -configsvr -dbpath=./data/config -port 20000 -logpath=./data/config.log --fork

config启动一台即可,同样通过ps命令查看是否已启动。

注意上述三个步骤的命令,mongod-shardsvrconfigconfigsvr

4. 在80上启动mongos进程

bin/mongos -configdb 192.168.229.80:20000 -port 30000 -chunkSize 1 -logpath=./data/mongos.log --fork

注意上述几个标蓝的内容:

命令:configdb

192.168.229.80:20000:这个是步骤3中的配置服务器的ip和端口

chunkSize一般默认是64M,但是为了测试,我们把它改小,设为1M

Chunksmongodb不是一个分片上存储一个空间,而是每个分片包含多个区间,每个区间就是一个块。

平衡:如果存在多个可用的分片,只要块的数量足够多,mongodb就会把数据迁移到其他分片上,这个迁移的过程叫做平衡。

5. 链接mongos

如图:我在192.168.192.75上链接80mongs进程

6. 添加片

db.runCommand({"addshard":"192.168.229.79:27017"})

db.runCommand({"addshard":"192.168.229.80:27017"})

如果顺利,你应该能看到{ ”ok“ : 1}的字样。这样你就成功的把两个shard加入了分片。现在你还需要制定分片的规则。

7. 激活分片设置

db.runCommand({"enablesharding": "ndmongo"})

8. 添加片键

db.runCommand({"shardcollection":"mydb.user", "key":{"_id":1}})

Mydb:我的测试数据库名称

User: 我的测试集合名称

Key: "_id"为我定义的文档的一个字段。

如:


9. 查看状态

通过:

db.printShardingStatus()

如图:


10. 执行测试数据

 mongos> for(i=0;i<1000000;i++){ db.user.insert({"_id":i}); }

注意,这里一定要从mongos进程添加数据,最开始我从单片(79)上添加了1万条,发现从mongos查询不到。

11. 查询平衡结果

分片在自动移动:

80:


:79:


查看mongos状态:

 

继续查看79:

 

查看80:


再次查看mongos状态:


可以看到这次平衡了。

遇到的问题:

1.发现79上插入数据总是报失败:

> db.users.save({"name":"zhangsan"})

_filename.empty() 

 

而80上是ok的。

 

最后怀疑是没有空间所致,查看目录,果然,mydb没有空间可以预分配:

 

删除admin数据库:

 

重新插入数据,结果ok:

 

 

2.设置的块太大了,看不出效果:可以调整块的大小,如

 

Mongo架构:

mongodb的逻辑存储结构:


物理结构:

如图:


可以看到里面有2种文件,一种是mydb.n(n表示数字,从0开始,由于我用的是64位机器,所以文件从64M开始,每次翻倍,直到2G后每次都生成2G),这是数据文件,数据文件在内部分为很多块,每一块保存一个名字空间的数据,块与块之间用链表连接,每块中的每条数据间也用链表连接。还有一个是16m的文件mydb.nsmydb.ns是一个命名空间文件,用来保存名字空间对应的元数据,mydb.ns是一个hashtable,保存了每个名字空间中的储存信息,包括大小,块数,第一块位置,最后一块位置,索引信息等,而块的位置又通过文件序号(后面跟的数字)与文件中的偏移量来确定。

   需要注意的是,我现在数据库里面只有一条不到2k的数据,为什么会有2个数据文件,一个64m,一个128m呢?

   这正是由mongodb的存储空间预先分配决定的,当你开始往64m的文件中存储数据时,同时mongodb会预先分配一个128m的文件空间,并且用0来填充,这样每次都有一个文件的空间是完全没有存放数据的,虽然浪费了一定大小的空间,但是也免去了每次写入时分配空间消耗的时间,加快了存储速度。

     看一下我在网上找的一张图片,mongodb的文件内部存储结构:

      

 

mongodb在数据存储上按命名空间来划分,一个Collection是一个命名空间,一个索引也是一个命名空间。

同一个命名空间的数据被分成很多个Extent,Extent之间使用双向链表来连接。

在每一个Extent中,保存了具体每一行的数据,这些数据也是通过双向链表来连接的。

参考:

http://www.cnblogs.com/magialmoon/archive/2013/04/11/3015394.html

http://my.oschina.net/zhzhenqin/blog/97268

http://blog.sina.com.cn/s/blog_4a7e719d010155s2.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值