mongodb介绍:
是最常用的nosql数据库,在数据库排名中已经上升到了前六。这篇文章介绍如何搭建高可用的mongodb(分片+副本)集群。
环境准备
系统系统 BC 21.10
三台服务器 :192.168.123.247/248/249
安装包:
mongodb-linux-x86_64-rhel8-7.0.14.tgz
(截止2024年10月11日星期五次新版)
mongosh-2.3.1-linux-x64.tgz
服务器规划
服务器247 | 服务器248 | 服务器249 |
---|---|---|
mongos | mongos | mongos |
config server | config server | config server |
shard1 | 主节点 shard1 副节点 | shard1 仲裁 |
shard2 | 仲裁 shard2 主节点 | shard2 副节点 |
shard3 | 副节点 shard3 仲裁 | shard3 主节点 |
端口规划
主机名 | IP | 组件mongos | 组件config server | 分片shard |
---|---|---|---|---|
server1 | 192.168.123.247 | 端口:27000 | 端口:27017 | shard1:27001 |
server2 | 192.168.123.248 | 端口:27000 | 端口:27017 | shard2:27002 |
server3 | 192.168.123.249 | 端口:27000 | 端口:27017 | shard3:27003 |
时间同步
略
防火墙
略
集群部署
解压mongodb
官网下载,根据操作系统选择下载相应的版本。
Mongodb-download
在三台机器上执行解压
bash
tar zxvf mongodb-linux-x86_64-rhel8-7.0.14.tgz -C /usr/local/mongodb
新建目录
三台机器建立config、mongos、shard1、shard2、shard3目录,包括子目录
bash
mkdir -p /usr/local/mongodb/config/{conf,data,log,run}
mkdir -p /usr/local/mongodb/mongos/{conf,data,log,run}
mkdir -p /usr/local/mongodb/shard{1,2,3}/{conf,data,log}
目录结构概述
bash
/usr/local/mongodb/config:
用途:存放配置服务器的相关文件。
子目录:
bash
conf:存放配置服务器的配置文件(如 mongod.conf)。
data:存放配置服务器的数据文件。
log:存放配置服务器的日志文件。
run: 存储进程PID文件
bash
/usr/local/mongodb/mongos:
用途:存放路由进程(Mongos)的相关文件。
子目录:
bash
conf:存放路由进程的配置文件。
data:因为 Mongos 不持久化数据。(也可以不创建)
log:存放路由进程的日志文件。
run: 存储进程PID文件
bash
/usr/local/mongodb/shard{1,2,3}:
用途:存放分片服务器的相关文件。
子目录:
bash
conf:存放分片服务器的配置文件。
data:存放分片服务器的数据文件。
log:存放分片服务器的日志文件。
配置环境变量
bash
vim /etc/profile
export MONGODB_HOME=/usr/local/mongodb
export PATH=$MONGODB_HOME/bin:$PATH
使立即生效
bash
source /etc/profile
安装依赖包,缺少就安装
bash
yum install libcurl openssl xz-libs
创建用户,指定组标识符
bash
groupadd mongo -g 777
useradd mongo -g 777 -M -s /sbin/nologin
id mongo
开机启动
bash
cat > /etc/systemd/system/mongodb.service << EOF
[Unit]
Description=mongodb
After=network.target remote-fs.target nss-lookup.target
[Service]
Type=simple
ExecStart=/usr/local/mongodb/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb/mongodb/bin/mongod --config /usr/local/mongodb/mongodb.conf --shutdown
PrivateTmp=true
[Install]
WantedBy=multi-user.target
EOF
三台config server配置:
bash
cat > /usr/local/mongodb/config/conf/mongod.conf << EOF
bash
# 日志设置
systemLog:
destination: file # 日志写入文件
path: /usr/local/mongodb/config/log/mongod.log # 日志文件路径
logAppend: true # 追加日志
logRotate: rename # 日志轮转方式,支持 rename 或 reopen
# 网络设置
net:
port: 27017 # MongoDB 默认端口
bindIp: 0.0.0.0 # 允许从所有 IP 访问,生产环境建议限制
# 数据目录
storage:
dbPath: /usr/local/mongodb/config/data # 数据文件存放路径
wiredTiger:
engineConfig:
cacheSizeGB: 1 # 根据情况配置内存
# 进程设置
processManagement:
fork: true # 以后台进程方式运行
pidFilePath: /usr/local/mongodb/config/run/mongod.pid # PID 文件路径
#复制集名称
replication:
replSetName: "myconfigset"
#作为配置服务
sharding:
clusterRole: configsvr
EOF
三台mongos配置
bash
cat > /usr/local/mongodb/config/conf/mongod.conf << EOF
# 日志设置
systemLog:
destination: file # 日志写入文件
path: /usr/local/mongodb/mongos/log/mongos.log # 日志文件路径
logAppend: true # 追加日志
logRotate: rename # 日志轮转方式,支持 rename 或 reopen
# 网络设置
net:
port: 27000 # MongoDB 默认端口
bindIp: 0.0.0.0 # 允许从所有 IP 访问,生产环境建议限制
# 进程设置
processManagement:
fork: true # 以后台进程方式运行
pidFilePath: /usr/local/mongodb/mongos/run/mongos.pid # PID 文件路径
#网络延迟阈值
replication:
localPingThresholdMs: 15
#关联配置服务
sharding:
configDB: myconfigset/server1:27017,server2:27017,server3:27017
EOF
启动三台config server (3台)
bash
mongod --config /usr/local/mongodb/config/conf/mongod.conf
安装mongosh
安装好mongosh工具,方便初始化副本集使用,
bash
# mongosh mongodb://server1:27017。成功登录如下图:默认的提示符是'test>'
大内存页 关闭 hugepage
bash
echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
echo "never" > /sys/kernel/mm/transparent_hugepage/defrag
初始化配置副本集(3台机器执行相同操作)
启动config server后,开始初始化副本集,登录任意一台开始初始化配置副本集
bash
#7.0.14版本登录时在test>数据库下,切换到admin数据库
test> use admin
switched to db admin
admin>
#执行以下config变量,注意myconfigset,要和mongod.conf里配置一致。
config={_id:"myconfigset",members:[
{_id:0,host:"server1:27017"},
{_id:1,host:"server2:27017"},
{_id:2,host:"server3:27017",},
]}
执行结果如下:
bash
#再执行初始化
rs.initiate(config)
bash
rs.status()
3.9 配置分片副本集
每台shard1,shard2,shard3配置
Shard1
bash
cat > /usr/local/mongodb/shard1/conf/shard1.conf << EOF
# 日志设置
systemLog:
destination: file # 日志写入文件
path: /usr/local/mongodb/shard1/log/shard1.log # 日志文件路径
logAppend: true # 追加日志
logRotate: rename # 日志轮转方式,支持 rename 或 reopen
# 网络设置
net:
port: 27001 # MongoDB shard1端口
bindIp: 0.0.0.0 # 允许从所有 IP 访问,生产环境建议限制
# 数据目录
storage:
dbPath: /usr/local/mongodb/shard1/data # 数据文件存放路径
wiredTiger:
engineConfig:
cacheSizeGB: 1 # 根据情况配置内存
# 进程设置
processManagement:
fork: true # 以后台进程方式运行
pidFilePath: /usr/local/mongodb/shard1/data/shard1.pid # PID 文件路径
#复制集名称
replication:
replSetName: "shard1"
#慢查询
operationProfiling:
slowOpThresholdMs : 100
mode: "slowOp"
#作为分片服务
sharding:
clusterRole: shardsvr
EOF
Shard2
bash
cat > /usr/local/mongodb/shard2/conf/shard2.conf << EOF
# 日志设置
systemLog:
destination: file # 日志写入文件
path: /usr/local/mongodb/shard2/log/shard2.log # 日志文件路径
logAppend: true # 追加日志
logRotate: rename # 日志轮转方式,支持 rename 或 reopen
# 网络设置
net:
port: 27002 # shard2端口
bindIp: 0.0.0.0 # 允许从所有 IP 访问,生产环境建议限制
# 数据目录
storage:
dbPath: /usr/local/mongodb/shard2/data # 数据文件存放路径
wiredTiger:
engineConfig:
cacheSizeGB: 1 # 根据情况配置内存
# 进程设置
processManagement:
fork: true # 以后台进程方式运行
pidFilePath: /usr/local/mongodb/shard2/data/shard2.pid # PID 文件路径
#复制集名称
replication:
replSetName: "shard2"
#慢查询
operationProfiling:
slowOpThresholdMs : 100
mode: "slowOp"
#作为分片服务
sharding:
clusterRole: shardsvr
EOF
Shard3
bash
cat > /usr/local/mongodb/shard3/conf/shard3.conf << EOF
# 日志设置
systemLog:
destination: file # 日志写入文件
path: /usr/local/mongodb/shard3/log/shard3.log # 日志文件路径
logAppend: true # 追加日志
logRotate: rename # 日志轮转方式,支持 rename 或 reopen
# 网络设置
net:
port: 27003 # MongoDB shard3 默认端口
bindIp: 0.0.0.0 # 允许从所有 IP 访问,生产环境建议限制
# 数据目录
storage:
dbPath: /usr/local/mongodb/shard3/data # 数据文件存放路径
wiredTiger:
engineConfig:
cacheSizeGB: 1 # 根据情况配置内存
# 进程设置
processManagement:
fork: true # 以后台进程方式运行
pidFilePath: /usr/local/mongodb/shard3/data/shard3.pid # PID 文件路径
#复制集名称
replication:
replSetName: "shard3"
#慢查询
operationProfiling:
slowOpThresholdMs : 100
mode: "slowOp"
#作为分片服务
sharding:
clusterRole: shardsvr
EOF
启动三台247,248,249服务器的shard1 server
bash
mongod --config /usr/local/mongodb/shard1/conf/shard1.conf
初始化shard1分片副本集
登录任意一台,注意端口号
bash
mongosh mongodb://server1:27001
初始化三台的shard1
#7.0.14版本登录时在test>数据库下,切换到admin数据库
test> use admin
switched to db admin
admin>
config={_id:"shard1",members:[
{_id:0,host:"server1:27001"},
{_id:1,host:"server2:27001"},
{_id:2,host:"server3:27001",arbiterOnly: true},
]}
#再执行初始化
rs.initiate(config)
rs.status()
启动三台247,248,249服务器的shard2 server
bash
mongod --config /usr/local/mongodb/shard2/conf/shard2.conf
登录任意一个节点,注意端口号,注意安装了mongosh
bash
mongosh mongodb://server2:27002
初始化三台的shard2
bash
#7.0.14版本登录时在test>数据库下,切换到admin数据库
test> use admin
switched to db admin
admin>
config={_id:"shard2",members:[
{_id:0,host:"server1:27002",arbiterOnly: true},
{_id:1,host:"server2:27002"},
{_id:2,host:"server3:27002"},
]}
#再执行初始化
rs.initiate(config)
rs.status()
3.12.1 初始化三台的shard3
bash
#7.0.14版本登录时在test>数据库下,切换到admin数据库
test> use admin;
switched to db admin
admin>
config={_id:"shard3",members:[
{_id:0,host:"server1:27003"},
{_id:1,host:"server2:27003",arbiterOnly: true},
{_id:2,host:"server3:27003"},
]}
#再执行初始化
rs.initiate(config)
rs.status()
启动mongos路由并分片
启动三台247,248,249服务器的mongos
bash
mongos --config /usr/local/mongodb/mongos/conf/mongos.conf
登录任意路由节点,注意端口号,注意安装了mongosh
bash
mongosh mongodb://server1:27000
添加分片
bash
#7.0.14版本登录时在test>数据库下,切换到admin数据库
test> use admin
switched to db admin
admin>db.adminCommand({ "setDefaultRWConcern" : 1, "defaultWriteConcern" : { "w" : 1 }})
admin>
##添加分片
sh.addShard("shard1/server1:27001,server2:27001,server3:27001")
sh.addShard("shard2/server1:27002,server2:27002,server3:27002")
sh.addShard("shard3/server1:27003,server2:27003,server3:27003")
#
Admin> sh.status();
验证分片机制
指定分片生效:
bash
db.runCommand({enablesharding:"testdb"})
哈希分片
bash
db.runCommand({shardcollection:"testdb.table1",key:{id:"hashed"}})
插入1万个数据,测试
bash
for (var i = 1; i <= 10000; i++){
db.table1.insertOne({id:i,"test1":"testval1"});
Shard1
Shard2
Shard3
汇总内容
验证已完成,可以看到数据分到3个分片,各自分片数量为:
shard1 "count" : 3366,
shard2 "count" : 3284,
shard3 "count" : 3350。
已经成功!