一、集群的理论知识

1.1 集群成员

MongoDB的集群类似于GreenPlum集群,由一个入口节点负责任务分发与结果统计,分片结节负责执行任务。不同GP,多了一个config servers。

集群有三个组件:
A。shards:分片,即数据结点,存储数据和执行计算。为了保证高可用和数据一致性,生产环境中shards应该做成
        replicasets(防止丢失数据)。集群中有一个primary shards,执行非分片的任务。
B。mongos(query routers):查询路由,负责client的连接,并把任务分给shards,然后收集结果。一个集群中可以有多个query
         routers(replica sets),以分担客户端请求(负载均衡)。
C。config server:配置服务器。保存了集群的元数据(比如数据放在哪个shards上),query router通过config server中的配置信 
      息决定把任务分配到哪个shards上。从3.2开始,config servers可以做成replica sets。
 
集群架构图:

1.2 数据的分片

MongoDB在集合层面做数据分片,以shard key来分片。
shard key应该是一个索引字段或者复合索引字段。
MongoDB根据shard key创建chunks,然后把chunks均衡的分布在shards上。
两种分区方式:range和hash.结果全oracle里range分区和hash分区理解一下。
 

1.3 分片的性能

range分片:适合range query,能够使用批量I/O。但是如果分区键不是均匀分布的的,则可能只用到集群中的少数据结点,不能发挥集群的性能。
hash分片:数据平均分布到各个节点上。但是范围查询时需要各个节点一起读,效率比range分片低。
MongoDB支持数据标签,用户可以指定某个标签的数据分布到特定节点上。

1.4数据的平衡

1.4.1 分裂(splite)

    当一个chunk的大小超过chunk的最大值大时,这个chunk会分裂为两个。该过程只修改元数据,不迁移数据。该过程是后台进程完成,不需要人工执行。chunk默认值64M。
     分裂的特点:
    1)默认的chunk是64M。小的chunk好处是数据平衡性,坏处是经常要做数据平衡。大的chunk则正好相反
    2)只有在insert或者update时才会发生chunk的分裂。如果人为修改chunk的大小,是不会发生分裂的。
    3)某个特定的shard key values的chunk可能大小默认的chunk大小,并且无法分裂
 

1.4.2 平衡(balance)

    如果集群中的某个节点保存的数据太多,就会自动的把数据分配给其它节点。该过程是后台进程完成,不需要人工执行。
在平衡数据时,先从原始节点复制数据到新节点,然后更新复制的数据。只有在平衡完成后,才会删除原始节点上的数据。如果发生了错误,则不影响原始节点数据。
    增加和删除节点都会造成数据的平衡。
    注意:并非所有的数据不均匀都会自动平衡,一般来说,一个节点可以至少存储数百个chunk(其它节点可以一个chunk都没有)而不触发平衡操作。    所以小数据量没有必要使用集群。
    数据平衡的特点:

1)自动化的,默认是开启的
    2)每次只移动一个chunk,但可能在源上的chunk没有删除前就开始新的移动
    3)只有在节点的chunk数量差距非常大的时候才触发。
        触发的阀值:

4)一直迁移到任何两个节点上的chunk数量相差小于2为止。
    5)如果设置了shard可以使用的磁盘最大小值 ,如果节点的磁盘使用超过了这个值,将不会balance到这个节点上。
    6)平衡完毕后,会修改confige server的信息

    7)_secondaryThrottle默认为true,当定入至少一个secondary。

1.5 config server

1.5.1 config serve配置成replicatsion sets的限制

     config servers配置成replicate sets有以下限制:

1)没有仲裁节点
        2)没有延迟节点

        3)build indexes必须为true

1.5.2 config server的读写

    写:只有集群的元数据发生变化时,才会更新config server的信息。比如加入、删除节点、分裂chunk。使用write majority方式写。
    读:当mongos程序重启或集群的元数据发生了变化mongos才会读取元数据。使用read majority方式读。

1.6 系统架构

1.6.1 用于生产的架构

    用于生产的架构必须要保证数据的冗余,mongos、shards、config server必须要做成replication sets。每个集群都必须有一个独立的config server(一台config server不能多用)。生产的架构示意:
    说明:
        不做replications set的话,shard节点是没有数据冗余的功能,如果数据丢失了,就找不回来(此时其它节点可以正常工作)。因此对于生产环境,做复制是十分必要的。同样,confige server也是一样,也要做复制。
 

