一、集群的理论知识

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. ios常用数据库、完美无缺

    直接copy过去就能用,我们不用再去造轮子,现在的xocod9.4更加人性化了,不用再添加依赖库,这点苹果你让我开始喜欢了,哈哈. 需要这兄弟拉进去的哈 下班标的1,2,3,4就是就截图的4个文件,没 ...

  2. Java并发编程(一)为什么要并发

    并发所带来的好处 1. 并发在某些情况(并不是所有情况)下可以带来性能上的提升 1) 提升对CPU的使用效率 提升多核CPU的利用率:一般来说一台主机上的会有多个CPU核心,我们可以创建多个线程,理论 ...

  3. vue移动端项目vw适配运行项目时出现"advanced"报错解决办法。

    Module build failed: Error: Cannot load preset "advanced". Please check your configuration ...

  4. 洛谷P4525 【模板】自适应辛普森法1(simpson积分)

    题目描述 计算积分 结果保留至小数点后6位. 数据保证计算过程中分母不为0且积分能够收敛. 输入输出格式 输入格式: 一行,包含6个实数a,b,c,d,L,R 输出格式: 一行,积分值,保留至小数点后 ...

  5. Codeforces Round #483 (Div. 2)C题

    C. Finite or not? time limit per test 1 second memory limit per test 256 megabytes input standard in ...

  6. python字符编码转换说明及深浅copy介绍

    编码说明: 常用编码介绍: ascii 数字,字母 特殊字符. 字节:8位表示一个字节. 字符:是你看到的内容的最小组成单位. abc : a 一个字符. 中国:中 一个字符. a : 0000 10 ...

  7. 【Java】abstract,final,static,private,protected,public的区别

    [abstract]抽象的 1. abstract可以修饰类和成员方法,被abstract修饰的类称为抽象类,被abstract修饰成员方法叫抽象方法.抽象类不一定有抽象方法,但拥有抽象方法的类一定是 ...

  8. hadoop生态搭建(3节点)-15.Nginx_Keepalived_Tomcat配置

    # Nginx+Tomcat搭建高可用服务器名称 预装软件 IP地址Nginx服务器 Nginx1 192.168.6.131Nginx服务器 Nginx2 192.168.6.132 # ===== ...

  9. S3C2440启动程序运行过程

    s3c2440有两种启动方式,一种Nor flash 启动,一种Nand flash 启动. 由于NAND FLASH是接在NAND FLASH控制器上而不是系统总线上,所以没有在S3C2440A的8 ...

  10. SaltStack error: No module named 'salt'

    启动saltstack的时候出现下面的错误 问题原因 是因为我在centos7中安装了多版本的python导致的 解决方案 将文件下面文件首行更改成python2 [root@saltstack-12 ...