目录
最近要研究mongos的分片集群,测试环境搭建了一套,简单的记录一下搭建的过程。
首先说一下分片的目的:分片是为了应付高频读IO压力、数据丢失容忍度极低的场景。高数据量和吞吐量的数据库应用会对单机的性能造成较大压力,大的查询量会将单机的CPU耗尽,大的数据量对单机的存储压力较大,最终会耗尽系统的内存而将压力转移到磁盘IO上。主要是为了解决这个问题。
配置顺序需按照 分片节点、config server/ mongos的顺序来。
因为是测试,4个节点全部放在了一台服务器(192.168.1.169)上
节点名称 | 对应端口 | 生产环境至少需要节点数量 |
---|---|---|
shard1 | 28019 | 3 |
shard2 | 28020 | 3 |
config | 28018 | 3 |
mongos | 28017 | 2 |
useradd mongo
su - mongo
mkdir config mongos shard
配置分片服务器
# 创建目录
cd ~/shard
for i in 28019 28020; do
mkdir -p $i/{conf,data,log}
done
编辑第一个节点实例配置文件
cat >> 28019/conf/mongod.conf<<EOF
systemLog:
destination: file
path: /home/mongo/shard/28019/log/mongodb.log
logAppend: true
storage:
journal:
enabled: true
dbPath: /home/mongo/shard/28019/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
# cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
processManagement:
fork: true
net:
bindIp: 0.0.0.0
port: 28019
replication:
oplogSizeMB: 2048
replSetName: shard1
sharding:
# 作为配置服务
clusterRole: shardsvr
EOF
配置第2个分片节点
\cp 28019/conf/mongod.conf 28020/conf/
sed -i "s#28019#28020#g" 28020/conf/mongod.conf
sed -i "s#shard1#shard2#g" 28020/conf/mongod.conf
启动两个节点
for i in 28019 28020; do
mongod -f $i/conf/mongod.conf
done
# 关闭分片服务器的方法
for i in 28019 28020; do
mongod --shutdown -f $i/conf/mongod.conf
done
配置两个节点复制集信息
mongo 192.168.1.169:28019/admin
> config = {_id: "shard1",members:[
{_id:0,host:"192.168.1.169:28019",priority:1},
]}
# 初始化配置
> rs.initiate(config)
mongo 192.168.1.169:28020/admin
> config = {_id:"shard2",members:[
{_id:0,host:"192.168.1.169:28020",priority:1},
]}
# 初始化配置
> rs.initiate(config)
如果只有一个节点的话,mongo 在命令行提示符会显示 shardN:SECONDARY,
其实这是一个主节点,退出后重新连接就会正常提示: shardN:PRIMARY,感觉这个提示是个bug?
配置config server
编写配置文件
cd ~/config/
cat > /home/mongo/config/conf/mongod.conf <<EOF
systemLog:
destination: file
path: /home/mongo/config/log/mongodb.conf
logAppend: true
storage:
journal:
enabled: true
dbPath: /home/mongo/config/data
directoryPerDB: true
#engine: wiredTiger
wiredTiger:
engineConfig:
cacheSizeGB: 1
directoryForIndexes: true
collectionConfig:
blockCompressor: zlib
indexConfig:
prefixCompression: true
net:
bindIp: 0.0.0.0
port: 28018
replication:
oplogSizeMB: 2048
replSetName: configReplSet
sharding:
clusterRole: configsvr
processManagement:
fork: true
EOF
启动config节点
# 启动节点
mongod -f /home/mongo/config/conf/mongod.conf
配置config节点
mongo --host 192.168.1.169 --port 28018 admin
> config = {_id: 'configReplSet', members: [
{_id: 0, host: '192.168.1.169:28018'},]
}
# 初始化配置
> rs.initiate(config)
配置router → mongos
编写mongos配置文件
cd ~/mongos/
mkdir conf data log
# 配置文件
cat > /home/mongo/mongos/conf/mongos.conf <<EOF
systemLog:
destination: file
path: /home/mongo/mongos/log/mongos.log
logAppend: true
net:
bindIp: 192.168.1.169
port: 28017
sharding:
configDB: configReplSet/192.168.1.169:28019,192.168.1.169:28020
processManagement:
fork: true
EOF
启动mongos
mongos -f /home/mongo/mongos/conf/mongos.conf
查看mongos状态
# 连接mongos
mongo 192.168.1.169:28017/admin
# 查看mongos状态
sh.status()
到这里其实就完成了分片集群的搭建。
下面我们盘一盘分片集群的操作和状态检查。
刚开始运行sh.status();时服务器的状态,会发现chunks是不平均的。
过一段时间后,会发现chunks已经平均了,并且有提示分片平衡后的数量
检查当前配置
这个时候我们连接mongos,看看未做指定数据集配置之前,分片数据集的情况是怎么样的
mongos> use admin
# 判断是否Shard集群
mongos> db.runCommand({ isdbgrid : 1})
列出所有分片信息
mongos> db.runCommand({ listshards : 1}) # 列出开启分片的数据库
mongos> use config
mongos> db.databases.find({ "partitioned": true })
为了测试我创建了两个collection,db1和test。
可以看到,这两个数据库只落在了一个shard上。看起来好像不符合官网及其他文档介绍的自动分片,这是什么情况?
答:这里就要引入chunks的概念。有兴趣的同学可以去看看官网文档。
这个是因为默认的chunks是64MB,也就是说,只有当数据库的文件大小超过这个数值的时候,才会做数据多分片的操作!大家可以show dbs; 执行这个命令看看数据库的大小。可以看出,我们创建的空数据库(或者说只有几条测试的数据库),大小是不足以达到分片的前提条件的。
当然这里的意思不是说,mongo会自动开启分片。分片需要针对数据库的collection手动开启。
也不是说,达不到chunks要求的大小就无法开启分片,只是达不到默认要求大小,分片是没有效果的。
其他的相关操作命令
#查看分片的片键
mongos> db.collections.find().pretty()
# 查看分片的详细信息
mongos> sh.status() # 或者 db.printShardingStatus()
# 删除分片节点
mongos> db.runCommand( { removeShard: "shard2" } )
mongo分片的一些操作
对指定库db1开启分片,如果db1不存在会自动创建
mongos> sh.enableSharding("db1")
# 指定分片的库的第二种方式:
db.runCommand({ enablesharding : “db1”})
创建集合
mongos> sh.shardCollection("db1.cl01",{"id":1} )
balance操作
# 查看mongo集群是否开启了 balance 状态
mongos> use admin
mongos> sh.getBalancerState()
mongos> sh.isBalancerRunning()
# 设置balance 窗口
mongos> use config
# 如果未设置
mongos> sh.setBalancerState( true )
# 修改balance 窗口的时间
mongos> db.settings.update(
{ _id: "balancer" },
{ $set: { activeWindow : { start : "<start-time>", stop : "<stop-time>" } } },
{ upsert: true }
)
# db.settings.update({ _id : "balancer" }, { $set : { activeWindow : { start : "00:00", stop : "5:00" } } }, true)
# 删除balance 窗口
mongos> use config
mongos> db.settings.update({ _id : "balancer" }, { $unset : { activeWindow : true } })
# 关闭balance
mongos> sh.stopBalancer()
mongos> sh.getBalancerState()
# 还可以关闭指定集合的balance
mongos> sh.disableBalancing("students.grades")
# 打开某个集合的balance
mongos> sh.enableBalancing("students.grades")
# 检查某个集合的balance是开启或者关闭
mongos> db.getSiblingDB("config").collections.findOne({_id : "students.grades"}).noBalance;
mongodb在做自动分片平衡的时候,或引起数据库响应的缓慢,可以通过禁用自动平衡以及设置自动平衡进行的时间来解决这一问题。
# 禁用分片的自动平衡
> use config
> db.settings.update({ _id: "balancer" }, { $set : { stopped: true } } , true );
# 自定义 自动平衡进行的时间段
> use config
> db.settings.update({ _id : "balancer" },
{ $set :
{ activeWindow :
{start: "21:00", stop: "9:00"}
}
},
true )
数据库分片设置
# 激活数据库分片功能
mongos> db.runCommand( { enablesharding : "test" } )
# 指定分片建对集合分片,范围片键--创建索引
mongos> use test
mongos> db.vast.ensureIndex( { id: 1 } )
mongos> use admin
mongos> db.runCommand( { shardcollection : "test.vast",key : {id: 1} } )
# 集合分片验证
mongos> use test
mongos> for(i=0;i<20000;i++){ db.vast1.insert({"id":i,"name":"clsn","age":70,"date":new Date()}); }
mongos> db.vast.stats()
# 插入数据的条数尽量大些,能够看出更好的效果。
相关脚本
后记
刚开始没明白顺序,执行之后报错
mongos> db.runCommand( { addshard : "my_repl/192.168.1.169:28020",name:"shard2"} )
{
"ok" : 0,
"errmsg" : "Cannot add my_repl/192.168.1.169:28020 as a shard since it is a config server",
"code" : 96,
"codeName" : "OperationFailed",
"operationTime" : Timestamp(1609142884, 1),
"$clusterTime" : {
"clusterTime" : Timestamp(1609142885, 1),
"signature" : {
"hash" : BinData(0,"AAAAAAAAAAAAAAAAAAAAAAAAAAA="),
"keyId" : NumberLong(0)
}
}
}
这个是因为配置文件中sharding.clusterRole 这个配置写错了,写成了configsrv
再重新走一遍,因为目前我用的单节点,所以我会受到一个告警:
{"t":{"$date":"2020-12-28T08:57:49.327Z"},"s":"W", "c":"SHARDING", "id":24132, "ctx":"main","msg":"Running a sharded cluster with fewer than 3 config servers should only be done for testing purposes and is not recommended for production."}
所以网上很多文档推荐说config必须要走3个节点
参考文档