MongoDB副本集 一主一备+仲裁 环境部署

参考:
https://www.cnblogs.com/kevingrace/p/7881496.html
https://www.jianshu.com/p/f9f1454f251f

一、介绍

MongoDB复制集是一个带有故障转移的主从集群。是从现有的主从模式演变而来,增加了自动故障转移和节点成员自动恢复。MongoDB复制集模式中没有固定的主节点,在启动后,多个服务节点间将自动选举产生一个主节点。该主节点被称为primary,一个或多个从节点被称为secondaries。primary节点基本上就是master结点,不同之处在于primary结点在不同时间可能是不同的服务器。如果当前的主结点失效了,复制集中的其余结点将会试图选出一个新的主结点。

MongoDB复制集模式的好处:

  • 一切自动化。首先,复制集模式本身做了大量的管理工作,自动管理从节点,确保数据不会不一致。
  • 主节点挂掉后,会自动判断集群中的服务器并进行故障转移,推举新的主节点。
  • 一个复制集集群支持1-7台服务器,在一个复制集中各个服务器数据保持完全一致。

在一个MongoDB复制集集群中,各个服务器有以下几种状态:

  • Primary 主节点,一个复制集有且仅有一台服务器处于Primary状态,只有主节点才对外提供读写服务。如果主节点挂掉,复制集将投票选出一个备节点成为新的主节点。
  • Secondary 备用节点,复制集允许有多台Secondary,每个备用节点的数据与主节点的数据是完全同步的。Recovering 恢复中,当复制集中某台服务器挂掉或者掉线后数据无法同步,重新恢复服务后从其他成员复制数据,这时就处于恢复过程,数据同步后,该节点又回到备用状态。
  • Arbiter 仲裁节点,该类节点可以不用单独存在,如果配置为仲裁节点,就主要负责在复本集中监控其他节点状态,投票选出主节点。该节点将不会用于存放数据。如果没有仲裁节点,那么投票工作将由所有节点共同进行。
  • Down 无效节点,当服务器挂掉或掉线时就会处于该状态。复制集的从节点读请求,也是在各个Driver层设置slaveOk的值来实现的。

如上介绍所知,mongodb中的复制可以在多台服务器中同步数据。复制提供了冗余和增加了数据的高可用性,防止单个节点易丢失数据的可能性,也可以用来进行读写分离提高客户端操作性能。复制集中各节点的mongodb实例有相同的数据集副本。主节点可以接收客户端所有写操作记录到日志中,从库复制主库的操作日志记录应用到其数据库中。一个客户端只能有一个主节点,如果主节点不可用(10秒内无法连接),复制集中将选一个成员节点作为主节点。MongoDB主备+仲裁的基本结构如下:


原理图
  • 主节点(Primary)
    在复制集中,主节点是唯一能够接收写请求的节点。MongoDB在主节点进行写操作,并将这些操作记录到主节点的oplog中。而从节点将会从oplog复制到其本机,并将这些操作应用到自己的数据集上。(复制集最多只能拥有一个主节点)
  • 从节点(Secondaries)
    从节点通过应用主节点传来的数据变动操作来保持其数据集与主节点一致。从节点也可以通过增加额外参数配置来对应特殊需求。例如,从节点可以是non-voting或是priority 0.
  • 仲裁节点(ARBITER)
    仲裁节点即投票节点,其本身并不包含数据集,且也无法晋升为主节点。但是,旦当前的主节点不可用时,投票节点就会参与到新的主节点选举的投票中。仲裁节点使用最小的资源并且不要求硬件设备。投票节点的存在使得复制集可以以偶数个节点存在,而无需为复制集再新增节点 不要将投票节点运行在复制集的主节点或从节点机器上。 投票节点与其他 复制集节点的交流仅有:选举过程中的投票,心跳检测和配置数据。这些交互都是不加密的。

心跳检测
复制集成员每两秒向复制集中其他成员进行心跳检测。如果某个节点在10秒内没有返回,那么它将被标记为不可用。

二、安装

1.下载mongodb
https://www.mongodb.com/download-center/community
选择版本,本例选择最新4.2.3,服务器上用wget下载

wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.2.3.tgz

2.配置

  • 解压
tar -xzvf mongodb-linux-x86_64-rhel70-4.2.3.tgz 
  • 重命名为
mv mongodb-linux-x86_64-rhel70-4.2.3/ mongodb
  • 在mongodb目录新建data logs conf文件夹
cd mongodb
mkdir data logs conf
  • conf中新建配置文件
vi conf/mongodb.conf
#内容如下:
systemLog:
    destination: file
    path: "/home/cluster/mongodb/logs/mongod.log"
    logAppend: true
storage:
    dbPath: "/home/cluster/mongodb/data"
    journal:
        enabled: true
processManagement:
    fork: true  # fork and run in background
    timeZoneInfo: /usr/share/zoneinfo
net:
    bindIp: 192.168.62.15
    port: 28017
replication:
    oplogSizeMB: 1024
    replSetName: rs0

