MongoDB基础请参考:https://blog.51cto.com/kaliarch/2044423前端
MongoDB(replica set)请参考:http://www.javashuo.com/article/p-evgbnpka-kx.htmllinux
1、概述mongodb
1.1 背景数据库
为解决mongodb在replica set每一个从节点上面的数据库均是对数据库的全量拷贝,从节点压力在高并发大数据量的场景下存在很大挑战,同时考虑到后期mongodb集群的在数据压力巨大时的扩展性,应对海量数据引出了分片机制。后端
1.2 分片概念缓存
分片是将数据库进行拆分,将其分散在不一样的机器上的过程,无需功能强大的服务器就能够存储更多的数据,处理更大的负载,在总数据中,将集合切成小块,将这些块分散到若干片中,每一个片只负载总数据的一部分,经过一个知道数据与片对应关系的组件mongos的路由进程进行操做。bash
1.3 基础组件服务器
其利用到了四个组件:mongos,config server,shard,replica set网络
mongos:数据库集群请求的入口,全部请求须要通过mongos进行协调,无需在应用层面利用程序来进行路由选择,mongos其自身是一个请求分发中心,负责将外部的请求分发到对应的shard服务器上,mongos做为统一的请求入口,为防止mongos单节点故障,通常须要对其作HA。架构
config server:配置服务器,存储全部数据库元数据(分片,路由)的配置。mongos自己没有物理存储分片服务器和数据路由信息,只是存缓存在内存中来读取数据,mongos在第一次启动或后期重启时候,就会从config server中加载配置信息,若是配置服务器信息发生更新会通知全部的mongos来更新本身的状态,从而保证准确的请求路由,生产环境中一般也须要多个config server,防止配置文件存在单节点丢失问题。
shard:在传统意义上来说,若是存在海量数据,单台服务器存储1T压力很是大,不管考虑数据库的硬盘,网络IO,又有CPU,内存的瓶颈,若是多台进行分摊1T的数据,到每台上就是可估量的较小数据,在mongodb集群只要设置好分片规则,经过mongos操做数据库,就能够自动把对应的操做请求转发到对应的后端分片服务器上。
replica set:在整体mongodb集群架构中,对应的分片节点,若是单台机器下线,对应整个集群的数据就会出现部分缺失,这是不能发生的,所以对于shard节点须要replica set来保证数据的可靠性,生产环境一般为2个副本+1个仲裁。
1.4 架构图
2、安装部署
2.1 基础环境
为了节省服务器,采用多实例配置,三个mongos,三个config server,单个服务器上面运行不通角色的shard(为了后期数据分片均匀,将三台shard在各个服务器上充当不一样的角色。),在一个节点内采用replica set保证高可用,对应主机与端口信息以下:
主机名 |
IP地址 |
组件mongos |
组件config server |
shard |
mongodb-1 |
172.20.6.10 |
端口:20000 |
端口:21000 |
主节点: 22001 |
副本节点:22002 |
||||
仲裁节点:22003 |
||||
mongodb-2 |
172.20.6.11 |
端口:20000 |
端口:21000 |
仲裁节点:22001 |
主节点: 22002 |
||||
副本节点:22003 |
||||
mongodb-3 |
172.20.6.12 |
端口:20000 |
端口:21000 |
副本节点:22001 |
仲裁节点:22002 |
||||
主节点: 22003 |
2.二、安装部署
2.2.1 软件下载目录建立
wget -c https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-3.4.10.tgz tar -zxvf mongodb-linux-x86_64-rhel62-3.4.10.tgz ln -sv mongodb-linux-x86_64-rhel62-3.4.10 mongodb echo "PATH=$PAHT:/usr/local/mongodb/bin">/etc/profile.d/mongodb.sh source /etc/profile.d/mongodb.sh
2.2.2 建立目录
分别在mongodb-1/mongodb-2/mongodb-3建立目录及日志文件
mkdir -p /data/mongodb/mongos/{log,conf} mkdir -p /data/mongodb/mongoconf/{data,log,conf} mkdir -p /data/mongodb/shard1/{data,log,conf} mkdir -p /data/mongodb/shard2/{data,log,conf} mkdir -p /data/mongodb/shard3/{data,log,conf} touch /data/mongodb/mongos/log/mongos.log touch /data/mongodb/mongoconf/log/mongoconf.log touch /data/mongodb/shard1/log/shard1.log touch /data/mongodb/shard2/log/shard2.log touch /data/mongodb/shard3/log/shard3.log
2.2.3 配置config server副本集
在mongodb3.4版本后要求配置服务器也建立为副本集,在此副本集名称:replconf
在三台服务器上配置config server副本集配置文件,并启动服务
cat>/data/mongodb/mongoconf/conf/mongoconf.conf<<EOFdbpath=/data/mongodb/mongoconf/data logpath=/data/mongodb/mongoconf/log/mongoconf.log #定义config server日志文件 logappend=true port = 21000 maxConns = 1000 #连接数 journal = true #日志开启 journalCommitInterval = 200 fork = true #后台执行 syncdelay = 60 oplogSize = 1000 configsvr = true #配置服务器 replSet=replconf #config server配置集replconf EOF mongod -f /data/mongodb/mongoconf/conf/mongoconf.conf #三台服务器均启动config server
任意登陆一台服务器进行配置服务器副本集初始化
use admin config = {_id:"replconf",members:[ {_id:0,host:"172.20.6.10:21000"}, {_id:1,host:"172.20.6.11:21000"}, {_id:2,host:"172.20.6.12:21000"},] } rs.initiate(config);
查看集群状态:
replconf:OTHER> rs.status() { "set" : "replconf", "date" : ISODate("2017-12-04T07:42:09.054Z"), "myState" : 1, "term" : NumberLong(1), "configsvr" : true, "heartbeatIntervalMillis" : NumberLong(2000), "optimes" : { "lastCommittedOpTime" : { "ts" : Timestamp(1512373328, 1), "t" : NumberLong(1) }, "readConcernMajorityOpTime" : { "ts" : Timestamp(1512373328, 1), "t" : NumberLong(1) }, "appliedOpTime" : { "ts" : Timestamp(1512373328, 1), "t" : NumberLong(1) }, "durableOpTime" : { "ts" : Timestamp(1512373328, 1), "t" : NumberLong(1) } }, "members" : [ { "_id" : 0, "name" : "172.20.6.10:21000", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", "uptime" : 221, "optime" : { "ts" : Timestamp(1512373328, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-04T07:42:08Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1512373296, 1), "electionDate" : ISODate("2017-12-04T07:41:36Z"), "configVersion" : 1, "self" : true }, { "_id" : 1, "name" : "172.20.6.11:21000", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 42, "optime" : { "ts" : Timestamp(1512373318, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1512373318, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-04T07:41:58Z"), "optimeDurableDate" : ISODate("2017-12-04T07:41:58Z"), "lastHeartbeat" : ISODate("2017-12-04T07:42:08.637Z"), "lastHeartbeatRecv" : ISODate("2017-12-04T07:42:07.648Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.10:21000", "configVersion" : 1 }, { "_id" : 2, "name" : "172.20.6.12:21000", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", "uptime" : 42, "optime" : { "ts" : Timestamp(1512373318, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1512373318, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-04T07:41:58Z"), "optimeDurableDate" : ISODate("2017-12-04T07:41:58Z"), "lastHeartbeat" : ISODate("2017-12-04T07:42:08.637Z"), "lastHeartbeatRecv" : ISODate("2017-12-04T07:42:07.642Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.10:21000", "configVersion" : 1 } ], "ok" : 1 }
此时config server集群已经配置完成,mongodb-1为primary,mongdb-2/mongodb-3为secondary
2.2.4 配置shard集群
三台服务器均进行shard集群配置
shard1配置
cat >/data/mongodb/shard1/conf/shard.conf <<EOF dbpath=/data/mongodb/shard1/data logpath = /data/mongodb/shard1/log/shard1.log port = 22001 logappend = true nohttpinterface = true fork = true oplogSize = 4096 journal = true #engine = wiredTiger #cacheSizeGB = 38G smallfiles=true shardsvr=true #shard服务器 replSet=shard1 #副本集名称shard1 EOF mongod -f /data/mongodb/shard1/conf/shard.conf #启动shard服务
查看此时服务已经正常启动,shard1的22001端口已经正常监听,接下来登陆mongodb-1服务器进行shard1副本集初始化
mongo 172.20.6.10:22001 use admin config = {_id:"shard1",members:[ {_id:0,host:"172.20.6.10:22001"}, {_id:1,host:"172.20.6.11:22001",arbiterOnly:true}, {_id:2,host:"172.20.6.12:22001"},] } rs.initiate(config);
查看集群状态,只列出了部分信息:
{ "_id" : 0, "name" : "172.20.6.10:22001", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #mongodb-1为primary "uptime" : 276, "optime" : { "ts" : Timestamp(1512373911, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-04T07:51:51Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1512373879, 1), "electionDate" : ISODate("2017-12-04T07:51:19Z"), "configVersion" : 1, "self" : true }, { "_id" : 1, "name" : "172.20.6.11:22001", "health" : 1, "state" : 7, "stateStr" : "ARBITER", #mongodb-2为arbiter "uptime" : 45, "lastHeartbeat" : ISODate("2017-12-04T07:51:53.597Z"), "lastHeartbeatRecv" : ISODate("2017-12-04T07:51:51.243Z"), "pingMs" : NumberLong(0), "configVersion" : 1 }, { "_id" : 2, "name" : "172.20.6.12:22001", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #mongodb-3为secondary "uptime" : 45, "optime" : { "ts" : Timestamp(1512373911, 1), "t" : NumberLong(1) },
此时shard1 副本集已经配置完成,mongodb-1为primary,mongodb-2为arbiter,mongodb-3为secondary。
一样的操做进行shard2配置和shard3配置
注意:进行shard2的副本集初始化,在mongodb-2, 初始化shard3副本集在mongodb-3上进行操做。
shard2配置文件
cat >/data/mongodb/shard2/conf/shard.conf <<EOF dbpath=/data/mongodb/shard2/data logpath = /data/mongodb/shard2/log/shard2.log port = 22002 logappend = true nohttpinterface = true fork = true oplogSize = 4096 journal = true #engine = wiredTiger #cacheSizeGB = 38G smallfiles=true shardsvr=true replSet=shard2 EOF mongod -f /data/mongodb/shard2/conf/shard.conf
shard3配置文件
cat >/data/mongodb/shard3/conf/shard.conf <<EOF dbpath=/data/mongodb/shard3/data logpath = /data/mongodb/shard3/log/shard3.log port = 22003 logappend = true nohttpinterface = true fork = true oplogSize = 4096 journal = true #engine = wiredTiger #cacheSizeGB = 38G smallfiles=true shardsvr=true replSet=shard3 EOF mongod -f /data/mongodb/shard2/conf/shard.conf
在mongodb-2上进行shard2副本集初始化
mongo 172.20.6.11:22002 #登陆mongodb-2 use admin config = {_id:"shard2",members:[ {_id:0,host:"172.20.6.10:22002"}, {_id:1,host:"172.20.6.11:22002"}, {_id:2,host:"172.20.6.12:22002",arbiterOnly:true},] } rs.initiate(config);
查看shard2副本集状态
{ "_id" : 0, "name" : "172.20.6.10:22002", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #mongodb-2为secondary "uptime" : 15, "optime" : { "ts" : Timestamp(1512374668, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1512374668, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-04T08:04:28Z"), "optimeDurableDate" : ISODate("2017-12-04T08:04:28Z"), "lastHeartbeat" : ISODate("2017-12-04T08:04:30.527Z"), "lastHeartbeatRecv" : ISODate("2017-12-04T08:04:28.492Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.11:22002", "configVersion" : 1 }, { "_id" : 1, "name" : "172.20.6.11:22002", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #mongodb-2为primary "uptime" : 211, "optime" : { "ts" : Timestamp(1512374668, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-04T08:04:28Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1512374666, 1), "electionDate" : ISODate("2017-12-04T08:04:26Z"), "configVersion" : 1, "self" : true }, { "_id" : 2, "name" : "172.20.6.12:22002", #mongodb-3为arbiter "health" : 1, "state" : 7, "stateStr" : "ARBITER", "uptime" : 15, "lastHeartbeat" : ISODate("2017-12-04T08:04:30.527Z"), "lastHeartbeatRecv" : ISODate("2017-12-04T08:04:28.384Z"), "pingMs" : NumberLong(0), "configVersion" : 1 }
登陆mongodb-3进行shard3副本集初始化
mongo 172.20.6.12:22003 #登陆mongodb-3 use admin config = {_id:"shard3",members:[ {_id:0,host:"172.20.6.10:22003",arbiterOnly:true}, {_id:1,host:"172.20.6.11:22003"}, {_id:2,host:"172.20.6.12:22003"},] } rs.initiate(config);
查看shard3副本集状态
{ "_id" : 0, "name" : "172.20.6.10:22003", "health" : 1, "state" : 7, "stateStr" : "ARBITER", #mongodb-1为arbiter "uptime" : 18, "lastHeartbeat" : ISODate("2017-12-04T08:07:37.488Z"), "lastHeartbeatRecv" : ISODate("2017-12-04T08:07:36.224Z"), "pingMs" : NumberLong(0), "configVersion" : 1 }, { "_id" : 1, "name" : "172.20.6.11:22003", "health" : 1, "state" : 2, "stateStr" : "SECONDARY", #mongodb-2为secondary "uptime" : 18, "optime" : { "ts" : Timestamp(1512374851, 1), "t" : NumberLong(1) }, "optimeDurable" : { "ts" : Timestamp(1512374851, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-04T08:07:31Z"), "optimeDurableDate" : ISODate("2017-12-04T08:07:31Z"), "lastHeartbeat" : ISODate("2017-12-04T08:07:37.488Z"), "lastHeartbeatRecv" : ISODate("2017-12-04T08:07:36.297Z"), "pingMs" : NumberLong(0), "syncingTo" : "172.20.6.12:22003", "configVersion" : 1 }, { "_id" : 2, "name" : "172.20.6.12:22003", "health" : 1, "state" : 1, "stateStr" : "PRIMARY", #mongodb-3为primary "uptime" : 380, "optime" : { "ts" : Timestamp(1512374851, 1), "t" : NumberLong(1) }, "optimeDate" : ISODate("2017-12-04T08:07:31Z"), "infoMessage" : "could not find member to sync from", "electionTime" : Timestamp(1512374849, 1), "electionDate" : ISODate("2017-12-04T08:07:29Z"), "configVersion" : 1, "self" : true }
此时shard集群所有已经配置完毕。
2.2.5 配置路由服务器mongos
目前三台服务器的配置服务器和分片服务器均已启动,配置三台mongos服务器
因为mongos服务器的配置是从内存中加载,因此本身没有存在数据目录configdb链接为配置服务器集群
cat >/data/mongodb/mongos/conf/mongos.conf<<EOF --logpath=/data/mongodb/mongos/log/mongos.log logappend=true port = 20000 maxConns = 1000 configdb=replconf/172.20.6.10:21000,172.20.6.11:21000,172.20.6.12:21000 #制定config server集群 fork = true EOF mongos -f /data/mongodb/mongos/conf/mongos.conf #启动mongos服务
目前config server集群/shard集群/mongos服务均已启动,但此时为设置分片,还不能使用分片功能。须要登陆mongos启用分片
登陆任意一台mongos
mongo 172.20.6.10:20000 use admin db.runCommand({addshard:"shard1/172.20.6.10:22001,172.20.6.11:22001,172.20.6.12:22001"}) db.runCommand({addshard:"shard2/172.20.6.10:22002,172.20.6.11:22002,172.20.6.12:22002"}) db.runCommand({addshard:"shard3/172.20.6.10:22003,172.20.6.11:22003,172.20.6.12:22003"})
查看集群
3、 测试
目前配置服务、路由服务、分片服务、副本集服务都已经串联起来了,此时进行数据插入,数据可以自动分片。链接在mongos上让指定的数据库、指定的集合分片生效。
注意:设置分片须要在admin数据库进行
use admin db.runCommand( { enablesharding :"kaliarchdb"}); #开启kaliarch库分片功能 db.runCommand( { shardcollection : "kaliarchdb.table1",key : {_id:"hashed"} } ) #指定数据库里须要分片的集合tables和片键_id
设置kaliarchdb的 table1 表须要分片,根据 _id 自动分片到 shard1 ,shard2,shard3 上面去。
查看分片信息
测试插入数据
use kaliarchdb; for (var i = 1; i <= 100000; i++) db.table1.save({_id:i,"test1":"testval1"});
查看分片状况:(省去部分信息)
db.table1.stats() { "sharded" : true, "capped" : false, "ns" : "kaliarchdb.table1", "count" : 100000, #总count "size" : 3800000, "storageSize" : 1335296, "totalIndexSize" : 4329472, "indexSizes" : { "_id_" : 1327104, "_id_hashed" : 3002368 }, "avgObjSize" : 38, "nindexes" : 2, "nchunks" : 6, "shards" : { "shard1" : { "ns" : "kaliarchdb.table1", "size" : 1282690, "count" : 33755, #shard1的count数 "avgObjSize" : 38, "storageSize" : 450560, "capped" : false, ...... "shard2" : { "ns" : "kaliarchdb.table1", "size" : 1259434, "count" : 33143, #shard2的count数 "avgObjSize" : 38, "storageSize" : 442368, "capped" : false, ....... "shard3" : { "ns" : "kaliarchdb.table1", "size" : 1257876, "count" : 33102, #shard3的count数 "avgObjSize" : 38, "storageSize" : 442368, "capped" : false,
此时架构中的mongos,config server,shard集群均已经搭建部署完毕,在实际生成环境话须要对前端的mongos作高可用来提示总体高可用。