目录
4.进入mongo,创建一个包含三个成员节点的MongoDB复制集,每个节点都运行在本地主机上,并监听不同的端口号。这样可以提高数据的冗余性和可用性。
5.将当前的MongoDB实例初始化为一个复制集,并根据配置信息cfg来配置复制集的成员节点。在执行该命令后,当前的MongoDB实例将成为复制集的主节点,并开始接受和处理写操作。
4.模拟当mongodb1实例故障时,由于mongodb2实例不参与选举,因此mongodb3也就是27019将会成为新的主节点
4.将当前的MongoDB实例初始化为一个复制集,并根据配置信息cfg来配置复制集的成员节点。在执行该命令后,当前的MongoDB实例将成为复制集的主节点,并开始接受和处理写操作。
7.启动mongodb1和mongodb2,依旧是27017为主服务器
一、基本概念
- 文档(document)是MongoDB中数据的基本单元,非常类似于关系型数据库系统中的行(记录)但是比行存储的数据要复杂的多。
- 集合(collection)就是一组文档组成,如果说MongoDB中的文档类似于关系型数据库中的行,那么集合就如同数据表。
- MongoDB的单个实例可以容纳多个独立的数据库,每一个数据库都有自己的集合和权限。
二、 mongodb安装部署
1、关闭防火墙和selinux
[root@localhost ~] iptables -F
[root@localhost ~] setenforce 0
[root@localhost ~] systemctl stop firewalld
2、指定一个进程同一时间最多可开启的文件数
[root@localhost ~] ulimit -n
1024
[root@localhost ~] ulimit -n 65535
[root@localhost ~] ulimit -n
65535
3、用户最多可开启的进程数目
[root@localhost ~] ulimit -u
7183
[root@localhost ~] ulimit -u 65535
[root@localhost ~] ulimit -u
65535
4.安装版本下载地址,并优化命令
[root@localhost ~] wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.0.6.tgz
[root@localhost ~] tar xf mongodb-linux-x86_64-rhel70-4.0.6.tgz
[root@localhost ~] mv mongodb-linux-x86_64-rhel70-4.0.6 /usr/local/mongodb
[root@localhost ~] ln -s /usr/local/mongodb/bin/* /bin/
5、创建数据目录,日志文件及目录并创建相应配置文件
[root@localhost ~] mkdir -p /data/mongodb1 #数据目录
[root@localhost ~] mkdir -p /data/logs/mongodb #日志目录
[root@localhost ~] touch /data/logs/mongodb/mongodb1.log #日志文件
[root@localhost ~] cd /usr/local/mongodb/
[root@localhost mongodb] mkdir conf #配置文件目录
[root@localhost mongodb] vim conf/mongodb1.conf #配置文件
port=27017 #监听端口
dbpath=/data/mongodb1 #指定数据目录
logpath=/data/logs/mongodb/mongodb1.log #指定日志文件路径
logappend=true #允许写入日志
fork=true #允许创建子进程
maxConns=5000 #最大连接数
storageEngine=mmapv1 #存储引擎
6、启动MongoDB数据库,-f指定配置文件
[root@localhost mongodb]/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/mongodb1.conf
about to fork child process, waiting until server is ready for connections.
forked process: 8710
child process started successfully, parent exiting
[root@localhost mongodb] netstat -lnpt |grep mongod
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 8710/mongod
[root@localhost mongodb] ps aux |grep mongod |grep -v grep
root 8710 1.5 5.1 1501404 96244 ? Sl 18:22 0:00 /usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/mongodb1.conf
7、设置开机自动启动
[root@localhost mongodb] vim /etc/rc.local
rm -f /data/mongodb1/mongod.lock
mongod -f /usr/local/mongodb/conf/mongodb1.conf
8、连接数据库
[root@localhost mongodb] mongo
> show dbs
admin 0.078GB
config 0.078GB
local 0.078GB
> exit
bye
[root@localhost mongodb]
- admin:从权限的角度来看,这是"root"数据库。要是将一个用户添加到这个数据库,这个用户自动继承所有数据库的权限。一些特定的服务器端命令也只能从这个数据库运行,比如列出所有的数据库或者关闭服务器。
- local:这个数据永远不会被复制,可以用来存储限于本地单台服务器的任意集合。
- config:当Mongo用于分片设置时,config数据库在内部使用,用于保存分片的相关信息。
三、mongodb复制群集群部署
1.配置4个mongodb
[root@localhost mongodb] vim /usr/local/mongodb/conf/mongodb1.conf
port=27017 #监听端口
dbpath=/data/mongodb1 #指定数据目录
logpath=/data/logs/mongodb/mongodb1.log #指定日志文件路径
logappend=true #允许写入日志
fork=true #允许创建子进程
maxConns=5000 #最大连接数
storageEngine=mmapv1 #存储引擎
slowms=1
profile=1
replSet=copygroup #名字随意取
[root@localhost mongodb] cp /usr/local/mongodb/conf/mongodb1.conf /usr/local/mongodb/conf/mongodb2.conf
[root@localhost mongodb] vim /usr/local/mongodb/conf/mongodb2.conf
port=27018 #监听端口
dbpath=/data/mongodb2 #指定数据目录
logpath=/data/logs/mongodb/mongodb2.log #指定日志文件路径
logappend=true #允许写入日志
fork=true #允许创建子进程
maxConns=5000 #最大连接数
storageEngine=mmapv1 #存储引擎
slowms=1
profile=1
replSet=copygroup #名字随意取
3.4同理
创建配置文件目录、日志文件目录、日志文件路径
[root@localhost mongodb] mkdir /data/mongodb{2..4} -p
[root@localhost mongodb] mkdir /data/logs/mongodb -p
[root@localhost mongodb] touch /data/logs/mongodb/mongodb{2..4}.log
[root@localhost mongodb] chmod 777 /data/logs/mongodb/mongodb*
[root@localhost mongodb] ll /data/logs/mongodb/mongodb*
-rwxrwxrwx. 1 root root 10147 7月 4 18:41 /data/logs/mongodb/mongodb1.log
-rwxrwxrwx. 1 root root 0 7月 4 18:43 /data/logs/mongodb/mongodb2.log
-rwxrwxrwx. 1 root root 0 7月 4 18:43 /data/logs/mongodb/mongodb3.log
-rwxrwxrwx. 1 root root 0 7月 4 18:43 /data/logs/mongodb/mongodb4.log
2.创建启动脚本
[root@localhost mongodb] vim /etc/init.d/mongodb
#!/bin/bash
INSTANCE=$1
ACTION=$2
case "$ACTION" in
'start')
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/"$INSTANCE".conf;;
'stop')
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/"$INSTANCE".conf --shutdown;;
'restart')
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/"$INSTANCE".conf --shutdown
/usr/local/mongodb/bin/mongod -f /usr/local/mongodb/conf/"$INSTANCE".conf;;
esac
[root@localhost mongodb] chmod +x /etc/init.d/mongodb
3.启动mongdb1.、2、3、4
[root@localhost mongodb] /etc/init.d/mongodb mongodb1 stop
killing process with pid: 8710
[root@localhost mongodb] /etc/init.d/mongodb mongodb1 start
child process started successfully, parent exiting
[root@localhost mongodb] /etc/init.d/mongodb mongodb2 start
child process started successfully, parent exiting
[root@localhost mongodb] /etc/init.d/mongodb mongodb3 start
child process started successfully, parent exiting
[root@localhost mongodb] /etc/init.d/mongodb mongodb4 start
child process started successfully, parent exiting
[root@localhost mongodb] netstat -lnpt|grep mongod
tcp 0 0 127.0.0.1:27017 0.0.0.0:* LISTEN 9160/mongod
tcp 0 0 127.0.0.1:27018 0.0.0.0:* LISTEN 9189/mongod
tcp 0 0 127.0.0.1:27019 0.0.0.0:* LISTEN 9218/mongod
tcp 0 0 127.0.0.1:27020 0.0.0.0:* LISTEN 9247/mongod
4.进入mongo,创建一个包含三个成员节点的MongoDB复制集,每个节点都运行在本地主机上,并监听不同的端口号。这样可以提高数据的冗余性和可用性。
[root@mongodb ~] mongo
crushlinux:PRIMARY> rs.help() #查看复制集帮助指令
> cfg={"_id":"copygroup","members":[{"_id":0,"host":"127.0.0.1:27017"},{"_id":1,"host":"127.0.0.1:27018"},{"_id":2,"host":"127.0.0.1:27019"}]}
{
"_id" : "copygroup",
"members" : [
{
"_id" : 0,
"host" : "127.0.0.1:27017"
},
{
"_id" : 1,
"host" : "127.0.0.1:27018"
},
{
"_id" : 2,
"host" : "127.0.0.1:27019"
}
]
}
5.将当前的MongoDB实例初始化为一个复制集,并根据配置信息cfg
来配置复制集的成员节点。在执行该命令后,当前的MongoDB实例将成为复制集的主节点,并开始接受和处理写操作。
> rs.initiate(cfg)
{
"ok" : 1,
"operationTime" : Timestamp(1688469362, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1688469362, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
6.获取复制集状态
copygroup:PRIMARY> rs.status()
"members" : [
{
"_id" : 0,
"name" : "127.0.0.1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1434,
"optime" : {
"ts" : Timestamp(1688469415, 1),
"t" : NumberLong(1)
{
"_id" : 1,
"name" : "127.0.0.1:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 54,
"optime" : {
"ts" : Timestamp(1688469415, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1688469415, 1),
"t" : NumberLong(1)
{
"_id" : 2,
"name" : "127.0.0.1:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"uptime" : 54,
"optime" : {
"ts" : Timestamp(1688469415, 1),
"t" : NumberLong(1)
},
"optimeDurable" : {
"ts" : Timestamp(1688469415, 1),
"t" : NumberLong(1)
},
health:1 表示状态健康 state:1 表示为主服务器
health: 0 表示宕机 state:2 表示为从服务器
四、测试
1.模拟故障机,杀掉27017端口
[root@localhost mongodb] kill -9 9160 #杀掉27017
[root@localhost mongodb] mongo --port 27018
copygroup:PRIMARY>
#发现27018 变成了PRIMARY(主服务器)
copygroup:PRIMARY> rs.status()
"name" : "127.0.0.1:27017",
"health" : 0,
"state" : 8,
"name" : "127.0.0.1:27018",
"health" : 1,
"state" : 1, #主服务器
2.开启27017端口
[root@localhost mongodb] /etc/init.d/mongodb mongodb1 start
about to fork child process, waiting until server is ready for connections.
forked process: 11306
child process started successfully, parent exiting
[root@localhost mongodb] mongodb --port 27018
copygroup:PRIMARY> rs.status()
"name" : "127.0.0.1:27017",
"health" : 1,
"state" : 2,
"name" : "127.0.0.1:27018",
"health" : 1,
"state" : 1,
#27017变成从服务器
3.手动切换主实例
[root@localhost mongodb] mongo --port 27018
copygroup:PRIMARY> rs.freeze(30) #27018暂停30秒选举
copygroup:PRIMARY> rs.stepDown(60,30) #修改成从节点
2023-07-04T19:37:04.203+0800 I NETWORK [js] trying reconnect to 127.0.0.1:27018 failed
2023-07-04T19:37:04.204+0800 I NETWORK [js] reconnect 127.0.0.1:27018 ok
copygroup:SECONDARY> rs.status()
"name" : "127.0.0.1:27017",
"health" : 1,
"state" : 1, #27017变成主服务器
"stateStr" : "PRIMARY",
"name" : "127.0.0.1:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
4.模拟当mongodb1实例故障时,由于mongodb2实例不参与选举,因此mongodb3也就是27019将会成为新的主节点
[root@localhost mongodb] mongo --port 27017
copygroup:SECONDARY> rs.freeze(120) #不让27017选举
[root@localhost mongodb] ps aux |grep mongod
root 9189 0.5 5.2 4007480 98500 ? Sl 18:53 0:20 /usr/local/mongodb/bin/mo
root 9218 0.5 3.5 3943816 65808 ? Sl 18:53 0:20 /usr/local/mongodb/bin/mo
root 9247 0.5 3.5 1207568 65232 ? Sl 18:53 0:20 /usr/local/mongodb/bin/mo
root 12276 0.7 5.0 3877244 94916 ? Sl 19:49 0:00 /usr/local/mongodb/bin/mo
root 12374 0.0 0.0 112828 980 pts/0 R+ 19:49 0:00 grep --color=auto mongod
[root@localhost mongodb] kill -9 9189 #杀掉27018
[root@localhost mongodb] mongo --port 27017
copygroup:SECONDARY> rs.status()
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"name" : "127.0.0.1:27018",
"health" : 0,
"state" : 8,
"name" : "127.0.0.1:27019",
"health" : 1,
"state" : 1, #27019变成了主服务器
"stateStr" : "PRIMARY",
五、复制集选举原理
1、复制的原理
MongoDB复制是基于操作日志oplog实现,oplog相当于mysql中的二进制日志,只记录数据发生的改变操作。
2、选举的原理
(1)节点类型:标准节点,被动节点,仲裁节点
- 只有标准节点可能被选举为活跃(主)节点,有选举权
- 被动节点有完整副本,不可能成为活跃节点,有选举权
- 仲裁节点不复制数据,不可能成为活跃节点,只有选举权
(2)标准节点与被动节点的区别
priority值高者是标准节点,低者则为被动节点
(3)选举规则
票数高者获胜,priority是优先权0-1000值,相当于额外增加0-1000的票数。
选举结果:票数高者获胜;若票数相同,数据新者获胜。
3.重新定义集群,将27020节点设置为仲裁节点
[root@localhost mongodb] /etc/init.d/mongodb mongodb1 stop
[root@localhost mongodb] /etc/init.d/mongodb mongodb2 stop
[root@localhost mongodb] /etc/init.d/mongodb mongodb3 stop
[root@localhost mongodb] /etc/init.d/mongodb mongodb4 stop
[root@localhost mongodb] /etc/init.d/mongodb mongodb1 start
[root@localhost mongodb] /etc/init.d/mongodb mongodb2 start
[root@localhost mongodb] /etc/init.d/mongodb mongodb3 start
[root@localhost mongodb] /etc/init.d/mongodb mongodb4 start
[root@localhost mongodb] mongo
copygroup:PRIMARY> cfg={"_id":"copygroup","protocolVersion":1,"members":[{"_id":0,"host":"127.0.0.1:27017","priority":100}, {"_id":1,"host":"127.0.0.1:27018","priority":100}, {"_id":2,"host":"127.0.0.1:27019","priority":0}, {"_id":3,"host":"127.0.0.1:27020","arbiterOnly":true}]} #arbiterOnly代表为仲裁节点
{
"_id" : "copygroup",
"protocolVersion" : 1,
"members" : [
{
"_id" : 0,
"host" : "127.0.0.1:27017",
"priority" : 100
},
{
"_id" : 1,
"host" : "127.0.0.1:27018",
"priority" : 100
},
{
"_id" : 2,
"host" : "127.0.0.1:27019",
"priority" : 0
},
{
"_id" : 3,
"host" : "127.0.0.1:27020",
"arbiterOnly" : true
}
]
}
4.将当前的MongoDB实例初始化为一个复制集,并根据配置信息cfg
来配置复制集的成员节点。在执行该命令后,当前的MongoDB实例将成为复制集的主节点,并开始接受和处理写操作。
copygroup:PRIMARY> rs.reconfig(cfg)
{
"ok" : 1,
"operationTime" : Timestamp(1688472419, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1688472419, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
copygroup:PRIMARY> rs.status()
"name" : "127.0.0.1:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"name" : "127.0.0.1:27018",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"name" : "127.0.0.1:27019",
"health" : 1,
"state" : 2,
"stateStr" : "SECONDARY",
"name" : "127.0.0.1:27020",
"health" : 1,
"state" : 7,
"stateStr" : "ARBITER", #仲裁节点
5.获取主节点信息
copygroup:PRIMARY> rs.isMaster()
{
"hosts" : [ #标准节点
"127.0.0.1:27017",
"127.0.0.1:27018"
],
"passives" : [ #被动节点
"127.0.0.1:27019"
],
"arbiters" : [ #仲裁节点
"127.0.0.1:27020"
],
6.模拟mongodb1和mongodb2故障
[root@localhost mongodb] /etc/init.d/mongodb mongodb1 stop
killing process with pid: 13105
[root@localhost mongodb] /etc/init.d/mongodb mongodb2 stop
killing process with pid: 13163
[root@localhost mongodb] mongo --port 27019
copygroup:SECONDARY> rs.status()
"name" : "127.0.0.1:27017",
"health" : 0,
"state" : 8, #故障
"stateStr" : "(not reachable/healthy)",
"name" : "127.0.0.1:27018",
"health" : 0,
"state" : 8, #故障
"stateStr" : "(not reachable/healthy)",
"name" : "127.0.0.1:27019",
"health" : 1,
"state" : 2, #从服务器
"stateStr" : "SECONDARY", #被动节点不能成为活跃节点
"name" : "127.0.0.1:27020",
"health" : 1,
"state" : 7, #不参与选举
"stateStr" : "ARBITER",
3.4都不会去切换为主服务器,因为不参加选举