1.6.2. 用于测试的架构

    测试的架构可以不做replication sets,以节省机器为目的,可以把mongos和config server和shards放一起。测试架构示意:

1.7 分片键shards key

    分片键用于决定数据分布在哪个节点上。分片键中的列必须是index key或者组合index key,分片键也可以组合的(比如key(c1,c2))。分片键在数据插入后不能改变。

1.7.1 hash 分片

    hash key能够很好的将数据均匀的分布在不同的节点上。选择做为hash key的键应该有很大的基数,一般将object_id或者timestamp列作为hash 键。
    对于空集合,hash 分片会自动的在每个节点上创建两个chunk,通过修改shardCollection的numInitialChunks参数来决定空集合的chunk个数。
 

1.7.2 分片键对性能的影响

     不同的分片键到性能有不同的影响。
     1)使用object_id这样唯一性或者基数很大的键做为分布键,则所有数据被离散的分布到各个节点上,这样能显著的提高集群的写性能,适合存储大量数据的场合。
     2)查询集群中的数据时,最快的方式是查询中包含了分片键,这样就能直接定位的到数据所在的节点,否则就要在所有节点上执行全表扫描。对于读操作,考虑以下两点:
 A.确定最常用被查询的列
 B.考虑这些列哪个对于性能影响最大
如果最后选定的这个列基数比较小,那么在分片皱中加入二级键,做一二级键组成的集合基数小即可(对比oracle中的组合索引)。
 

1.8 集群的高可用

1.8.1 shards节点

    如果shars节点没有做replication sets,该节点如果宕机,这部分数据就不可访问。因此为了业务的持续性,对于shards节点有必要做成replication sets.

1.8.2 config server

   1) 和shards一样,如果没有做replication set此时又宕机的话,整个集群都不能用。如果做了replications sets,当其中的一台机宕机后,会自动选出主节点,整个集群还可以用。如果宕机的过多无法选出主节点,整个集群依然可以用(读写),但是不能有chunk操作(chunk的创建、移动)。
   2)如果不用replication set用mirror的方式来做配置config server,在confige server宕机后,则需要重启所有的集群成员来连接镜像confige server。解决重启的办法是配置DNS

1.8.3 mongos

    mongos是应用程序的入口,如果mongos宕机了,应用程序就无法使用集群。因此一般也做也replication Set。mongos使用的资源相对于shards和confige server是最小的,因此可以和应用服务器放一台机上。当mongos宕机修复后,会自动从config server读取数据.
 

1.9 集群的查询

1.9.1 查询路径

    mongos是应用程序的接口。mongos通过config server中的信息查询数据在哪个节点从而分配任务。如果结果有中sort(),primary shard会合并shards的数据然后排序返回给mongos再返回给client.limit()操作直接在shards上完成。skip()不会发送给shards来执行。

1.9.2 mongos标识

    应用程序连接到集群后,执行isMaster()命令,返回:
{
"ismaster" : true,
"msg" : "isdbgrid",
"maxBsonObjectSize" : 16777216,
"ok" : 1
}
则表示是mongos。如果msg不是 isdbgrid则不是mongos。
 

二、集群的搭建

2.1集群搭建的步骤

 

2.1.1 配置confige server

    以下代码是搭建一个三个结点的replication sets的config server:
1).创建replications sets
mongod --configsvr --replSet configReplSet --port <port> --dbpath <path>
或者使用配置文件
sharding:
clusterRole: configsvr
replication:
replSetName: configReplSet
net:
port: <port>
storage:
dbpath: <path>
2).初始化。进入其中一个的mongo shell:
rs.initiate( {
_id: "configReplSet",
configsvr: true,
members: [
{ _id: 0, host: "<host1>:<port1>" },
{ _id: 1, host: "<host2>:<port2>" },
{ _id: 2, host: "<host3>:<port3>" }
]
} )

2.1.2 创建mongos实例(路由实例)

mongos --configdb configReplSet/<cfgsvr1:port1>,<cfgsvr2:port2>,<cfgsvr3:port3>

