linux上使用yum部署mongodb4.2+分片副本

时间:2022-12-14 19:02:57

系统配置

Linux是有文件句柄限制的,而且默认不是很高,一般都是1024,作为一台生产服务器,其实很容易就达到这个数量。

为防止服务因too many open files错误出现宕机,这里需要对linux系统句柄数进行调整。

## 临时调整,系统重启即失效
ulimit -SHn 65535
## 永久调整,编辑 /etc/security/limits.conf 文件,最后行添加:
## 重新登录验证,或reboot后验证。
root soft nofile 65535
root hard nofile 65535
* soft nofile 65535
* hard nofile 65535

MongoDB分片

下图展示了在MongoDB中使用分片集群结构分布:

linux上使用yum部署mongodb4.2+分片副本

上图中主要有如下所述三个主要组件:

  • Shard: 用于存储实际的数据块,实际生产环境中一个shard server角色可由几台机器组个一个replica set承担,防止主机单点故障。
  • Config Server: mongod实例,存储了整个 ClusterMetadata,其中包括 chunk信息。
  • Query Routers: 前端路由,客户端由此接入,且让整个集群看上去像单一数据库,前端应用可以透明使用。

集群信息

mongodb-1:10.x.x.56 mongodb-2:10.x.x.57 mongodb-3:10.x.x.58 功能
mongos:23000 mongos:23000 mongos:23000 路由服务,负责客户端的连接,并把任务分给shards,然后收集结果
config server:24000 config server:24000 config server:24000 配置服务器,保存集群的元数据
shard1:主:25001 shard2:主:25002 shard3:主:25003 分片:接受读写
shard2:从:25002 shard3:从:25003 shard1:从:25001 副本集:备份数据
shard3:仲裁:25003 shard1:仲裁:25001 shard2:仲裁:25002

服务部署流程

安装mongodb

安装 mongodb到node1,2,3节点(以下操作node1,2,3各节点上都要执行)。

配置mongo的yum源:

# cat /etc/yum.repos.d/mongodb-org.repo
[mongodb-org]
name=MongoDB Repository
baseurl=http://mirrors.aliyun.com/mongodb/yum/redhat/7Server/mongodb-org/4.2/x86_64/
gpgcheck=0
enabled=1
yum clean all
yum makecache
yum update
# 查找对应包的版本
yum list mongodb --showduplicates | sort -r
yum install -y mongodb-org

创建mongo相关目录

在node1,node2,node3创建一个mongo目录(以下操作node1,2,3各节点上都要执行)chunk信息。

# 在mongo文件夹底下创建mongos, config, shard1,shard2,shard3五个文件夹,命令如下:
mkdir -p /opt/mongo/{mongos,config,shard1,shard2,shard3}
# 在五个文件夹中分别对应三个子目录用来存 data,log, run
mkdir /opt/mongo/mongos/{data,log,run}
mkdir /opt/mongo/config/{data,log,run}
mkdir /opt/mongo/shard1/{data,log,run}
mkdir /opt/mongo/shard2/{data,log,run}
mkdir /opt/mongo/shard3/{data,log,run}

创建密钥目录文件

在keyfile身份验证中,副本集中的每个mongod实例都使用keyfile的内容作为共享密码,只有具有正确密钥文件的mongod或者mongos实例可以连接到副本集。密钥文件的内容必须在6到1024个字符之间,并且在unix/linux系统中文件所有者必须有对文件至少有读的权限。

## 在node1,node2,node3创建密钥目录
mkdir -p /opt/mongo/keys
## 生成密钥文件,node1上执行
openssl rand -base64 756 > /opt/mongo/keys/mongoKeyFile.file
## 拷贝密钥文件到node2和node3
scp /opt/mongo/keys/mongoKeyFile.file root@10.x.x.x:/opt/mongo/keys/

配置服务

在node1,node2,node3先创建config server(以下操作node1,2,3各节点上都要执行)

# cat /opt/mongo/config/mongod.conf
systemLog:
  destination: file
  logAppend: true
  path: /opt/mongo/config/log/mongod.log
storage:
  dbPath: /opt/mongo/config/data
  journal:
    enabled: true
processManagement:
  fork: true
  pidFilePath: /opt/mongo/config/run/mongod.pid
net:
  port: 24000
  bindIp: 0.0.0.0
replication:
  replSetName: config
sharding:
  clusterRole: configsvr
security:
  keyFile: /opt/mongo/keys/mongoKeyFile.file
  authorization: enabled

依次启动所有的mongo config server服务:

mongod --config /opt/mongo/config/mongod.conf

