当前位置: 代码迷 >> 综合 >> MongoDB分片 sharding
  详细解决方案

MongoDB分片 sharding

热度:42   发布时间:2023-09-20 09:55:06.0

分片(sharding)是指将数据拆分,将其分散存在不同的机器上的过程。有时也用分区(partitioning)来表示这个概念。将数据分散到不同的机器上,不需要功能强大的大型计算机就可以储存更多的数据,处理更多的负载。

MongoDB分片的基本思想就是将集合切分成小块。这些块分散到若干片里面,每个片只负责总数据的一部分。应用程序不必知道哪片对应哪些数据,甚至不需要知道数据已经被拆分了,所以在分片之前要运行一个路由进程,该进程名为mongos。这个路由器知道所有数据的存放位置,所以应用可以连接它来正常发送请求。对应用来说,它仅知道连接了一个普通的mongod。路由器知道数据和片的对应关系,能够转发请求道正确的片上。如果请求有了回应,路由器将其收集起来回送给应用。

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

用个例子来说明这个过程:假设有个文档集合表示的是人员。如果选择名字("name")作为片键,第一片可能会存放名字以A~F开头的文档,第二片存的G~P的名字,第三片存的Q~Z的名字。随着添加或者删除片,MongoDB会重新平衡数据,使每片的流量都比较均衡,数据量也在合理范围内。

mongos就是一个路由服务器,它会根据管理员设置的片键将数据分摊到自己管理的mongod集群,数据和片的对应关系以及相应的配置信息保存在config服务器上。

MongoDB分片 sharding

MongoDB分片 sharding

mongod:一个普通的数据库实例,如果不分片的话,我们会直接连上mongod

1、创建三个目录,分别存放两个mongod服务的数据文件和config服务的数据文件

[wj@localhost data]$ sudo mkdir 20 21 22

启动两台实例服务器:

[wj@localhost data]$ sudo ./mongod --port 27020 --dbpath /usr/local/mongodb/data/20 --smallfiles --fork --logpath /usr/local/mongodb/logs/mongo20.log

[wj@localhost bin]$ sudo ./mongod --port 27021 --dbpath /usr/local/mongodb/data/21 --smallfiles --fork --logpath /usr/local/mongodb/logs/mongo21.log

准备configsvr

[wj@localhost bin]$ sudo ./mongod --port 27022 --dbpath /usr/local/mongodb/data/22 --configsvr --fork --logpath /usr/local/mongodb/logs/mongo22.log

准备mongos路由 configdb后面是configsvr的ip及端口

[wj@localhost bin]$ sudo ./mongos --port 30000 --configdb 192.168.125.128:27022 --fork --logpath /usr/local/mongodb/logs/mongo30.log

连接mongos路由

[wj@localhost bin]$ ./mongo --port 30000

添加分片shard

mongos> sh.addShard("192.168.125.128:27020");
{ "shardAdded" : "shard0000", "ok" : 1 }
mongos> sh.addShard("192.168.125.128:27021");
{ "shardAdded" : "shard0001", "ok" : 1 }

查看分片状态

mongos> sh.status()

选择库分片

mongos> sh.enableSharding("shop");

指定分片的库的collection的片键

mongos> sh.shardCollection('shop.goods',{goods_id:1});

mongos> use shop

添加测试数据

mongos> for(var i=1;i<=30000;i++){db.goods.insert({goods_id:i,goods_name:'hello world afdjfdkfdjjfajdlfdsfdf'})}

mongos> db.goods.find().count();

mongos> use config

mongos> db.settings.find();

设置chuckSize大小为1M

mongos> db.settings.save({_id:'chunksize',value:1})

mongodb不是从单篇文档的级别,绝对平均的散落在各个片上,

而是N篇文档,形成一个块"chunk",

优先放在某个片上,

当这片上的chunk,比另一个片的chunk,区别比较大时, (>=3) ,会把本片上的chunk,移到另一个片上, 以chunk为单位,

维护片之间的数据均衡

问: 为什么插入了10万条数据,才2个chunk?

答: 说明chunk比较大(默认是64M)

在config数据库中,修改chunksize的值.

问: 既然优先往某个片上插入,当chunk失衡时,再移动chunk,

自然,随着数据的增多,shard的实例之间,有chunk来回移动的现象,这将带来什么问题?

答: 服务器之间IO的增加,

接上问: 能否我定义一个规则, 某N条数据形成1个块,预告分配M个chunk,

M个chunk预告分配在不同片上.

以后的数据直接入各自预分配好的chunk,不再来回移动?

答: 能, 手动预先分片!

以shop.user表为例

1: sh.shardCollection(‘shop.user’,{userid:1}); //user表用userid做shard key

2: for(var i=1;i<=40;i++) { sh.splitAt('shop.user',{userid:i*1000}) } // 预先在1K 2K...40K这样的界限切好chunk(虽然chunk是空的), 这些chunk将会均匀移动到各片上.

3: 通过mongos添加user数据. 数据会添加到预先分配好的chunk上, chunk就不会来回移动了.

添加片后都需要手动分下片吗?configsvr和mongos单点安全可靠吗?replicaSet和sharding时主挂掉后会自动切换吗?

  相关解决方案