mongoDB集群有三种方式
1、主从模式:类似于mysql master slave 方式。
2、副本集模式:其实就是一主多从,如果主节点挂掉,会重新在从节点选取一台为主节点。
3、分片模式:针对大数据量,高负载情况。
由于我们是为了处理全球矢量数据,针对这种情况我们选用分片+副本集群方式。
分片集群
当MongoDB存储海量的数据时,一台机器可能不足以存储数据,也可能不足以提供可接受的读写吞吐量。这时,我们就可以通过在多台机器上分割数据,使得数据库系统能存储和处理更多的数据。
为什么使用分片?
1. 复制所有的写入操作到主节点
2. 延迟的敏感数据会在主节点查询
3. 单个副本集限制在12个节点
4. 当请求量巨大时会出现内存不足。
5. 本地磁盘不足
6. 垂直扩展价格昂贵
Shard:
用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个relica set承担,防止主机单点故障
Config Server:
mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
Query Routers:
前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。
分片实例:
node1:10.0.0.10 – 3个Config Server、1个Routers、1个Shard
node2:10.0.0.11 – 1个Routers、1个Shard
node3:10.0.0.12 – 1个Shard
注意:在做分片的时候,要避免Shard在同一台主机上,这样就没办法实现分片。
分片+副本集集群搭建
模块介绍
(1)Shard服务器:使用Replica Sets确保每个数据节点都具有备份、自动容错转移、自动恢复的能力。
(2)配置服务器:使用使用3个配置服务器确保元数据完整性。
(3)路由进程:使用3个路由进程实现平衡,提高客户端接入性能
(4)3 个分片进程:Shard11,Shard12,Shard13 组成一个副本集,提供Sharding 中 shard1 的功能。
(5)3 个分片进程:Shard21,Shard22,Shard23 组成一个副本集,提供Sharding 中 Shard2 的功能。
(6)3 个分片进程:Shard31,Shard32,Shard33 组成一个副本集,提供Sharding 中 Shard3的功能。
(7)3个配置服务器进程和3个路由器进程。
构建一个mongodb sharding Cluster 需要三个角色:shard服务器(shardServer),配置服务器(configServer),路由进程(RouteServer)
Shard服务器
shard 服务器即存储实际数据的分片,每个 shard 可以是一个 mongod 实例, 也可以是一组 mongod 实例构成的 Replica Sets.为了实现每个 Shard 内部的故障 自动转换,MongoDB 官方建议每个 shard 为一组 Replica Sets.
配置服务器
为了将一个特定的 collection 存储在多个 shard 中,需要为该 collection 指定 一个 shard key,决定该条记录属于哪个 chunk,配置服务器可以存储以下信息, 每个shard节点的配置信息,每个chunk的shard key范围,chunk在各shard 的分布情况,集群中所有 DB 和 collection 的 sharding 配置信息。
路由进程
它是一个前段路由,客户端由此接入,首先询问配置服务器需要到哪个 shard 上查询或保存记录,然后连接相应的 shard 执行操作,最后将结果返回给客户端,客 户端只需要将原本发给 mongod 的查询或更新请求原封不动地发给路由进程,而 不必关心所操作的记录存储在哪个 shard 上。
环境准备
系统:centos7
三台服务器:
192.168.1.145
192.168.1.149
192.168.1.166
安装包:https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.4.10.tgz 服务器规划:
端口号分配:
mongos:20000
config:21000
shard1:27001
shard2:27002
shard3:27003
集群搭建
1、安装mongodb(三台均执行)
下载mongodb
(1)在 usr/local 下执行
(2)、解压压缩包到mongodb文件夹下
解压后的文件夹下的界面如图:
(3)分别在每台机器建立conf、mongos、config、shard1、shard2、shard3六个目录,因为mongos不存储数据,只需要建立日志文件目录即可。
mkdir -p /usr/local/mongodb/conf
mkdir -p /usr/local/mongodb/mongos/log
mkdir -p /usr/local/mongodb/config/data
mkdir -p /usr/local/mongodb/config/log
mkdir -p /usr/local/mongodb/shard1/data
mkdir -p /usr/local/mongodb/shard1/log
mkdir -p /usr/local/mongodb/shard2/data
mkdir -p /usr/local/mongodb/shard2/log
mkdir -p /usr/local/mongodb/shard3/data
mkdir -p /usr/local/mongodb/shard3/log
(4)、配置环境变量
vi /etc/profile
# 内容
export MONGODB_HOME=/usr/local/mongodb
export PATH=$MONGODB_HOME/bin:$PATH
# 使立即生效
source /etc/profile
2、config server配置服务器
由于mongodb3.4之后要求配置服务器也需要配置副本集,不然集群搭建不成功。
添加配置文件,如下(三台机器均配置)
## 配置文件内容
pidfilepath = /usr/local/mongodb/config/log/configsrv.pid
dbpath = /usr/local/mongodb/config/data
logpath = /usr/local/mongodb/config/log/congigsrv.log
logappend = true
bind_ip = 0.0.0.0
## 端口号
port = 21000
fork = true
configsvr = true
##副本集名称
replSet=configs
## 最大连接数
maxConns=20000
运行三台服务器的config.server
mongod -f /usr/local/mongodb/conf/config.conf
登录任意一台配置服务器,初始化配置副本集
连接到mongodb
mongo --port 21000
设置config变量
config = {
... _id : "configs",
... members : [
... {_id : 0, host : "192.168.1.145:21000" },
... {_id : 1, host : "192.168.1.149:21000" },
... {_id : 2, host : "192.168.1.166:21000" }
... ]
... }
其中,"_id" : "configs"应与配置文件中配置的 replicaction.replSetName 一致,“members” 中的 “host” 为三个节点的 ip 和 port
初始化副本集
rs.initiate(config)
重点来了======================================
3、配置分片副本集(三台服务器均执行)
设置第一个分片副本集(三台机器均设置第一个分片副本集shard1)
配置文件如下:
编辑文件
vi /usr/local/mongodb/conf/shard1.conf
内容:
pidfilepath = /usr/local/mongodb/shard1/log/shard1.pid
dbpath = /usr/local/mongodb/shard1/data
logpath = /usr/local/mongodb/shard1/log/shard1.log
logappend = true
bind_ip = 0.0.0.0
port = 27001
fork = true
#打开web监控
httpinterface=true
rest=true
#副本集名称
replSet=shard1
#declare this is a shard db of a cluster;
shardsvr = true
#设置最大连接数
maxConns=20000
启动三台服务器第一个shard1.server
mongod -f /usr/local/mongodb/conf/shard1.conf
登录任意一台机器,初始化副本集
登录mongo --port 27001
使用admin数据库use admin
定义副本集配置,第三个节点的 “arbiterOnly”:true 代表其为仲裁节点。
config = {
... _id : "shard1",
... members : [
... {_id : 0, host : "192.168.1.145:27001" },
... {_id : 1, host : "192.168.1.149:27001" },
... {_id : 2, host : "192.168.1.166:27001” , arbiterOnly: true }
... ]
... }
初始化副本集配置
rs.initiate(config);
设置第二个分片副本集(三台机器均设置第一个分片副本集shard2)
配置文件如下
vi /usr/local/mongodb/conf/shard2.conf
#配置文件内容
#——————————————–
pidfilepath = /usr/local/mongodb/shard2/log/shard2.pid
dbpath = /usr/local/mongodb/shard2/data
logpath = /usr/local/mongodb/shard2/log/shard2.log
logappend = true
bind_ip = 0.0.0.0
port = 27002
fork = true
#打开web监控
httpinterface=true
rest=true
#副本集名称
replSet=shard2
#declare this is a shard db of a cluster;
shardsvr = true
#设置最大连接数
maxConns=20000
启动三台服务器的shard2.server
mongod -f /usr/local/mongodb/conf/shard2.conf
登陆任意一台服务器,初始化副本集
mongo --port 27002
#使用admin数据库
use admin
#定义副本集配置
config = {
... _id : "shard2",
... members : [
... {_id : 0, host : "192.168.1.145:27002" , arbiterOnly: true },
... {_id : 1, host : "192.168.1.149:27002" },
... {_id : 2, host : "192.168.1.166:27002" }
... ]
... }
#初始化副本集配置
rs.initiate(config);
设置第三个分片副本集(三台机器均设置第一个分片副本集shard3)
配置文件
vi /usr/local/mongodb/conf/shard3.conf
#配置文件内容
#——————————————–
pidfilepath = /usr/local/mongodb/shard3/log/shard3.pid
dbpath = /usr/local/mongodb/shard3/data
logpath = /usr/local/mongodb/shard3/log/shard3.log
logappend = true
bind_ip = 0.0.0.0
port = 27003
fork = true
#打开web监控
httpinterface=true
rest=true
#副本集名称
replSet=shard3
#declare this is a shard db of a cluster;
shardsvr = true
#设置最大连接数
maxConns=20000
启动三台服务器的shard3.server
mongod -f /usr/local/mongodb/conf/shard3.conf
登陆任意一台服务器,初始化副本集
mongo --port 27003
#使用admin数据库
use admin
#定义副本集配置
config = {
... _id : "shard3",
... members : [
... {_id : 0, host : "192.168.1.145:27003" },
... {_id : 1, host : "192.168.1.149:27003" , arbiterOnly: true},
... {_id : 2, host : "192.168.1.166:27003" }
... ]
... }
#初始化副本集配置
rs.initiate(config);
4、配置路由服务器mongos
先启动配置服务器和分片服务器,后启动路由实例启动路由实例:(三台机器)
vi /usr/local/mongodb/conf/mongos.conf
#内容
pidfilepath = /usr/local/mongodb/mongos/log/mongos.pid
logpath = /usr/local/mongodb/mongos/log/mongos.log
logappend = true
bind_ip = 0.0.0.0
port = 20000
fork = true
#监听的配置服务器,只能有1个或者3个 configs为配置服务器的副本集名字
configdb = configs/192.168.1.145:21000,192.168.1.149:21000,192.168.1.166:21000
#设置最大连接数
maxConns=20000
启动三台服务器的mongos server
mongos -f /usr/local/mongodb/conf/mongos.conf
5、启用分片
目前搭建了mongodb配置服务器、路由服务器,各个分片服务器,不过应用程序连接到mongos路由服务器并不能使用分片机制,还需要在程序里设置分片配置,让分片生效。
登陆任意一台mongos
mongo --port 20000
#使用admin数据库
user admin
#串联路由服务器与分配副本集
mongos> sh.addShard("shard1/192.168.1.145:27001,192.168.1.149:27001,192.168.1.166:27001")
mongos> sh.addShard("shard2/192.168.1.145:27002,192.168.1.149:27002,192.168.1.166:27002")
mongos> sh.addShard("shard3/192.168.1.145:27003,192.168.1.149:27003,192.168.1.166:27003")
#查看集群状态
sh.status()
6、测试
目前配置服务、路由服务、分片服务、副本集服务都已经串联起来了,但我们的目的是希望插入数据,数据能够自动分片。连接在mongos上,准备让指定的数据库、指定的集合分片生效。
#指定testdb分片生效
db.runCommand( { enablesharding :"testdb"});
#指定数据库里需要分片的集合和片键
db.runCommand( { shardcollection : "testdb.table1",key : {id: 1} } )
我们设置testdb的 table1 表需要分片,根据 id 自动分片到 shard1 ,shard2,shard3 上面去。要这样设置是因为不是所有mongodb 的数据库和表 都需要分片!
测试分片配置结果
mongo 127.0.0.1:20000
#使用testdb
use testdb;
#插入测试数据
for (var i = 1; i <= 100000; i++)
db.table1.save({id:i,"test1":"testval1"});
#查看分片情况如下,部分无关信息省掉了
db.table1.stats();
{
"sharded" : true,
"ns" : "testdb.table1",
"count" : 100000,
"numExtents" : 13,
"size" : 5600000,
"storageSize" : 22372352,
"totalIndexSize" : 6213760,
"indexSizes" : {
"_id_" : 3335808,
"id_1" : 2877952
},
"avgObjSize" : 56,
"nindexes" : 2,
"nchunks" : 3,
"shards" : {
"shard1" : {
"ns" : "testdb.table1",
"count" : 42183,
"size" : 0,
...
"ok" : 1
},
"shard2" : {
"ns" : "testdb.table1",
"count" : 38937,
"size" : 2180472,
...
"ok" : 1
},
"shard3" : {
"ns" : "testdb.table1",
"count" :18880,
"size" : 3419528,
...
"ok" : 1
}
},
"ok" : 1
}
可以看到数据分到3个分片,各自分片数量为: shard1 “count” : 42183,shard2 “count” : 38937,shard3 “count” : 18880。已经成功了!
7、后期使用
mongodb的启动顺序是,先启动配置服务器,在启动分片,最后启动mongos.
mongod -f /usr/local/mongodb/conf/config.conf
mongod -f /usr/local/mongodb/conf/shard1.conf
mongod -f /usr/local/mongodb/conf/shard2.conf
mongod -f /usr/local/mongodb/conf/shard3.conf
mongos -f /usr/local/mongodb/conf/mongos.conf (看清楚是mongos -f ....)
关闭时,直接killall杀掉所有进程
killall mongod
killall mongos
ps:1、在安装了最简版的系统时,killall 命令不能使用 需要执行 yum install psmisc 即可。
2、关闭防火墙:systemctl stop firewalld
3、查看防火墙状态:firewall-cmd --state
4、禁止防火墙开机启动:systemctl disable firewalld.server
5、列表端口号:netstat -ntlp