mongodb的集群搭建

  对于当前的环境下,针对大数据量存储的处理,我们往往会选择分片或者集群方案。这两个方案具有数据库的可靠性和高可读性。可靠性是指对数据库的访问不会因为单点故障而导致用户无法操作;高可读性则是用户的读取服务器和写入服务器在不同的地方,而且,由不同的服务器为不同的用户提供 服务,提高整个系统的负载。

  mongodb的集群和分片方案和其他数据库不太一样,列如mysql,如果要实现其主从复制,我们获取会借助mycat组件来实现。而mongodb就不需要其他组件,它的集群分片方案几乎是全自动的。

一、mongodb集群--复制集

  复制集是指:一组复制集就是一组mongod实例掌管同一个数据集,实例可以在不同的机器上面。实例中包含一个主数据库(Primary),接受客户端所有的写入操作,其他都是副数据库(Secondary),从主服务器上获得数据并保持同步。

  1.1 复制集中的成员

  在了解复制集的架构前,我们需要先了解里面所有的成员

  

  在上面中所说的选举,它的主要过程是:复制集通过replSetInitiate命令(或mongo shell的rs.initiate())进行初始化,初始化后各个成员间开始发送心跳消 息,并发起Priamry选举操作,获得『大多数』成员投票支持的节点,会成为Primary,其余节点成为Secondary。

  假设复制集内投票成员数量为N,则大多数为 N/2 + 1,当复制集内存活成员数量不足大多数时,整个复制集将无法 选举出Primary,复制集将无法提供写服务,处于只读状态。

  1.2 复制集的架构

  根据mongodb中设计的成员,我们大概可以列出以下几种

  (1)一主两从

  

  这种就是我们最常见的一种架构,由一个主数据库和两个从数据库组成。主数据库负责用户写的操作,从数据库负责同步主数据库的数据,并且提供读操作。

  其次当主机意外宕机时,两个从机会自动选择一个作为主机。当原来的主机恢复后,会自动加入集群并成为一个从机。

  (2)一主一从一选举

      

  这个架构是在mongodb中独有的一种,它是由一个主机、一个从机和一个arbiter节点组成。由于arbiter节点的特殊性,可以复制集的成本压缩最小。arbiter节点只负责投票,不负责存数据,也不能当主机,因此我们可以在从机服务器上添加,这样如果主机意外宕机后,从机变成主机,复制集依然能够使用。

  1.3 集群搭建

  本文集群搭建的环境是linux下搭建的,用的mongodb版本为4.0.3,使用docker服务的方式进行集群搭建。

  第一步:创建3个mongodb容器。本文是根据上面介绍的架构,只用三个作为示例。

docker create --name mg1 -p 27017:27017 -v mongo-data-01:/data/db mongo:4.0.3 --replSet "colony" --bind_ip_all
docker create --name mg2 -p 27018:27017 -v mongo-data-02:/data/db mongo:4.0.3 --replSet "colony" --bind_ip_all
docker create --name mg3 -p 27019:27017 -v mongo-data-03:/data/db mongo:4.0.3 --replSet "colony" --bind_ip_all

  第二步:启动容器

docker start mg1 mg2 mg3

  第三步:在配置好容器后,我们需要进入连接mongodb服务,配置集群

docker exec -it mg1/bin/bash

  第四步:登录到一个mongodb

mongo 182.159.31.76:27017

  第五步:配置集群

rs.initiate( {
_id : "colony",
members: [
{ _id: 0, host: "182.159.31.76:27017" },
{ _id: 1, host: "182.159.31.76:27018" },
{ _id: 2, host: "182.159.31.76:27019" }
]
})

  以上mongodb的复制集就已经搭建完成,搭建完成后它会自动选择一个数据库作为主机。

二、mongodb分片集群

  分片是MongoDB用来将大型集合分割到不同服务器(或者说一个集群)上所采用的方法。尽管分片起 源于关系型数据库分区,但MongoDB分片完全又是另一回事。

  和MySQL分区方案相比,MongoDB的最大区别在于它几乎能自动完成所有事情,只要告诉MongoDB要分配数据,它就能自动维护数据在不同服务器之间的均衡。

  2.1 mongodb分片的好处

  (1)能够保证集群不可见,通过一个路由进程保证用户访问的是统一的入口。

  (2)当分片和集群同时使用时,能够保证集群总是可以读写的(故障转移的功能)。

  (3)使集群易于扩展,当系统需要更多的空间和资源的时候,MongoDB使我们可以按需方便的扩充系统容量。

  2.2 mongodb的分片架构

  

  架构中的成员是:

  

 

  根据架构图可以看见,Mongos本身并不持久化数据,Sharded cluster所有的元数据都会存储到Config Server,而用户的数据会分散存储 到各个shard。Mongos启动后,会从配置服务器加载元数据,开始提供服务,将用户的请求正确路由到对应的分 片。

  当数据写入时,MongoDB Cluster根据分片键设计写入数据。当外部语句发起数据查询时,MongoDB根据数据分布自动路由至指定节点返回数据。

  2.3 mongodb的数据分片原理

  mongodb的分片逻辑主要是在Shard中体现的,在一个shard server内部,MongoDB会把数据分为chunks,每个chunk代表这个shard server内部一部分数据。

  chunk主要有两个用途:

  (1)分裂(spliting):

  当一个chunk的大小超过配置中的chunk size时,MongoDB的后台进程会把这个chunk切分成更小的chunk,从而避免chunk过大的情况。

  (2)迁移(Balancing):

  

  在MongoDB中,balancer是一个后台进程,负责chunk的迁移,从而均衡各个shard server的负载,系统初始1个chunk,chunk size默认值64M,生产库上选择适合业务的chunk size是最好的。mongoDB会自动拆分和迁移chunks。

  2.4 chunk分裂的影响

  chunk有一个特点:只会分裂,不会合并。

  根据这个特点和上面mongodb的分片原理来看,设置chunk size的大小能够影响整个集群的性能。

  当设置chunk size较小时,数据均衡是迁移速度快,数据分布更均匀。数据分裂频繁,路由节点消耗更多资源。

  当设置chunk size较大时,数据分裂少,数据块移动集中消耗IO资源

  2.5 搭建mongodb分片

  第一步:创建config server节点,按照要求我们创建三个