3.添加用户环境变量

vi .bash_profile
#文件末尾加上
export PATH=$PATH:/home/cluster/mongodb/bin

4.注册为系统服务

vi /lib/systemd/system/mongodb.service 
#内容如下:
[Unit]
Description=MongoDB Database Server
Documentation=https://docs.mongodb.org/manual
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
User=cluster
Group=cluster
ExecStart=/home/cluster/mongodb/bin/mongod --config /home/cluster/mongodb/conf/mongodb.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/home/cluster/mongodb/bin/mongod --config /home/cluster/mongodb/conf/mongodb.conf --shutdown
PrivateTmp=true  

[Install]
WantedBy=multi-user.target

三、启动

#关闭mongodb
mongod -f /home/cluster/mongodb/conf/mongodb.conf --shutdown
#使用配置文件启动mongodb
mongod -f /home/cluster/mongodb/conf/mongodb.conf

systemctl start mongodb.service
systemctl stop mongodb.service

四、配置集群

192.168.62.37    Primary
192.168.62.15    Secondary
192.168.62.95    Arbiter
#连接主节点
mongo 192.168.62.15:28037
#初始化集群
rs.initiate({_id: "rs0",members: [{ _id: 0 , host: "192.168.62.37:28017" }]})
#添加副节点
rs.add("192.168.62.15:28017")
#添加仲裁节点
rs.addArb("192.168.62.95:28017")
#查看状态
rs0:PRIMARY> rs.status();
{
        "set" : "rs0",
        "date" : ISODate("2020-03-23T09:22:37.763Z"),
        "myState" : 1,
        "term" : NumberLong(5),
        "syncingTo" : "",
        "syncSourceHost" : "",
        "syncSourceId" : -1,
        "heartbeatIntervalMillis" : NumberLong(2000),
        "majorityVoteCount" : 2,
        "writeMajorityCount" : 2,
        "optimes" : {
                "lastCommittedOpTime" : {
                        "ts" : Timestamp(1584955352, 1),
                        "t" : NumberLong(5)
                },
                "lastCommittedWallTime" : ISODate("2020-03-23T09:22:32.126Z"),
                "readConcernMajorityOpTime" : {
                        "ts" : Timestamp(1584955352, 1),
                        "t" : NumberLong(5)
                },
                "readConcernMajorityWallTime" : ISODate("2020-03-23T09:22:32.126Z"),
                "appliedOpTime" : {
                        "ts" : Timestamp(1584955352, 1),
                        "t" : NumberLong(5)
                },
                "durableOpTime" : {
                        "ts" : Timestamp(1584955352, 1),
                        "t" : NumberLong(5)
                },
                "lastAppliedWallTime" : ISODate("2020-03-23T09:22:32.126Z"),
                "lastDurableWallTime" : ISODate("2020-03-23T09:22:32.126Z")
        },
        "lastStableRecoveryTimestamp" : Timestamp(1584955322, 1),
        "lastStableCheckpointTimestamp" : Timestamp(1584955322, 1),
        "electionCandidateMetrics" : {
                "lastElectionReason" : "electionTimeout",
                "lastElectionDate" : ISODate("2020-03-23T09:11:51.967Z"),
                "electionTerm" : NumberLong(5),
                "lastCommittedOpTimeAtElection" : {
                        "ts" : Timestamp(1584954671, 1),
                        "t" : NumberLong(3)
                },
                "lastSeenOpTimeAtElection" : {
                        "ts" : Timestamp(1584954671, 1),
                        "t" : NumberLong(3)
                },
                "numVotesNeeded" : 2,
                "priorityAtElection" : 1,
                "electionTimeoutMillis" : NumberLong(10000),
                "numCatchUpOps" : NumberLong(0),
                "newTermStartDate" : ISODate("2020-03-23T09:11:52.111Z"),
                "wMajorityWriteAvailabilityDate" : ISODate("2020-03-23T09:14:02.372Z")
        },
        "members" : [
                {
                        "_id" : 0,
                        "name" : "192.168.62.37:28017",
                        "health" : 1,
                        "state" : 1,
                        "stateStr" : "PRIMARY",
                        "uptime" : 755,
                        "optime" : {
                                "ts" : Timestamp(1584955352, 1),
                                "t" : NumberLong(5)
                        },
                        "optimeDate" : ISODate("2020-03-23T09:22:32Z"),
                        "syncingTo" : "",
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "electionTime" : Timestamp(1584954711, 1),
                        "electionDate" : ISODate("2020-03-23T09:11:51Z"),
                        "configVersion" : 3,
                        "self" : true,
                        "lastHeartbeatMessage" : ""
                },
                {
                        "_id" : 1,
                        "name" : "192.168.62.15:28017",
                        "health" : 1,
                        "state" : 2,
                        "stateStr" : "SECONDARY",
                        "uptime" : 515,
                        "optime" : {
                                "ts" : Timestamp(1584955352, 1),
                                "t" : NumberLong(5)
                        },
                        "optimeDurable" : {
                                "ts" : Timestamp(1584955352, 1),
                                "t" : NumberLong(5)
                        },
                        "optimeDate" : ISODate("2020-03-23T09:22:32Z"),
                        "optimeDurableDate" : ISODate("2020-03-23T09:22:32Z"),
                        "lastHeartbeat" : ISODate("2020-03-23T09:22:36.033Z"),
                        "lastHeartbeatRecv" : ISODate("2020-03-23T09:22:36.372Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncingTo" : "192.168.62.37:28017",
                        "syncSourceHost" : "192.168.62.37:28017",
                        "syncSourceId" : 0,
                        "infoMessage" : "",
                        "configVersion" : 3
                },
                {
                        "_id" : 2,
                        "name" : "192.168.62.95:28017",
                        "health" : 1,
                        "state" : 7,
                        "stateStr" : "ARBITER",
                        "uptime" : 753,
                        "lastHeartbeat" : ISODate("2020-03-23T09:22:35.972Z"),
                        "lastHeartbeatRecv" : ISODate("2020-03-23T09:22:36.371Z"),
                        "pingMs" : NumberLong(0),
                        "lastHeartbeatMessage" : "",
                        "syncingTo" : "",
                        "syncSourceHost" : "",
                        "syncSourceId" : -1,
                        "infoMessage" : "",
                        "configVersion" : 3
                }
        ],
        "ok" : 1,
        "$clusterTime" : {
                "clusterTime" : Timestamp(1584955352, 1),
                "signature" : {
                        "hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
                        "keyId" : NumberLong(0)
                }
        },
        "operationTime" : Timestamp(1584955352, 1)
}

五、开启验证

在副本集内成员之间需要用keyFile认证,集群所有mongod和mongos实例使用内容相同的keyFile文件;由于启用了认证,需要建立一个管理员帐号,才能从远程登录。建立管理员帐户,利用管理员账户从远程登录后,需要建立一个可以操作某个数据库的用户,客户端就用这个用户访问数据库。

  • 1.建立管理员账户
use admin

db.createUser({
 user:"root",
 pwd:"123456",
 roles: [ { role: "root",db:"admin"}]
})

db.auth("root","123456")//认证该用户
  • 2.用openssl生成keyFile认证文件
openssl rand -base64 700 > mdb-keyfile.jks
#长度不能太长,否则会报如下错误,此处定义700长度:
#security key in /home/cluster/mongodb/conf/mdb-keyfile.jks has length 1368, must be between 6 and 1024 chars
  • 3.更改keyfile权限
chmod 600 mdb-keyfile.jks
  • 4.拷贝到其他主机
scp -P 22 mdb-keyfile.jks cluster@192.168.62.95:/home/cluster/mongodb/conf
scp -P 22 mdb-keyfile.jks cluster@192.168.62.37:/home/cluster/mongodb/conf
  • 5.配置mongodb.conf文件开启auth认证
#配置文件增加:
security:
  authorization: enabled
  keyFile: /home/cluster/mongodb/conf/mdb-keyfile.jks
  • 6.登陆
mongo 192.168.62.37:28017/admin -u root -p 123456
mongo 192.168.62.15:28017/admin -u root -p 123456
  • 7.连接字符串
mongodb://192.168.62.37:28017,192.168.62.15:28017/?replicaSet=rs0

六、常用操作语句

show dbs;显示所有存在的数据库
use test;进入数据库
db;显示当前所在数据库
show collections;显示当前数据库所有集合
//向当前数据库,students集合中插入一个学生文档
db.students.insert({"name":"孙悟空","age":18,"sex":"男"});
//向当前数据库,students集合中插入多个学生文档
db.students.insert([{"name":"紫霞","age":16,"sex":"女"},{"name":"牛魔","age":23,"sex":"男"}]);
db.students.find();查询当前数据库,students集合中所有的文档
db.students.find({"sex":"男"});查询当前数据库,students集合中符合条件的文档
db.students.find({"name":/牛/});模糊查询
db.students.find().count();查询当前数据库,students集合中所有的文档的总数
db.students.find().sort({"age":1});根据字段排序,1正序  -1倒序
db.students.update({"name":"牛魔"}, {$set:{"name":"牛魔魔"}});部分字段更新,默认只修改一条记录
db.students.updateMany({"sex":"男"}, {$set:{"sex":"男生"}});部分字段更新,修改多条记录
db.students.remove({"name":"牛魔魔"});删除符合条件的文档
db.students.drop();删除当前集合
db.dropDatabase();删除当前数据库
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 216,258评论 6 498
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,335评论 3 392
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 162,225评论 0 353
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,126评论 1 292
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,140评论 6 388
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,098评论 1 295
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,018评论 3 417
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 38,857评论 0 273
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,298评论 1 310
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,518评论 2 332
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,678评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,400评论 5 343
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 40,993评论 3 325
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,638评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,801评论 1 268
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 47,661评论 2 368
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,558评论 2 352

推荐阅读更多精彩内容