2.1.3 加入 shards

1)连接mongos实例:
mongo --host <hostname of machine running mongos> --port <port mongos listens on>
2)在其中一台mongos上加入节点:
sh.addShard( "rs1/mongodb0.example.net:27017" )     (replications sets只需要加入rs中一个节点即可)
sh.addShard( "mongodb0.example.net:27017" )           (单机)
可能需要一段时间来迁移数据

2.1.4 设置分片

2.1.4.1 设置数据库分片
在设置集合分片之前,必须设置要分片的数据库。连接mongos:
mongo --host <hostname of machine running mongos> --port <port mongos listens on>
执行:
sh.enableSharding("<database>")或者db.runCommand( { enableSharding: <database> } )
2.1.4.2 设置集合分片
1)确定集合的shard key。如果集合已经有数据,那么在shard key上创建index。如果没有数据,集群会自动为shard key创建索引
2)将集合加入分片
sh.shardCollection("<database>.<collection>", shard-key-pattern)
如:
sh.shardCollection("records.people", { "zipcode": 1, "name": 1 } )  shard key 为zipcode,如果有相同的zipcode再根据name来分
sh.shardCollection("people.addresses", { "state": 1, "_id": 1 } )      同上
sh.shardCollection("assets.chairs", { "type": 1, "_id": 1 } )               同上
sh.shardCollection("events.alerts", { "_id": "hashed" } )                  hash分片

2.1.5 配置镜像config server

注意:不推荐使用镜像,请使用replication sets。
在每个config server上启动mongod实例:
mongod --configsvr --dbpath /data/configdb --port 27019
每个路由节点启动mongs,--configdb后面的连接字符串要一致
mongos --configdb cfg0.example.net:27019,cfg1.example.net:27019,cfg2.example.net:27019

2.2 实验

2.2.1实验环境

node1 192.168.75.10 config server1(configRS 37017)       mongos1( 27017)     shard1(47017)
node2 192.168.75.11 config server2(configRS 37017)       mongos2(27017)     shard2(47017)
node3 192.168.75.12 config server3(configRS 37017)                                        shard3( 47017)
在三台主机上,分别安mongoConfig、 mongoShard 、mongoRouter三个实例

2.2.2.配置config server

1)配置文件
在三台主机配置configution文件:
[root@node1 mongoConfig]# cat mongodb.config
dbpath=/usr/local/mongoConfig/data
logpath=/usr/local/mongoConfig/log/mongo.log
port=37017
fork=true
#master=true
replSet=configRS
configsvr=true
2)在三台机器上启动config server实例
[root@node1 bin]# ./mongod -f /usr/local/mongoConfig/mongodb.conf
about to fork child process, waiting until server is ready for connections.
forked process: 3032
child process started successfully, parent exiting
注意,打开防火墙的37017端口
3)初始化config server
连接到其中一台configer server:
[root@node1 bin]# ./mongo --port 37017
执行以下初始化:
> rs.initiate( {
... _id: "configRS",
... configsvr: true,
... members: [
... { _id: 0, host: "192.168.75.10:37017" },
... { _id: 1, host: "192.168.75.11:37017" },
... { _id: 2, host: "192.168.75.12:37017" }
... ]
... } );
{ "ok" : 1 }

2.2.3.配置mongos

在每台机器上执行:
./mongos --configdb configRS/192.168.75.10:37017,192.168.75.11:37017,192.168.75.12:37017 --port 27017 --fork --logpath=/usr/local/mongoRouter/log/mongo.log

2.2.4.启动三个shard实例

在三台机器修改配置文件:
[root@node1 mongoShard]# vi mongodb.config
dbpath=/usr/local/mongoShard/data
logpath=/usr/local/mongoShard/log/mongo.log
port=47017
fork=true
在三台机器上启动实例:
[root@node1 bin]# ./mongod -f /usr/local/mongoShard/mongodb.config
about to fork child process, waiting until server is ready for connections.
forked process: 17508
child process started successfully, parent exiting

2.2.5.将shards加入集群

在一台机器上连接mongos实例
./mongo --port 27017
执行:
sh.addShard( "192.168.75.10:47017" )
sh.addShard( "192.168.75.11:47017" )
sh.addShard( "192.168.75.12:47017" )

