1)主节点唯一
主节点唯一,但是不固定(不确定的原因是:主节点挂了的话,会重新选举出一个主节点)。
2)大多数原则
大多数原则,即1/2原则,一个复制集集群中,如果有大于等于1/2的节点不可用的话,那么整个进群将不可写,只可读(注:实际上应该是投票权重的1/2。
3)从库无法写入
从库无法写入,使用root权限也不行,这一点与MySQL不同,MySQL从库不能写入,原因是设置了readOnly。
4)副本集可以自动进行容灾
主节点服务不可用,会自动选举出新的主节点。
1)数据节点-------主节点(Primary)
主节点负责数据的读写操作,并把写的操作记录到OpLog中(mongo隐藏的库local的oplog集合)
2)数据节点-------从节点(Secondary)
复制主节点的数据,备份容灾用,主节点挂掉,会重新选举出新的主节点,从节点无法进行写操作,即使拥有root权限也不行(不同于MySQL)
3)投票节点(Arbiter)
不负责数据的存储和复制,只负责投票。(注:理论上一个mongo复制集,可以有一个主节点,多个从节点,多个投票节点) 无法 升职为主节点。投票节点的存在是为了使复制集中的节点数量为奇数,这样保证在进行投票的时候不会出现票数相同的情况。如果添加了一个节点后,总节点数为偶数,那么就需要相应的增加一个投票节点。
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
解压安装包。
mkdir /usr/local/mongodb4.2.8
cd /usr/local/mongodb4.2.8
# 上传文件并解压
tar -xvf mongodb-linux-x86_64-amazon-4.2.8.tgz
# 重命名
mv mongodb-linux-x86_64-amazon-4.2.8 mongodb
创建配置文件。
cd /usr/local/mongodb4.2.8/mongodb && mkdir config && cd config
cat<<"EOF">mongodb.conf
bind_ip = 0.0.0.0
#bind_ip_all = true
# add in 3.6 和 bind_ip 互斥
port = 27017
# 数据目录
dbpath = /var/lib/mongodb/mongodb4.2.8
# 日志目录
logpath = /var/log/mongodb4.2.8.log
#数据是否故障恢复
journal = true
#复制集日志是以追加的方式进行
logappend = true
#是否后台启动
fork = true
auth = false
# 副本集启用认证的配置
#keyFile =
directoryperdb = true
storageEngine = wiredTiger
#wiredTigerCacheSizeGB = 1
#profile = 2
#slowms = 1000
#oplogSize = 100
# 副本集名称
#replSet = test
EOF
创建数据目录。
mkdir -pv /var/lib/mongodb/mongodb4.2.8
启动 mongodb。
yum -y install numactl.x86_64
numactl --interleave=all /usr/local/mongodb4.2.8/mongodb/bin/mongod -f /usr/local/mongodb4.2.8/mongodb/config/mongodb.conf
确认启动,通过ps命令可以看到以下进程,说明成功启动,如果启动失败可以通过/var/log/mongodb4.2.8.log 日志文件观察具体失败原因。 以下为命令和输出示例:
ps -ef | grep mongodb
root 92478 1 20 17:39 ? 00:00:01 /usr/local/mongodb4.2.8/mongodb/bin/mongod -f /usr/local/mongodb4.2.8/mongodb/config/mongodb.conf
/usr/local/mongodb4.2.8/mongodb/bin/mongo --host 127.0.0.1 --port 27017
#创建相关账号 3.x 或 4.x 需要提前创建账号才能使用 rs.add()
use admin
db.createUser({user:"root",pwd:"root",roles:[{role:"root",db:"admin"}]});
#验证账号密码
use admin
db.auth('root','root')
通过以上步骤我们就成功的启动了 3 个 MongoDB 实例。
副本集配置比较简单,主要关注两个参数 replSet (每个节点必须配置一致)和 keyFile (认证相关)。
任意一台服务器生成 keyfile 文件,用于副本集认证,然后传送到每台服务器。
cd /usr/local/mongodb4.2.8/mongodb/config
openssl rand -base64 741 > mongodb-keyfile
2. 注意修改权限,否则会报错。
```shell
chmod 600 mongodb-keyfile
权限未修改为 600 的报错如下输出: ACCESS permissions on xxx are too open
编辑每个实例的配置文件,修改 replSet 和 keyfile
vi /usr/local/mongodb4.2.8/mongodb/config/mongodb.conf
auth = true
replSet = myRepl
keyFile = /usr/local/mongodb4.2.8/mongodb/config/mongodb-keyfile
4. 重启 mongodb
```shell
/usr/local/mongodb4.2.8/mongodb/bin/mongod -f /usr/local/mongodb4.2.8/mongodb/config/mongodb.conf --shutdown
numactl --interleave=all /usr/local/mongodb4.2.8/mongodb/bin/mongod -f /usr/local/mongodb4.2.8/mongodb/config/mongodb.conf
加入副本集集群
#使用命令行,进入到主节点实例
/usr/local/mongodb4.2.8/mongodb/bin/mongo --host 127.0.0.1 --port 27017
#验证账号密码,获取权限
use admin
db.auth('root','root')
#初始化一个副本集
config = {_id: "myRepl", members: []} # _id 为副本集的名称
config.members.push({_id: 0, host: "192.168.2.5:27017", "priority": 2})
config.members.push({_id: 1, host: "192.168.2.6:27017", "priority": 1})
config.members.push({_id: 2, host: "192.168.2.7:27017", "priority": 1})
rs.initiate(config)
#查看副本集状态命令
rs.conf()
#加入secondary节点
#rs.add("192.168.2.6:27017")
#加入投票节点
#rs.addArb("192.168.2.7:27017")
#查看副本集状态
rs.status()
#重要且必须, secondary节点允许读取操作在当前节点进行,否则从节点无法复制主节点的数据
#进入secondary实例-从节点
/usr/local/mongodb4.2.8/mongodb/bin/mongo --host 127.0.0.1 --port 27017
#验证账号密码,获取权限
use admin
db.auth(‘root’,‘root’)
rs.slaveOk()
至此为止一个三节点的副本集已经搭建完成。
Navicat连接示例
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-gBSvvFFP-1594198368164)(C:\Users\Administrator\AppData\Roaming\Typora\typora-user-images\image-20200708103355034.png)]
## 测试
```sql
#主节点
use admin
db.auth('root','root')
use test
db.createCollection('user')
db.user.insert({'name':'james'})
#从节点
use admin
db.auth('root','root')
use test
show collections
db.user.find()
以下命令能帮助您更快的上手副本集。
查看oplog 大小
rs.printReplicationInfo() # 2.6+``db.getReplicationInfo()
查看延迟
db.printSlaveReplicationInfo()
查看副本集的状态
rs.status()
设置SECONDARY 为可读
rs.slaveOk() db.isMaster() rs.config()
增加副本集成员
rs.add()
删除副本集成员
rs.remove()
rs 帮助命令
rs.help()
使Primary 节点退化为
Secondary ,并在一段时间内不能参与选举。
rs.stepDown(time)
阻止选举,始终处于备份节点状态。比如主节点需要做一些维护,不希望其他成员选举为主节点,可以在每个备份节点上执行。强制他们出于备份节点状态。
rs.freeze(time)
在使用副本集的过程中,对于一些有较高频率碰到的问题,在此做了一些总结,用以帮助想要学习 MongoDB
副本集的小伙伴们少走弯路。
初始化节点的时候报错怎么办?
为什么使用奇数个数成员?
MongoDB 本身设计的就是一个可以跨 IDC 的分布式数据库,假设一种场景,偶数 8 节点,IDC 网络故障发生分裂,这两个分裂后的 IDC 各持有 4 个节点,因为投票数未超过半数,所以无法选举出新 Primary。
仲裁节点作用?
仲裁节点并不需要太多系统资源,也并不持有数据本身,而是参与投票。 投票选举机制,根据数据最后操作、更新时间戳等判定,若有两方都为最新,且票数相等,此环节需要等待若干分钟。仲裁节点打破这个僵局。当节点数目为奇数时,可以不需要。 当节点数目为偶数个时,需要部署一个仲裁节点,否则偶数个节点,当主节点挂了后,其他节点会变为只读。
将一台节点移除副本集,并且注释掉相关配置文件后,重启启动该节点登录后会有REMOVED 字样,如何去掉?
登录后在 local
数据库下查找 db.system.replset.find()
,如果还有之前的副本集相关记录,删掉即可,db.system.replset.remove({})
。
什么情况下会出现 OTHER 状态?
当使用 rs.reconfig
重新对副本集进行初始化的时候,SECONDARY
和 ARBITER
节点会出现 OTHER
状态。
对于连接 MongoDB 的客户端都是外网的情况,如何配置副本级?
初始化副本级的时候 host 必须为外网 IP。