测试登录node1,2,3中一台的config server,以创建配置并激活,以登录node1中的mongo config server为例):

# version 4.2+
mongo --port 24000

运行配置(这里一个节点上执行就可)

(1) 在刚刚登陆的节点中执行以下命令

config = {
   _id : "config",
    members : [
        {_id : 0, host : "10.x.x.56:24000" },
        {_id : 1, host : "10.x.x.57:24000" },
        {_id : 2, host : "10.x.x.58:24000" }
    ]
}

注意:members数组中改为自己节点的ip,_id: config 必须与前面的 config server配置文件中的 replSetName: config 一致。

(2) 初始化副本集配置

rs.initiate(config)

(3) 查看分区状态

rs.status()

配置分片和副本集

第一个分片和副本集

给node1,2,3 各创建第一个分片和副本集(以下操作node1,2,3各节点上都要执行)。

# cat /opt/mongo/shard1/mongod.conf
systemLog:
  destination: file
  logAppend: true
  path: /opt/mongo/shard1/log/mongod.log
storage:
  dbPath: /opt/mongo/shard1/data
  journal:
    enabled: true
processManagement:
  fork: true
  pidFilePath: /opt/mongo/shard1/run/mongod.pid
net:
  port: 25001
  bindIp: 0.0.0.0
replication:
  replSetName: shard1
sharding:
  clusterRole: shardsvr
security:
  keyFile: /opt/mongo/keys/mongoKeyFile.file
  authorization: enabled

依次启动所有的shard1 server:

mongod --config /opt/mongo/shard1/mongod.conf

登陆任意一台shard1服务器(希望哪一台机器是主,就登录到那一台机器上,这里是准备将node1设为shard1的主节点),初始化副本集(以下内容在一个节点上执行)

mongo --port 25001

在登陆的节点上使用admin数据库:

use admin
## 定义副本集配置,执行下面的内容
config = {
	_id : "shard1",
	 members : [
		 {_id : 0, host : "10.x.x.56:25001" },
		 {_id : 1, host : "10.x.x.57:25001" },
		 {_id : 2, host : "10.x.x.58:25001" }
	 ]
 }
 ## 初始化副本集配置,返回{"OK" : 1}表示成功
 rs.initiate(config)
 ## 查看分区状态
 rs.status()

第二个分片和副本集

给node1,2,3 各创建第二个分片和副本集(以下操作node1,2,3各节点上都要执行)。

cat > /opt/mongo/shard2/mongod.conf << EOF
systemLog:
  destination: file
  logAppend: true
  path: /opt/mongo/shard2/log/mongod.log
storage:
  dbPath: /opt/mongo/shard2/data
  journal:
    enabled: true
processManagement:
  fork: true
  pidFilePath: /opt/mongo/shard2/run/mongod.pid
net:
  port: 25002
  bindIp: 0.0.0.0
replication:
  replSetName: shard2
sharding:
  clusterRole: shardsvr
security:
  keyFile: /opt/mongo/keys/mongoKeyFile.file
  authorization: enabled
EOF

依次启动所有的shard2 server:

mongod --config /opt/mongo/shard2/mongod.conf

登陆任意一台shard2服务器(希望哪一台机器是主,就登录到那一台机器上,这里是准备将node2设为shard2的主节点),初始化副本集(以下操作在单节点上执行)

mongo --port 25002

使用admin数据库:

use admin
## 定义副本集配置,注意改为自己节点的ip
config = {
	_id : "shard2",
	 members : [
		 {_id : 0, host : "10.x.x.57:25002" },
		 {_id : 1, host : "10.x.x.56:25002" },
		 {_id : 2, host : "10.x.x.58:25002" }
	 ]
 }
 ## 初始化副本集配置,返回{"OK" : 1}表示成功
 rs.initiate(config)
 ## 查看分区状态
 rs.status()

第三个分片和副本集

给node1,2,3 各创建第三个分片和副本集(以下操作node1,2,3各节点上都要执行)。

cat > /opt/mongo/shard3/mongod.conf << EOF
systemLog:
  destination: file
  logAppend: true
  path: /opt/mongo/shard3/log/mongod.log
storage:
  dbPath: /opt/mongo/shard3/data
  journal:
    enabled: true
processManagement:
  fork: true
  pidFilePath: /opt/mongo/shard3/run/mongod.pid
net:
  port: 25003
  bindIp: 0.0.0.0
replication:
  replSetName: shard3
sharding:
  clusterRole: shardsvr
security:
  keyFile: /opt/mongo/keys/mongoKeyFile.file
  authorization: enabled
EOF

