分片集群的部署有两种方式,一是把参数写在命令行中,而是把参数写在配置文件中,这两种方式是等价的,下面的链接是命令行参数与配置文件参数对应表:
下面讲述的是如何在单机上部署我们的测试分片集群(采用配置文件方式):
1.配置说明
2.创建对应的文件夹:
mkdir -p /home/hongxin/mongodb/conf
mkdir -p /home/hongxin/mongodb/mongos/log
mkdir -p /home/hongxin/mongodb/config/data
mkdir -p /home/hongxin/mongodb/config/log
mkdir -p /home/hongxin/mongodb/shard1/data
mkdir -p /home/hongxin/mongodb/shard1/log
mkdir -p /home/hongxin/mongodb/shard2/data
mkdir -p /home/hongxin/mongodb/shard2/log
3.新建config server 副本集
注:本次为了测试,该副本集只包含一个成员,实际生产环境应至少有三个成员)
配置文件说明
从MongoDB2.6开始,配置文件开始采用YAML的格式(YAML支持空格,不支持Tab)
# 2.6版本之前的写法(键值对)
configsvr = true
replSet=configs
# 2.6版本以后的写法
sharding:
clusterRole: configsvr
replication:
replSetName: <replica set name>
新建config.conf文件
>vim /home/hongxin/mongodb/conf/config.conf
# 填入以下内容
systemLog:
destination: file
path: /home/hongxin/mongodb/config/log/configsrv.log
logAppend: true
storage:
dbPath: /home/hongxin/mongodb/config/data
journal:
enabled: true
processManagement:
pidFilePath: /home/hongxin/mongodb/config/log/configsrv.pid
fork: true
net:
bindIp: 127.0.0.1
port: 27001
sharding:
clusterRole: configsvr # 代表此进程是config server
replication:
replSetName: configs # 副本集名称
运行并初始化
# 创建进程
[hongxin@localhost conf]$ mongod -f /home/hongxin/mongodb/conf/config.conf
2018-12-02T15:29:15.608+0800 I CONTROL [main] Automatically disabling TLS 1.0, to force-enable TLS 1.0 specify --sslDisabledProtocols 'none'
about to fork child process, waiting until server is ready for connections.
forked process: 9587
child process started successfully, parent exiting
# 连接
[hongxin@localhost conf]$ mongo --host 127.0.0.1 --port 27001
# 初始化,默认创建一个成员
>rs.initiate()
# 如果要创建多个成员,参见下面
rs.initiate(
{
_id: "<replSetName>",
configsvr: true,
members: [
{ _id : 0, host : "cfg1.example.net:27019" },
{ _id : 1, host : "cfg2.example.net:27019" },
{ _id : 2, host : "cfg3.example.net:27019" }
]
}
)
4.新建shard副本集
shard的创建方式与config server大同小异
新建shard1.conf文件
systemLog:
destination: file
path: /home/hongxin/mongodb/shard1/log/shard1.log
logAppend: true
storage:
dbPath: /home/hongxin/mongodb/shard1/data
journal:
enabled: true
processManagement:
pidFilePath: /home/hongxin/mongodb/shard1/log/shard1.pid
fork: true
net:
bindIp: 127.0.0.1
port: 27003
sharding:
clusterRole: shardsvr
replication:
replSetName: shard1
创建连接及初始化
[hongxin@localhost conf]$ mongod -f /home/hongxin/mongodb/conf/shard1.conf
[hongxin@localhost conf]$ mongo --host 127.0.0.1 --port 27003
>rs.initiate()
shard2 的创建与上面类似
注: shard 副本集的名字与 config server的名字不能一样!
5.新建mongos
新建 mongos.conf
注意 mongos.conf 没有存储选项
systemLog:
destination: file
path: /home/hongxin/mongodb/mongos/log/mongos.log
logAppend: true
processManagement:
pidFilePath: /home/hongxin/mongodb/mongos/log/mongos.pid
fork: true
net:
bindIp: 127.0.0.1
port: 27007
sharding:
configDB: configs/127.0.0.1:27001
创建连接及初始化
[hongxin@localhost conf]$ mongos -f /home/hongxin/mongodb/conf/mongos.conf
[hongxin@localhost conf]$ mongo --host 127.0.0.1 --port 27007
mongos> sh.addShard("shard1/127.0.0.1:27003, 127.0.0.1:27005")
至此,单机分片集群已搭建完毕
测试
mongos> use testdb
switched to db testdb
mongos> db.mycoll.insertOne({id: 1, "test": "test_shard"})
{
"acknowledged" : true,
"insertedId" : ObjectId("5c039517071e1ba7e339fe24")
}
# 首先要让数据库启动分片
mongos> sh.enableSharding("testdb")
{
"ok" : 1,
"operationTime" : Timestamp(1543738671, 3),
"$clusterTime" : {
....
}
mongos> db.mycoll.find({})
{ "_id" : ObjectId("5c039517071e1ba7e339fe24"), "id" : 1, "test" : "test_shard" }
# 因为集合不为空,所以在执行shardCollection前要先创建索引,如果集合为空,会自动创建索引
mongos> db.mycoll.createIndex({id: 1})
{
"raw" : {
"shard1/127.0.0.1:27003" : {
"createdCollectionAutomatically" : false,
"numIndexesBefore" : 1,
"numIndexesAfter" : 2,
"ok" : 1
}
},
...
}
# 查看索引
mongos> db.mycoll.getIndexes()
[
{
"v" : 2,
"key" : {
"_id" : 1
},
"name" : "_id_",
"ns" : "testdb.mycoll"
},
{
"v" : 2,
"key" : {
"id" : 1
},
"name" : "id_1",
"ns" : "testdb.mycoll"
}
]
# 使用 _id 作为分片键
mongos> sh.shardCollection("testdb.mycoll", {_id:1})
{
"collectionsharded" : "testdb.mycoll",
"collectionUUID" : UUID("cffb9588-52df-4df4-bb1a-9e461602cabd"),
"ok" : 1,
...
}
# 因为先使用 _id 作为分片键,再使用 id 会报错
mongos> sh.shardCollection("testdb.mycoll", {id:1})
{
"ok" : 0,
"errmsg" : "sharding already enabled for collection testdb.mycoll with options { _id: \"testdb.mycoll\", lastmodEpoch: ObjectId('5c039722733b2ba5a2bafebd'), lastmod: new Date(4294967296), dropped: false, key: { _id: 1.0 }, unique: false, uuid: UUID(\"cffb9588-52df-4df4-bb1a-9e461602cabd\") }",
"code" : 23,
"codeName" : "AlreadyInitialized",
...
}
# 插入100000条数据
mongos> for (var i = 1; i <= 100000; i++) db.mycoll.save({id:i,"test1":"test_shard"});
WriteResult({ "nInserted" : 1 })
# 查看结果(不知道是不是因为分片键为_id的缘故,数据并没有分散到shard2中)
mongos> db.mycoll.stats()
后期运维
mongodb的启动顺序是,先启动配置服务器,在启动分片,最后启动mongos.
mongod -f /usr/local/mongodb/conf/config.conf
mongod -f /usr/local/mongodb/conf/shard1.conf
mongod -f /usr/local/mongodb/conf/shard2.conf
mongod -f /usr/local/mongodb/conf/shard3.conf
mongod -f /usr/local/mongodb/conf/mongos.conf
关闭时,直接killall杀掉所有进程
killall mongod
killall mongos