docker create --name configserver1 -p 2500:27019 -v mongoconfigserver1:/data/configdb mongo:4.0.3 --configsvr --replSet "colonyconfigserver" --bind_ip_all
docker create --name configserver2 -p 2501:27019 -v mongoconfigserver2:/data/configdb mongo:4.0.3 --configsvr --replSet "colonyconfigserver" --bind_ip_all
docker create --name configserver3 -p 2502:27019 -v mongoconfigserver3:/data/configdb mongo:4.0.3 --configsvr --replSet "colonyconfigserver" --bind_ip_all

  第二步:启动服务

docker start configserver1 configserver2 configserver3

  第三步:进入mongodb容器,对集群初始化

docker exec -it configserver1 /bin/bash
mongo 182.159.31.76:2500
rs.initiate(
{
_id: "colonyconfigserver",
#设置集群为congfig server集群 configsvr: true, members: [       { _id : 0, host : "182.159.31.76:2500" },       { _id : 1, host : "182.159.31.76:2501" },       { _id : 2, host : "182.159.31.76:2502" }     ]   } )

  第四步:在创建好configserver节点后,我们接下来创建shard节点,在这么我们采用复制集的方式创建

  创建两个shard复制集,每个集群有3个节点

#集群一
docker create --name shardsvr01 -p 37000:27018 -v mongoshardsvr-data-01:/data/db
mongo:4.0.3 --replSet "rs_shardsvr1" --bind_ip_all --shardsvr
docker create --name shardsvr02 -p 37001:27018 -v mongoshardsvr-data-02:/data/db
mongo:4.0.3 --replSet "rs_shardsvr1" --bind_ip_all --shardsvr
docker create --name shardsvr03 -p 37002:27018 -v mongoshardsvr-data-03:/data/db
mongo:4.0.3 --replSet "rs_shardsvr1" --bind_ip_all --shardsvr
#集群二
docker create --name shardsvr04 -p 37003:27018 -v mongoshardsvr-data-04:/data/db
mongo:4.0.3 --replSet "rs_shardsvr2" --bind_ip_all --shardsvr
docker create --name shardsvr05 -p 37004:27018 -v mongoshardsvr-data-05:/data/db
mongo:4.0.3 --replSet "rs_shardsvr2" --bind_ip_all --shardsvr
docker create --name shardsvr06 -p 37005:27018 -v mongoshardsvr-data-06:/data/db
mongo:4.0.3 --replSet "rs_shardsvr2" --bind_ip_all --shardsvr

  第五步:启动容器

docker start shardsvr01 shardsvr02 shardsvr03
docker start shardsvr04 shardsvr05 shardsvr06

  第六步:初始化集群

docker exec -it shardsvr01 /bin/bash
mongo 182.159.31.76:37000
#初始化集群
rs.initiate(
{
_id: "rs_shardsvr1",
members: [
{ _id : 0, host : "182.159.31.76:37000" },
{ _id : 1, host : "182.159.31.76:37001" },
{ _id : 2, host : "182.159.31.76:37002" }
]
}
)
#初始化集群二
mongo 182.159.31.76:37003
rs.initiate(
{
_id: "rs_shardsvr2",
members: [
{ _id : 0, host : "182.159.31.76:37003" },
{ _id : 1, host : "182.159.31.76:37004" },
{ _id : 2, host : "182.159.31.76:37005" }
]
}
)

  第七步:配置好configserver和shard后,就该配置mongos了。需要注意的是mongos在构建容器时要添加configsever的所有节点。

docker create --name mongos -p 2400:27017 --entrypoint "mongos" mongo:4.0.3 --configdb colonyconfigserver/182.159.31.76:2500,182.159.31.76:2501,182.159.31.76:2502--
bind_ip_all

  第八步:在mongos中添加shard节点

docker start mongos
#进入容器执行
docker exec -it mongos bash
mongo 182.159.31.76:2400
#添加shard节点
sh.addShard("rs_shardsvr1/182.159.31.76:37000,182.159.31.76:37001,182.159.31.76:37002
")
sh.addShard("rs_shardsvr2/182.159.31.76:37003,182.159.31.76:37004,182.159.31.76:37005
")

  这样我们的分片集群就搭建好了,接下来就是启用和设置我们的分片

  2.6 分片设置

  第一步:对usertest数据库启用分片

sh.enableSharding("usertest")

  第二步:设置分片规则,常用的有两种,第一种是hash分片,hash分片非常简单,直接设置即可

#设置分片规则,按照_id的hash进行区分,第一个参数是指定mongodb中的collection
sh.shardCollection("test.user", {"_id": "hashed" })

  第二种是根据索引进行分片,因此设置分片时,需要先添加索引

#对userId创建索引
db.col.createIndex({"userid":1})
#创建索引后,就能进行分片
sh.shardCollection(“test.user” , "userid" : 1)  

  至此,mongodb的分片就设置完成了。

 

 

  

  

 

 

 

  

  

posted @ 2020-06-14 21:53  想去天空的猫  阅读(947)  评论(0编辑  收藏  举报