单实例Mongo升级为副本集

背景

因为是做短信业务的,随着公司业务增加,数据库压力也日益增加,目前数据量在70亿左右,Mongo只存储一周内的数据,数据量将近1亿左右。之前想要节省成本,所以一直都是单实例。随着接入客户日益增多,每天短信发送量也开始大幅度增加,最担心的就是过节假日,一直比较担心如果Mongo突然挂了,哈 哈!那就是面向死亡编程了。

纠结

经过几次讨论最终决定采用Mongo副本集读写分离处理,于是开始了服务改造。

准备

  • 已经部署好Mongo的机器数台服务器(192.168.0.101、192.168.0.102、192.168.0.103、192.168.0.104),安装Mongo参考:Linux安装Mongo
  • 机器说明:两台Mongo为从库,一台只负责投票节点不处理数据节点(192.168.0.104)

升级

秘钥文件

通过keyfile身份验证,副本集中的每个mongod实例都将密钥文件的内容用作共享密码,以对部署中的其他成员进行身份验证。只有具有正确密钥文件的mongod个实例可以加入副本集。密钥文件的内容长度必须在 6 到 1024 个字符之间,并且副本集的所有成员都必须相同。

openssl rand -base64 756 > /key/mongodb-keyfile
chmod 400 /key/mongodb-keyfile

将密钥文件复制到承载副本集成员的每个服务器上。确保运行mongod实例的用户是文件的所有者,并且可以访问密钥文件。

修改每台服务Mongo配置

首先停止单实例Mongo(命令:systemctl stop mongod),修改mongo配置文件 /etc/mongod.conf中的net、security、replication配置信息

net:
  port: 27017
  bindIp: 0.0.0.0  # 允许所有ip远程连接Mongo

security:
  authorization: enabled # 用户只能访问已为其授予特权的数据库资源和操作。
  keyFile: /key/mongodb-keyfile # 秘钥文件路径

replication:
  replSetName: "S1" # 副本集名称
  enableMajorityReadConcern: false # 以为有投票节点,禁用该功能以防止存储高速缓存压力使部署无法固定。

启动Mongo

使用命令(systemctl start mongo),进入mongo (希望作为主节点的Mongo),执行处理化副本集配置

rs.initiate( {
   _id : "s1",
   members: [
      { _id: 0, host: "192.168.0.101:27017" },
      { _id: 1, host: "192.168.0.102:27017" },
      { _id: 2, host: "192.168.0.103:27017" },
      { _id: 3, host: "192.168.0.104:27017",arbiterOnly:true },
   ]
})

查看副本集配置,升级完成(远程连接查看)

rs.conf();

临时成员添加副本集中

rs.add( { host: "192.168.0.105:27017", priority: 0, votes: 0 } )

注:

当新添加的辅助节点的votespriority设置大于零时,在其初始同步期间,即使辅助节点不能提供读取或成为主节点,因为其数据仍不一致,所以该辅助节点仍会计为有表决权的成员。

这可能导致大多数投票成员在线但无法选举主要成员的情况。为避免这种情况,请考虑首先使用priority :0votes :0添加新的辅助服务器。然后,一旦成员已转换为SECONDARY状态,请使用rs.reconfig()更新其优先级和投票。

如果rs.conf()返回192.168.0.105:27017的配置文档作为members数组中的第五个元素,以将其优先级更新并投票给1,请使用以下操作序列

var cfg = rs.conf();
cfg.members[4].priority = 1
cfg.members[4].votes = 1
rs.reconfig(cfg)

异常问题

一、秘钥文件读取授权失败异常,造成启动失败

{"t":{"$date":"2020-10-17T14:38:26.085+08:00"},"s":"I",  "c":"ACCESS",   "id":20254,   "ctx":"main","msg":"Read security file failed","attr":{"error":{"code":30,"codeName":"InvalidPath","errmsg":"Error reading file /key/mongodb-keyfile: Permission denied"}}}

解决方案:

原来想着是不是权限太小,于是直接授权 777 权限发现直接报 file Permission too open 错误,所以直接扩大权限方案错误。

1、默认情况下,MongoDB 使用mongod用户帐户运行。创建后,将目录的所有者和组设置为mongod

sudo chown -R mongod:mongod /key/mongodb-keyfile

2、按照官方文档给出的只要修改文件组即可读取成功,但是不幸的是仍然读取文件失败,通过各种搜索资料最后在Rad Hat linux官方目录权限文档才找到最终解决方案,需要需改SELinux策略配置

chcon system_u:object_r:mongod_var_lib_t:s0 /key/mongodb-keyfile

二、读取秘钥文件too open 错误

解决方案:

1、因为在 UNIX 系统上,密钥文件不得具有组或世界权限。在 Windows 系统上,不检查密钥文件权限。所以只需开放读权限,权限不允许过大

chmod 400 /key/mongodb-keyfile

参考文档:

https://docs.mongodb.com/manual/

https://stackoverflow.com/questions/28251531/permission-denied-to-read-file-owned-by-user

https://access.redhat.com/documentation/en-us/red_hat_enterprise_linux/6/html/security-enhanced_linux/chap-security-enhanced_linux-selinux_contexts

猜你喜欢

转载自blog.csdn.net/qq_31150503/article/details/109118459