2.2.6.将数据库加入分片

sh.enableSharding("testShards")

2.2.7.将集合加入分片

sh.shardCollection("testShards.test", { "_id": "hashed" });

2.2.8.插入数据

在某个mongos上执行:
mongos> use testShards
switched to db testShards
mongos> show collections;
test
mongos> db.test.insert({"name":"testshrads","msg":"ok"});
WriteResult({ "nInserted" : 1 })
mongos> db.test.insert({"name":"testshrads2","msg":"ok"});
WriteResult({ "nInserted" : 1 })
mongos> db.test.insert({"name":"testshrads3","msg":"ok"});
WriteResult({ "nInserted" : 1 })
mongos> db.test.insert({"name":"testshrads4","msg":"ok"});
WriteResult({ "nInserted" : 1 })
mongos> db.test.insert({"name":"testshrads5","msg":"ok"});
WriteResult({ "nInserted" : 1 })
mongos> db.test.insert({"name":"testshrads6","msg":"ok"});
WriteResult({ "nInserted" : 1 })
mongos> db.test.insert({"name":"testshrads7","msg":"ok"});
WriteResult({ "nInserted" : 1 })
mongos> db.test.insert({"name":"testshrads8","msg":"ok"});
WriteResult({ "nInserted" : 1 })
mongos> db.test.insert({"name":"testshrads9","msg":"ok"});
WriteResult({ "nInserted" : 1 })
 
查看数据:
mongos> db.test.find();
{ "_id" : ObjectId("56815a0617de6d7dfc1051b5"), "name" : "testshrads", "msg" : "ok" }
{ "_id" : ObjectId("56815a0e17de6d7dfc1051b6"), "name" : "testshrads2", "msg" : "ok" }
{ "_id" : ObjectId("56815a1717de6d7dfc1051b8"), "name" : "testshrads4", "msg" : "ok" }
{ "_id" : ObjectId("56815a1b17de6d7dfc1051b9"), "name" : "testshrads5", "msg" : "ok" }
{ "_id" : ObjectId("56815a1e17de6d7dfc1051ba"), "name" : "testshrads6", "msg" : "ok" }
{ "_id" : ObjectId("56815a2617de6d7dfc1051bc"), "name" : "testshrads8", "msg" : "ok" }
{ "_id" : ObjectId("56815a1217de6d7dfc1051b7"), "name" : "testshrads3", "msg" : "ok" }
{ "_id" : ObjectId("56815a2117de6d7dfc1051bb"), "name" : "testshrads7", "msg" : "ok" }
{ "_id" : ObjectId("56815a2917de6d7dfc1051bd"), "name" : "testshrads9", "msg" : "ok" }
 

2.2.9.测试数据

连接到某个shards上:
#./mongod --port 47017
执行:
> use testShards
switched to db testShards
> db.test.find();
{ "_id" : ObjectId("56815a1217de6d7dfc1051b7"), "name" : "testshrads3", "msg" : "ok" }
{ "_id" : ObjectId("56815a2117de6d7dfc1051bb"), "name" : "testshrads7", "msg" : "ok" }
{ "_id" : ObjectId("56815a2917de6d7dfc1051bd"), "name" : "testshrads9", "msg" : "ok" }
发现数据分片正常.
mongoDB集群搭建完毕。
 
 
 
 
 

