Mongodb分片(sharding)配置
xc
本文介绍mongodb分片的配置
基本概念
分片的主要思想就是把一块较大的数据分散到多台机器上,实现提速。
从 https://www.mongodb.com/download-center/community
下载server,mongos,shell,tool四个deb包,dpkg -i安装。(从apt装的话太卡了)
分片文档 https://docs.mongodb.com/manual/sharding/
replica set
副本集。就是一组数据库节点,里面每个节点的数据是一致的。 https://docs.mongodb.com/manual/replication/
mongos
是路由,应用程序要连到mongos,而不是直接连mongod。https://docs.mongodb.com/manual/core/sharded-cluster-query-router/
config server
存某个分片的配置。mongos根据这个来路由。https://docs.mongodb.com/manual/core/sharded-cluster-config-servers/
shard
是分片,包含实际数据。https://docs.mongodb.com/manual/core/sharded-cluster-shards/
分片配置
部署步骤参考文档 https://docs.mongodb.com/manual/tutorial/deploy-shard-cluster/
以两台机器为例
db1 1.1.1.1
db2 2.2.2.2
程序结构
[db1] [db2]
mongos:27017
config_server:27019 config_server:27019
shard:27018 shard:27018
一共要起1个mongos,4个mongod(2个config。2个shard)。
先手动创建目录
目录结构
├── mongodb
│ ├── config
│ │ ├── config_server.conf
│ │ └── shard.conf
│ ├── data
│ │ ├── config_server
│ │ │ ├── data
│ │ │ └── log
│ │ ├── mongos
│ │ │ └── log
│ │ └── shard
│ │ ├── data
│ │ └── log
│ └── temp
1.启动config server
config server是当作一个replica set副本集的,用mongod启动。
与正常副本集的区别是clusterRole设置为configsvr。
sudo mongod --config /airm2m_data/airm2m/database/mongodb/config/config_server.conf
两台机器都启动
2.初始化config server副本集
db2
mongo –port 27019 连上config server
rs.initiate(
{
_id:"config_server",
configsvr:true,
members: [
{ _id : 0, host : "2.2.2.2:27019" },
{ _id : 1, host : "1.1.1.1:27019" }
]
}
)
其中members包含2个config server的信息
rs.status()可查看副本集状态
3.启动shard分片
配置clusterRole: shardsvr
sudo mongod --config /airm2m_data/airm2m/database/mongodb/config/shard.conf
4.初始化shard副本集
这里每个shard只包含了一个节点。如果机器多,一个shard可以有多个节点分布在多台机器,这样每个shard的数据也会被同步到各个节点来保证安全。
db2
mongo –port 27018 连上shard
rs.initiate(
{
_id :"air_shard",
members: [
{ _id : 0, host : "2.2.2.2:27018" }
]
}
)
db1
mongo –port 27018 连上shard
rs.initiate(
{
_id :"air_shard_2",
members: [
{ _id : 0, host : "1.1.1.1:27018"}
]
}
)
5.启动mongos
配置里指定configDB为config_server
sudo mongos --config /airm2m_data/airm2m/database/mongodb/config/mongos.conf
6.往mongos里添加分片
mongo –port 27017 连上mongos
sh.addShard("air_shard/2.2.2.2:27018")
sh.addShard("air_shard_2/1.1.1.1:27018")
sh.status()可查看分片状态
这时可以创建数据了,添加数据,默认会选一个shard。
7.开启分片
sh.enableSharding("test1") 打开某个数据库的分片
sh.shardCollection("test1.a", {mnc : 1}) 打开某个collection的分片
继续往mongso节点添加数据,当数据量超过一个chunk时就会开始往别的shard挪数据。
可以设置chunk size
权限配置
1.给mongos、两个shard都添加一个root用户,有所有权限。
db.createUser(
{
user: "admin",
pwd: "123456",
roles: [ "root" ]
}
)
2.配置key。各个节点之间用key鉴权。
生成key
openssl rand -base64 756 > mongodb_key
chmod 400 mongodb_key
所有配置都加上
keyFile: /airm2m_data/airm2m/database/mongodb/config/mongodb_key
authorization保持disabled
重启所有节点
3.添加各app小号
mongos和shard里都添加一下。
use admin
db.auth('admin', '123456')
db.createUser(
{
user: "bsgps_worker",
pwd: "123456",
roles: [ { role: "readWrite", db: "bsgps" } ]
})
要use admin后添加用户,这样能添加到admin表里。修改权限时也在admin里操作。
如果把用户添加到实际数据库比如bsgps,python程序貌似权限转换有点问题。(需要authSource指定默认数据库,而且直接读别的数据库会报权限错误。)
添加权限的命令:
use admin
db.grantRolesToUser( "bsgps_worker", [ { role: "readWrite", db: "openluat" } ])
使用
1、所有app只接入mongos这个唯一的入口。管理员分析数据可以单独接入两个shard。
接入mongos目前看来是有几毫秒延迟的,即使只有一个数据库,并没有开启分片。例如查基站,直接进数据库查一个需要0.5毫秒,进mongos查就要0.9毫秒。
2、创建数据库必须在mongos操作,因为在某个shard创建的话貌似不能同步到mongos。
在mongos里创建数据库时它会自己选一个shard,没法默认建在某个shard上(见 https://docs.mongodb.com/manual/core/sharded-cluster-shards/index.html)
这时如果collection需要分片,则在mongos里操作(上面第7点)。
如果不需要分片,可以用movePrimary命令挪到db2(如果没有自动创建在db2)。
db.adminCommand( { movePrimary : "mongos_create", to : "air_shard" } )
一些操作
设置shard最大容量。可以限制弱的机器分到的数据量。
https://docs.mongodb.com/manual/tutorial/manage-sharded-cluster-balancer
设置Chunk Size
https://docs.mongodb.com/manual/tutorial/modify-chunk-size-in-sharded-cluster/
删除一个分片
https://docs.mongodb.com/manual/reference/command/removeShard/
进入mongos
db.adminCommand( { removeShard : "air_shard_2" } )
分片里的数据会挪到其他分片
如果分片里有不分片的collection,得用movePrimary挪走,然后再次removeShard才能彻底删除。否则貌似mongos状态会有问题,刷不出数据。
往副本集里添加一个节点
https://docs.mongodb.com/manual/tutorial/expand-replica-set/
用rs.add()
从副本集里删除一个节点
https://docs.mongodb.com/manual/tutorial/remove-replica-set-member/
可以用rs.remove()也可以用rs.reconfig()