依次启动所有的shard3 server:

mongod --config /opt/mongo/shard3/mongod.conf

登陆任意一台shard3服务器(希望哪一台机器是主,就登录到那一台机器上,这里是准备将node3设为shard3的主节点),初始化副本集(以下操作在单节点上执行)

mongo --port 25003

使用admin数据库:

use admin
## 定义副本集配置,注意改为自己节点的ip
config = {
	_id : "shard3",
	 members : [
		 {_id : 0, host : "10.x.x.58:25003" },
		 {_id : 1, host : "10.x.x.56:25003" },
		 {_id : 2, host : "10.x.x.57:25003" }
	 ]
 }
 ## 初始化副本集配置,返回{"OK" : 1}表示成功
 rs.initiate(config)
 ## 查看分区状态
 rs.status()

配置 mongos 进程

安装配置 mongos 进程, 给node1, 2,3各创建目录(以下操作node1,2,3各节点上都要执行)。

cat > /opt/mongo/mongos/mongod.conf << EOF

systemLog:
  destination: file
  logAppend: true
  path: /opt/mongo/mongos/log/mongod.log
processManagement:
  fork: true
  pidFilePath: /opt/mongo/mongos/run/mongod.pid
net:
  port: 23000
  bindIp: 0.0.0.0
sharding:
  configDB: config/10.x.x.56:24000,10.x.x.57:24000,10.x.x.58:24000
security:
  keyFile: /opt/mongo/keys/mongoKeyFile.file

依次启动所有的路由服务器:

mongos --config /opt/mongo/mongos/mongod.conf

登录其中的一台路由节点,手动启用分片(以下操作选用一台节点,我用node3):

mongo --port 23000

添加分片到mongos(注意修改自己节点的ip):

sh.addShard("shard1/10.x.x.56:25001,10.x.x.57:25001,10.x.x.58:25001")
sh.addShard("shard2/10.x.x.57:25002,10.x.x.56:25002,10.x.x.58.25002")
sh.addShard("shard3/10.x.x.58:25003,10.x.x.56:25003,10.x.x.57:25003")

设置slave可读(在命令行中生效一次),如果配置从接到可读,那么是连接客户端指定的:

## 命令在node3中执行一次即可
rs.secondaryOk()

常用命令

mongo服务相关

## 停止服务
## 如系统没有killall命令,请执行:yum install psmisc -y
killall mongod
killall mongos
## 启动服务,在每个节点上一条一条启动:
mongod --config /opt/mongo/config/mongod.conf
mongod --config /opt/mongo/shard1/mongod.conf
mongod --config /opt/mongo/shard2/mongod.conf
mongod --config /opt/mongo/shard3/mongod.conf
mongos --config /opt/mongo/mongos/mongod.conf

创建库并开启分片功能

## 创建库
use mybike
## 创建 bikes集合
db.createCollection("bikes")
## 切换到admin库,再指定某个库启用分片
use admin
## 对mybike这个数据库开启分片功能
db.runCommand({"enablesharding":"mybike"})
## 对mybike数据库下的bikes集合按id的hash进行分片
db.runCommand({"shardcollection":"mybike.bikes","key":{_id:'hashed'}})
## 又切换回 mybike库
use mybike
## 切换到 mybike库,向bikes集合中插入数据
db.bikes.insert(   {"status": 1, "loc": [28.189153,112.960318],"qrcode":""}   )
db.bikes.insert(   { "status": 1, "loc": [28.189155,112.960318],"qrcode":""}   )
db.bikes.insert(   {"status": 1, "loc": [28.189159,112.960318],"qrcode":""}   )
db.bikes.insert(   {"status": 1, "loc": [28.189163,112.960318],"qrcode":""}   )
## 在mongos 进程中查询得到的结果是所有分片要满足条件的结果
mongo --port 23000 -u "admin" -p "passwd" --authenticationDatabase "admin"
## 查看所有库
show dbs
## 使用mybike库
use mybike
## 查看mybike库里面集合
show collections
## 查询集合里面数据
db.bikes.find()

对现有集合开启分片功能

可参考MongoDB 对现有集合进行分片 操作方法

普通账号创建和授权

## 先进入/创建库
use tsp-prod
## 创建tsp-prod账户对tsp-prod读写权限账户 
db.createUser(
  {
    user: "tsp-prod",
    pwd: "test123",
    roles: [ { role: "readWrite", db: "tsp-prod" } ]
  }
);
## 删除账户
use tsp-prod
db.dropUser("tsp-prod")
## 删除当前库的所有用户,慎用
db.dropAllUser()

参考教程