MongoDB3.2 集群搭建的更多相关文章

  1. mongodb3.6集群搭建:分片+副本集

    mongodb是最常用的noSql数据库,在数据库排名中已经上升到了前五.这篇文章介绍如何搭建高可用的mongodb(分片+副本)集群. 在搭建集群之前,需要首先了解几个概念:路由,分片.副本集.配置 ...

  2. mongodb3.6集群搭建:分片集群认证

    上篇集群已经创建,现在加入认证. 1. 生成密钥文件每个服务器上创建路径: mkdir -p /var/lib/mongo/auth 生成64字节的密钥文件openssl rand -base64 6 ...

  3. MongoDB-3.4集群搭建:分片

    概念 集群拥有三个节点: 分片(sharding),分发路由(query routers)和配置服务器 (config server) Shard 分片是存储了一个集合部分数据的MongoDB实例,每 ...

  4. mongoDB3.4的sharding集群搭建及JavaAPI的简易使用

    第一部分 在搭建mongoDB之前,我们要考虑几个小问题: 1.我们搭建集群的目的是什么?是多备份提高容错和系统可用性还是横向拓展存储大规模数据还是两者兼有? 如果是为了多备份那么选择replicat ...

  5. mongodb3集群搭建

    三台服务器:先设置hosts 10.0.0.231 node1 10.0.0.232 node2 10.0.0.233 node3 1:下载 mongodb-linux-x86_64-rhel70-3 ...

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

    mongodb是最常用的nodql数据库,在数据库排名中已经上升到了前六.这篇文章介绍如何搭建高可用的mongodb(分片+副本)集群. 在搭建集群之前,需要首先了解几个概念:路由,分片.副本集.配置 ...

  7. mongodb 3.6 集群搭建:分片+副本集

    mongodb是最常用的nosql数据库,在数据库排名中已经上升到了前六.这篇文章介绍如何搭建高可用的mongodb(分片+副本)集群. 在搭建集群之前,需要首先了解几个概念:路由,分片.副本集.配置 ...

  8. mongodb之 3.4.0 mongodb sharing 副本集群搭建

    系统系统 centos6.5三台服务器:10.100.25.42/43/44安装包: mongodb-linux-x86_64-rhel62-3.4.0.tgz 服务器规划:mongos mongos ...

  9. MongoDB分布式集群搭建

    最近在做一个关于车险的项目,由于数据量较大,实验室的Boss决定采用HBase+ES/MongoDB这两种方案,并做性能对比,本人负责MongoDB方案.为了满足海量数据的存储要求,需要搭建一个分布式 ...

随机推荐

  1. forEach for...in for...of

    forEach orEach 方法为数组中含有有效值的每一项执行一次 callback 函数,那些已删除(使用 delete 方法等情况)或者从未赋值的项将被跳过(不包括那些值为 undefined ...

  2. TCP/IP协议族之链路层(二)

    TCP/IP学习记录,如有错误请指正,谢谢!!! TCP/IP协议族之链路层(二) 链路层是最底层协议,主要有三个目的: 1. 为IP模块发送和接收IP数据报 2. 为ARP模块发送ARP请求和接收A ...

  3. Zabbix——自动发现

    前提条件: Zabbix版本为4.0 固定网段寻找网络设备,并添加组.添加模板.添加proxy. 设置完毕,等待~~ 如果没有问题,将会直接出现在host中.

  4. Jquery拼图

    Jquery代码 <script> $(function () { $("td").click(function () { var img = $(this).prop ...

  5. Windows 安装 MongoDB 并开启认证

    下载 可以自行上官网找需要的版本,Windows系统各个64位版本下载地址: http://dl.mongodb.org/dl/win32/x86_64 安装 正常的软件安装流程,这里就不细讲了. 配 ...

  6. restframework中的那些参数你知道吗?

    序列化是很重要的过程, 在构建数据结构的时候, 往往会出现很多意想不到的问题, 有一些参数你要用, 但是没有办法穿过来, 怎么办> 今天这篇博客就是写我之前的一个小项目中用restframewo ...

  7. redis整合Spring之序列化对象与反序列化

    写在最前面 1.Spring必须是4.2.6及以上版本才支持redis 2.jar包版本建议统一 需要准备jar包 1.aopalliance-1.0.jar 2.spring-data-common ...

  8. opencv3 学习三 - 图像输入输出显示等

    程序如下 #include "opencv2/opencv.hpp" using namespace cv; int main() { Mat file1 = imread(&qu ...

  9. Qt 本地化(翻译)

    Qt 本地化(翻译) 翻译流程大致是这样的:首先源代码产生 ts 文件,然后送给 Qt Linguist(Qt 语言家)这个 Qt 自带的小工具进行处理产生 qm 翻译文件,最后源代码里加载这个 qm ...

  10. telnet 批处理

    **** 需要确认多台服务器端口是否打开,如果一个一个telnet会非常麻烦,通过百度,写了两个BAT,基本能做工作需要. ***start.bat start "" " ...