`

【转】MongoDB Replica Sets + Sharding 方案 及 chunks块 和 片键分析

 
阅读更多
以下就是我们将要搭建的mongdb集群架构
创建第一个replset
---------------------------------------------------------------------------------------------------------------------------------------------------
创建目录
mkdir -p /data/replset_sharding/replset1/r0
mkdir -p /data/replset_sharding/replset1/r1
mkdir -p /data/replset_sharding/replset1/r2
mkdir -p /data/replset_sharding/replset1/log
 
 
改用下面的就行了(这是里为方便看日志,直接在命令行输出查看)
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset1/r0 --replSet  replset1 --port 18010 --directoryperdb --rest
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset1/r1 --replSet  replset1 --port 18011 --directoryperdb --rest
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset1/r2 --replSet  replset1 --port 18012 --directoryperdb --rest
 
 
初始化复本集:
 
/Apps/mongo/bin/mongo --port 18010
 
config_replset1 = {
_id:"replset1",
members:
[
{_id:0,host:"127.0.0.1:18010",priority:4},
{_id:1,host:"127.0.0.1:18011",priority:2},
{_id:2,host:"127.0.0.1:18012",arbiterOnly : true}
]
}
 
注意arbiter仲裁节点只投票,不接收复制的数据!
 
 
rs.initiate(config_replset1);
---------------------------------------------------------------------------------------------------------------------------------------------------
 
创建第二个replset
---------------------------------------------------------------------------------------------------------------------------------------------------
创建目录
mkdir -p /data/replset_sharding/replset2/r0
mkdir -p /data/replset_sharding/replset2/r1
mkdir -p /data/replset_sharding/replset2/r2
mkdir -p /data/replset_sharding/replset2/log
 
 
改用下面的就行了(这是里为方便看日志,直接在命令行输出查看)
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset2/r0 --replSet  replset2 --port 28010 --directoryperdb --rest
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset2/r1 --replSet  replset2 --port 28011 --directoryperdb --rest
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset2/r2 --replSet  replset2 --port 28012 --directoryperdb --rest
 
 
初始化复本集:
 
/Apps/mongo/bin/mongo --port 28010
 
config_replset2 = {
_id:"replset2",
members:
[
{_id:0,host:"127.0.0.1:28010",priority:4},
{_id:1,host:"127.0.0.1:28011",priority:2},
{_id:2,host:"127.0.0.1:28012",arbiterOnly : true}
]
}
 
注意arbiter仲裁节点只投票,不接收复制的数据!
 
 
rs.initiate(config_replset2);
---------------------------------------------------------------------------------------------------------------------------------------------------
创建第三个replset
---------------------------------------------------------------------------------------------------------------------------------------------------
创建目录
mkdir -p /data/replset_sharding/replset3/r0
mkdir -p /data/replset_sharding/replset3/r1
mkdir -p /data/replset_sharding/replset3/r2
mkdir -p /data/replset_sharding/replset3/log
 
 
改用下面的就行了(这是里为方便看日志,直接在命令行输出查看)
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset3/r0 --replSet  replset3 --port 38010 --directoryperdb --rest
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset3/r1 --replSet  replset3 --port 38011 --directoryperdb --rest
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/replset3/r2 --replSet  replset3 --port 38012 --directoryperdb --rest
 
 
初始化复本集:
 
/Apps/mongo/bin/mongo --port 38010
 
config_replset3 = {
_id:"replset3",
members:
[
{_id:0,host:"127.0.0.1:38010",priority:4},
{_id:1,host:"127.0.0.1:38011",priority:2},
{_id:2,host:"127.0.0.1:38012",arbiterOnly : true}
]
}
 
注意arbiter仲裁节点只投票,不接收复制的数据!
 
 
rs.initiate(config_replset3);
---------------------------------------------------------------------------------------------------------------------------------------------------
 
 
 
---------------------------------------------------------------------------------------------------------------------------------------------------
 
//创建数据库,日志文件
 
 
mkdir -p /data/replset_sharding/log
 
 
 
--------------------------------------------------------------------------------
1,启动Config Server, Config Server : 40000,40001,40002
 
mkdir -p /data/replset_sharding/config0
mkdir -p /data/replset_sharding/config1
mkdir -p /data/replset_sharding/config2
 
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/config0 --configsvr --port 40000 --directoryperdb --rest
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/config1 --configsvr --port 40001 --directoryperdb --rest
/Apps/mongo/bin/mongod --dbpath /data/replset_sharding/config2 --configsvr --port 40002 --directoryperdb --rest
 
正式运行要后台运行就用下面的:
 
/Apps/mongo/bin/mongod  --dbpath /data/replset_sharding/config --configsvr --port 40000  --logpath /data/replset_sharding/log/config.log --fork --directoryperdb --rest
 
------------------------------------------------------------------------------------------------------------------------------
以上的3个Config Server里存放集群分片的配置信息,如果Config Server出问题是无法正常启动集群的!
配置服务器使用的是两步提交机制(而不是普通MongoDB副本集的异步复制),因为两步提交是实时的一致性,
而异步复制是最终一致性!
 
两步提交机制确保3台机的配置是一致的,如果有某台配置服务器宕机了,那集群配置信息将是只读的! 
客户端还是能够读取集群的数据,还有能有限地更新集群的数据(只要不需要修改配置服务器的配置,如chunks块的修改,或片键的修改)
 
 
 
PS:整个集群的admin数据库是存放在Config Sever中的,而3台Config Server不止数据库config是同步的,而且数据库admin也是同步的
 
 
--------------------------------------------------------------------------------
 
 
2,启动Route Process,Route Process : 50000
 
/Apps/mongo/bin/mongos --port 50000 --configdb 127.0.0.1:40000,127.0.0.1:40001,127.0.0.1:40002 --chunkSize 1 
 
--chunkSize 1 (MB)指定分片的最小单位容量,这里设置1M,方便查看效果 
 
正式运行要后台运行就用下面的:
 
/Apps/mongo/bin/mongos --port 50000 --configdb 127.0.0.1:40000 --chunkSize 50 --logpath=/data/replset_sharding/log/route.log --fork
 
--------------------------------------------------------------------------------
 
3,连接到mongos配置Sharding
 
用Mongo Shell 登录 Route Process
 
/Apps/mongo/bin/mongo --port 50000 
 
use admin (记得执行这一点,切换到admin数据库)
 
//添加分片节点,每个分片都是一个副本集
db.runCommand({addshard:"replset1/127.0.0.1:18010,127.0.0.1:18011,127.0.0.1:18012",allowLocal:true})
db.runCommand({addshard:"replset2/127.0.0.1:28010,127.0.0.1:28011,127.0.0.1:28012",allowLocal:true})
db.runCommand({addshard:"replset3/127.0.0.1:38010,127.0.0.1:38011,127.0.0.1:38012",allowLocal:true})
 
(allowLocal:true仅仅开发时才将分片配置到本地,生产时不能这样)
-----------------------------------------------------------------------------------
如图:配置信息被添加到Config Server的config数据库的shards集合中:
 
 
你会发觉,arbiter仲裁节点因为不接收数据,所以直接被mongos在配置阶段就去掉,
db.runCommand({addshard:"replset1/127.0.0.1:18010,127.0.0.1:18011,127.0.0.1:18012",allowLocal:true})
等价于:db.runCommand({addshard:"replset1/127.0.0.1:18010,127.0.0.1:18011",allowLocal:true})

 

 
-----------------------------------------------------------------------------------
 
//A,配置数据库mydb,启用分片
 
use admin
 
db.runCommand({enablesharding:"mydb"})
 
此时数据库mydb是以分片replset3为基片(primary shard)
 
mydb被配置成启用分片后,配置信息是存放在配置服务器的数据库config的databases集合里!
 
 
 
 
//B,设置要分片的集合:使集合users以片键_id来分片
db.runCommand({shardcollection:"mydb.users",key:{_id:1}})
 
mydb的users集合被配置成启用分片后,配置信息是存放在配置服务器的数据库config的collections集合里!
--------------------------------------------------------------------------------
 
 
这里可以看到,路由服务器是不会存放配置信息(不用配置dbpath也是这个原因,但会缓存配置服务器上的配置!)
 
5,Sharding,递增片键方式插入数据
 
/Apps/mongo/bin/mongo --port 50000 
 
use mydb
 
测试插入60万条数据
for(var i=1; i<=600000; i++) db.users.insert({age:i,name:"jack",addr:"guangzhou",country:"China"})
 
use admin
执行:
db.runCommand({enablesharding:"mydb"})使数据库启用分片
 
db.runCommand({ shardcollection:"mydb.users",key:{_id:1} }) 使集合users以_id为Sharding Key分片
 
然后等几分钟,集合users的数据就均匀分布到各个分片,分片完成
 
 
1,先看看每个trunk,这里测试需要,设置了1MB/trunk,如图
 
每个trunk记录了片键的范围,还有所在的片
 
--------------------------------------------------------------------------
因为Sharding key 是ObjectId
这里ObjectId就像一个递增片键,插入时不能均匀地路由到各片,此时写入的负载很不均匀,集中在一台机器上!
 
 
 
如图:Balancer正在移动分片的块chunk
 
在递增片键的情况下,数据刚插入完后,数据的分片不均匀,所以数据插入完后,mongos就会用Balancer进行数据的负载均衡!
如: Balancer正在执行负载均衡,此时要用到锁,MongoDB 2.2.0 引入了DB级别的锁,不知道分片时是不是也是DB级别的锁呢?
这会锁定分片的数据库mydb
 
图: mongos的Balancer正在执行负载均衡
 
 
图: mongos的Balancer正在执行负载均衡
 
 
图: mongos的Balancer正在执行负载均衡
 
 
图: mongos的Balancer正在执行负载均衡
 
-----------------------------------------------------------------------------
过了10+分钟的状态,此时应该分片"均匀"了..
 
细心发觉,怎么"均匀"呢??每个片的chunks是均匀了,每个片的chunks都是33个,
因为片replset2是数据库mydb的primary片(上图),又因为此时是递增片,开始时60万条记录全部都
插入到这个片中,又因为我们给mongos设置的--chunkSize是1Mb,所以给replset2片均衡数据时,
使其每个trunk的size均衡到接近1M就可以了(实际是1.1),
 
 
6,Sharding,随机片键方式插入数据
 
/Apps/mongo/bin/mongo --port 50000 
 
use admin
执行:
db.runCommand({enablesharding:"mydb"})使数据库启用分片
 
 
 
db.runCommand({ shardcollection:"mydb.user2",key:{shardkey:1} }) 使集合user2以shardkey为Sharding Key分片
 
 
空集合user2以shardkey为Sharding Key分片后,就会在配置服务器分配一个(-∞,+∞)的chunks块给数据库mydb的基片replset3,
基片很重要,对于一个不分片的集合是存放在基片中的,而对于分片的集合,每一个无限大的chunks块也是分配给基片的!
 
 
 
use mydb
 
测试插入60万条数据,这里生成的shardkey
for(var i=1; i<=600000; i++) db.user2.insert({name:"a long name",age:i,addr:"a long address guangzhou",country:"China", shardkey: Math.random()})
 
 
 
 
 
 
因为刚开始里,配置服务器里没有chunks块,第一个无限大的块位于基片上,而后来边向数据库插入数据边分裂出更细的chunks块,
这时分裂出的块主要分布在基片shard000上所以导致插入操作集中在基片上执行!
 
 
现在把集合user2里的数据全部remove掉!那集合就是剩下chunks块的信息(在配置服务器里)
 
图:集合user2清空后,各片的chunks块数量也不均匀
 
图:没数据,也会对各片进行chunks块数量调整,直至数量平均!
 
 
(再次说明:
mongos路由负载均衡的本质是:
          在后台对各片进行负载均衡,直至各片的chunks块数量相等!
)
 
向已有69个chunks块(块分布均匀)的空集合插入30万个随机键的文档
for(var i=1; i<=300000; i++) db.user2.insert({name:"a long name",age:i,addr:"a long address guangzhou",country:"China", shardkey: Math.random()})
 
 
 
 
 
 
 
 
 
 
 
 
 
可见,向已有69个chunks块(块分布均匀)的空集合插入30万个随机键的文档
整个插入过程是相当均匀!而块的数量仅仅增加了6块,就是说30万个文档几乎全部"命中"已存在的各个块!
 
-------------------------------------------------------------------------------------------
 
8,测试6和7的小结
 
1:如果刚开始对于新的集合,配置服务器里没有该集合的chunks块信息,这里无论是递增键或随机键,
  数据的插入过程也不会均匀,甚至有可能集中在某台机器上,然后mongos再来执行负载均衡
 
2: mongos路由会在后台对各片进行负载均衡,直至各片的chunks块数量相等!
 
3: 对于负载均衡的Sharding Cluster(各片的chunks块数量相等),对于随机键的操作会非常有效,基本整个过程是很均匀的
    而此时递增键的操作还是会出现严重的负载不均衡的情况!
 
 
 
--------------------------------------------------------------------------------
 
5,对现有的表执行Sharding
 
/Apps/mongo/bin/mongo --port 50000 
 
use mydb
 
测试插入60万条数据
for(var i=1; i<=600000; i++) db.users.insert({age:i,name:"irelandken",addr:"guangzhou",country:"China"})
 
 
 
然后等几分钟,集合users的数据就均匀分布到各个分片,分片完成
 
 
 
 
--------------------------------------------------------------------------------
 
6,移除Shard Server,回收数据
 
 
db.runCommand({"removeshard" : "127.0.0.1:38010"})
 
 
因为127.0.0.1:38010是数据库test和mydb的Primary片"primary" : "shard0000"基片,所以要手动移动数据库的基片
 
如:
 
/* 1 */
{
  "_id" : "test",
  "partitioned" : true,
  "primary" : "shard0000"
}
 
/* 2 */
{
  "_id" : "mydb",
  "partitioned" : true,
  "primary" : "shard0000"
}
 
手动修改数据库test的基片,改为127.0.0.1:38011
执行: 
mongos> db.runCommand({"moveprimary" : "test","to" : "127.0.0.1:38011"})
{ "primary " : "shard0001:127.0.0.1:38011", "ok" : 1 }
 
手动修改数据库test的基片,改为127.0.0.1:38011
执行: 
mongos> db.runCommand({"moveprimary" : "mydb","to" : "127.0.0.1:38011"})
{ "primary " : "shard0001:127.0.0.1:38011", "ok" : 1 }
 
 
依赖要删除的片的关系全部删除后,再找执行一次:
db.runCommand({"removeshard" : "127.0.0.1:38010"})
 
 
 
mongos> db.runCommand({"removeshard" : "127.0.0.1:38010"})
{
        "msg" : "removeshard completed successfully",
        "state" : "completed",
        "shard" : "shard0000",
        "ok" : 1
}
 
mongos分回收该片的数据,平均到其它片,然后在分片集群中移除该片!
 
多次调用这一句,中间可以看到进行的进度!此操作对用户完全透明,不需要停机操作!
 
--------------------------------------------------------------------------------
 
7,新增Shard Server
 
连接到mongos
 
因为在各分片里存在数据库test和mydb的集合的分片,而规定加入的新mongod不能含有相同的数据库
(试想如果加入的数据库含有数据库mydb,且其中含有一定数量的数据,此数据一定要被删除)
向mongos新加入的Shard Server一定不能含有与其它片相同的数据库的!
 
use admin
 
db.runCommand({addshard:"127.0.0.1:38010",allowLocal:true})
 
 
新的片被加入后,mongos再次将次执行负载均衡,将数据均匀到各片中!
 
 
--------------------------------------------------------------------------------
 
从各部分的LOG来看,只有节点Shard Server和路由Route Process是比较"忙"的,Config Server好像仅仅只是同步Route Process的配置而已,
因为路由Route Process不会持久化数据,Config Server为它存放配置
感觉路由Route Process是一个Facade,外部看来是一个数据库
 
 
转自 http://blog.csdn.net/irelandken/article/details/8003195
分享到:
评论

相关推荐

    2012 最新的mongodb sharding配置步骤 权威指南 分片步骤

    在处理海量数据时,为了提高性能和可扩展性,MongoDB 提供了分片(Sharding)功能,即将数据分散到多个物理节点上,实现水平扩展。本文将详细介绍2012年最新的MongoDB分片配置步骤,适用于权威的MongoDB环境搭建。 ...

    mongoDB sharding复制模式搭建官网文档

    - **分片(Shards)**:每个分片都包含数据的一个子集,分片可以是单一的MongoDB实例也可以是一组副本集(Replica Set),后者提供了更高的可用性和数据冗余。 - **配置服务器(Config Servers)**:配置服务器用于...

    mongodb分片设计

    MongoDB分片设计是针对大数据量的存储和处理提出的解决方案。在大数据环境下,单个数据库服务器往往难以满足高性能和高可用性的需求。MongoDB通过分片(Sharding)技术来解决这个问题。分片是一种将数据分散存储在多...

    mongodb分片与副本集详细配置方案

    MongoDB 是一个高性能、分布式、开源的文档型数据库,它支持分片(sharding)和副本集(replica sets)来实现水平扩展和高可用性。分片是将数据分散到多个物理节点上,以处理大数据量和高并发场景;副本集则是为了...

    centos7+mongodb 3.4 集群搭建:分片+副本集

    在本文档中,我们将详细介绍如何在CentOS 7.0系统上搭建基于MongoDB 3.4.3版本的集群环境,包括分片(sharding)和副本集(replica sets)的配置。本文档将介绍相关概念、环境准备、机器规划及端口分配、集群搭建的...

    深入剖析 MongoDB 架构

    MongoDB 采用的是主从复制(Replica Sets)和分片(Sharding)两种方式来实现高可用性和水平扩展。主从复制主要用于数据冗余和故障恢复,而分片则用于在多台服务器之间分配数据,以处理大规模的数据存储和查询需求。...

    MongoDb 副本集和分片.doc

    在大型分布式环境中,为了确保数据的高可用性和水平扩展能力,MongoDB 提供了副本集(Replica Set)和分片(Sharding)两种主要的部署策略。 副本集是 MongoDB 中用于实现数据冗余和故障恢复的核心机制。在一个副本...

    MongoDB架构图分享.pdf

    当数据量增长到一定程度时,分片机制可以自动将数据切分成更小的块(chunks),并将这些块移动到负载较轻的分片上,从而保证系统性能和数据均衡。 在服务器角色方面,MongoDB定义了几种节点角色以支持分片。客户端...

    Mongodb 集群分片部署.pdf

    MongoDB 的分片机制允许数据自动分割成多个块(chunks),并将这些块分布在不同的节点上,以平衡负载并提高性能。 在MongoDB集群中,主要有三个关键组件: 1. **Shard Server**:这是MongoDB集群的基础,由一个或...

    mongodb集群搭建

    1. **Replica Sets(副本集)**:用于提供容错能力和数据冗余。在一个副本集中,通常有一个主节点和多个从节点。主节点处理写入请求,而从节点通过复制主节点的数据来保持最新状态。 2. **Sharding(分片)**:用于...

    CentOS 7下MongoDB 3.4 集群搭建之分片

    本文将详细介绍如何在CentOS 7操作系统下,搭建一个MongoDB 3.4版本的集群,且包括分片(sharding)与副本集(replica set)两大特性。搭建这样的集群,旨在创建一个高性能、高可用且能够水平扩展的数据库架构。 在...

    mongo集群脚本参考.zip

    在大型应用中,为了确保高可用性、可扩展性和性能,MongoDB 提供了两种核心技术:副本集和分片。 **副本集(Replica Sets)** 副本集是 MongoDB 的一种高可用性解决方案,它通过复制数据到多个节点来确保数据的冗余...

    MongoDB

    3. **分片(Sharding)**:MongoDB支持水平扩展,通过将数据分散到多个节点上实现分片,以处理大量数据和高并发访问。 4. **复制集(Replica Sets)**:为保证高可用性,MongoDB使用复制集技术,将数据复制到多个...

    MongoDB分片的概念.pdf

    在MongoDB中,分片(Sharding)是将数据集划分为更小的部分,称为“chunks”,并把这些chunks分布在多个服务器上,这些服务器称为shard servers。这种分布式架构使得数据库能够存储更多数据,并且能够处理更高的读写...

    MongoDB Genenral Introduction

    2. **分布式架构**:MongoDB支持分片(sharding)和复制集(replica sets),可以轻松地在多台机器上分散数据,实现水平扩展,以应对高并发和大量数据存储的需求。 3. **弹性查询**:MongoDB提供了强大的查询语言,...

    NoSQL数据库-MongoDB和Redis归类.pdf

    3. 分片(Sharding):用于水平扩展,将数据分散在多台服务器上,以提高存储和处理能力。 4. 复制集(Replica Set):为了提供高可用性和数据冗余,MongoDB支持数据复制,形成一组镜像服务器。 【MongoDB资源消耗】...

    详解MongoDB4.0构建分布式分片群集

    在MongoDB 4.0版本中,引入了分片(Sharding)技术来构建分布式分片群集,以应对高数据量和吞吐量的挑战。分片允许我们将数据分散到多个服务器上,以提高存储能力和处理能力,确保系统的稳定性和性能。 分片简述: ...

    ubuntu 18.04安装mongo4.x切片副本集服务器

    MongoDB 分片(Sharding)是一种水平扩展技术,它将数据分散到多个服务器上,以增加存储容量和处理能力。这尤其适用于那些单台服务器难以容纳或处理的数据量巨大的场景。分片通过将数据分成小块(chunks),并将其...

    mong分片配置.zip

    在处理大量数据时,为了提高读写性能和扩展性,MongoDB 提供了分片(Sharding)功能,将数据分散到多个服务器上,实现水平扩展。本压缩包 "mong分片配置.zip" 内包含的是配置文件,可能用于搭建 MongoDB 分片集群。 ...

    PerconaLive - Sharded Cluster Tutorial.pdf

    《PerconaLive - Sharded Cluster Tutorial.pdf》是一份全面介绍MongoDB分片集群架构的教程文档,适合数据库管理员、数据库开发人员以及对NoSQL分片原理感兴趣的读者。文档涵盖了分片集群的基础知识、高级功能以及...

Global site tag (gtag.js) - Google Analytics