创建带有认证的mongo分片集群
-_-之前可视化编辑器的太丑了,所以删了原来的,拿markdown重写了一遍
本文适合已经对mongo集群的理论知识已经有所了解的读者
本文着重讲述集群部署上的完整步骤和细节,以及如何在集群上使用用户认证功能
我给的示例的集群结构 :
{
1个路由mongos结点(本地,27017端口)
1个元配置config结点(本地,27018端口)
2个分片shard结点(本地,28001以及28002端口)
}
环境版本 :
{
mongo版本 : 3.2.4
系统版本 : ubuntu15.04
}
当然,生产环境下,建议多个mongos结点和多个config结点,
其中mongo推荐的config结点的数量是至少三个
而且生产环境下,每个分片shard结点可以是一个复制集的主结点
下面列出所有的步骤:
先来不带认证的
一. 第一个shard分片数据结点的配置文件 shard28001.conf
port=28001
shard1的端口
bind_ip=127.0.0.1
shard1的绑定地址
dbpath=/home/seven/program/mongodb/data/shard28001/
shard1的数据目录(绝对路径)
logpath=/home/seven/program/mongodb/log/shard28001.log
shard1的日志目录(绝对路径)
pidfilepath=/home/seven/program/mongodb/data/shard28001/shard28001.pid
shard1的pid路径(绝对路径)
logappend=true
shard1的日志以追加方式
fork=true
shard1以后台方式运行
shardsvr=true
表明该mongo进程是一个分片结点
profile=1
只在操作时间超过slowms时,才记录慢日志
profile=0表示永不记录,profile=1表示只记录慢日志,profile=2表示所有日志都记录
slowms=100
慢日志的时间阀值是100ms
另外,这两项配置推荐在主结点和从结点上都进行配置
并且可以通过db.getProfilingStatus()这条命令来查看慢日志的配置信息
其实,不推荐通过配置文件的方式强制开启慢日志
相反,推荐使用db.setProfilingLevel(int)的方式动态调整profile的等级
因为,慢日志通常用在内测时候,真正上线后为了性能,是不会开启慢日志的,或者说是不会长期开着的
一般是每隔一段时间,动态地开启一段时间来获取线上测试情况
二. 第二个shard分片数据结点的配置文件 shard28002.conf
port=28002
shard2的端口
bind_ip=127.0.0.1
shard2的绑定地址
dbpath=/home/seven/program/mongodb/data/shard28002/
shard2的数据目录(绝对路径)
logpath=/home/seven/program/mongodb/log/shard28002.log
shard2的日志目录(绝对路径)
pidfilepath=/home/seven/program/mongodb/data/shard28002/shard28002.pid
shard2的pid路径(绝对路径)
logappend=true
shard2的日志以追加方式
fork=true
shard2以后台方式运行
shardsvr=true
表明该mongo进程是一个分片结点
profile=1
slowms=100
三. config元数据结点的配置文件 config27018.conf
port=27018
config结点的端口
bind_ip=127.0.0.1
config结点的绑定地址
dbpath=/home/seven/program/mongodb/data/config27018/
config结点的数据目录(绝对路径)
logpath=/home/seven/program/mongodb/log/config27018.log
config结点的日志路径(绝对路径)
pidfilepath=/home/seven/program/mongodb/data/config27018/config27018.pid
config结点的pid路径(绝对路径)
logappend=true
config结点的日志以追加方式
fork=true
config结点以后台方式运行
configsvr=true
表明该mongo进程是一个元数据结点
profile=1
slowms=100
四. mongos路由结点的配置文件 mongos27017.conf
port=27017
mongos结点的端口
bind_ip=127.0.0.1
mongos结点的绑定地址
logpath=/home/seven/program/mongodb/log/mongos27017.log
mongos结点的日志路径(绝对路径)
pidfilepath=/home/seven/program/mongodb/data/mongos27017/mongos27017.pid
mongos结点的pid路径(绝对路径)
logappend=true
mongos结点的日志以追加方式
fork=true
mongos结点以后台方式运行
configdb=127.0.0.1:27018
表明该mongo进程是一个路由结点,且它只有一个元数据结点并且地址为本地且端口为27018
注意mongos路由结点是不需要也不能定义dbpath的
注意路由结点上不需要配置profile和slowms,同样在路由结点上也无法查看这两项设置
五. 启动脚本
init.sh :
禁用hugepage,否则启动mongod进程的时候会有warning
另外这个脚本要以root方式运行,所以权限最好设置为700,所属组设置为root:root
echo never > /sys/kernel/mm/transparent_hugepage/enabled
echo never > /sys/kernel/mm/transparent_hugepage/defrag
shard28001.sh : 分片结点1的启动脚本,这个脚本最好不要以root身份运行
cd /home/seven/program/mongodb/bin
进入mongodb的bin目录
./mongod -f ../conf/shard28001.conf
启动shard1结点(-f指定配置文件)
shard28002.sh : 分片结点2的启动脚本,这个脚本最好不要以root身份运行
cd /home/seven/program/mongodb/bin
进入mongodb的bin目录
./mongod -f ../conf/shard28002.conf
启动shard2结点(-f指定配置文件)
config27018.sh : 元数据结点的启动脚本,这个脚本最好不要以root身份运行
cd /home/seven/program/mongodb/bin
进入mongodb的bin目录
./mongod -f ../conf/config27018.conf
启动config结点(-f指定配置文件)
mongos27017.sh : 路由结点的启动脚本,这个脚本最好不要以root身份运行
cd /home/seven/program/mongodb/bin
进入mongodb的bin目录
./mongos -f ../conf/mongos27017.conf
以mongos形式启动路由结点(-f指定配置文件)
六. 启动各实例
su root
切换为root身份,以便运行init.sh脚本来禁用hugepage
./init.sh
禁用hugepage,(当然这里你需要进到你自己机子上存放该脚本的目录)
exit
退出root身份,以便启动mongod实例
./shard28001.sh
启动第一个分片结点
./shard28002.sh
启动第二个分片结点
./config27018.sh
启动元数据结点
./mongos27017.sh
启动路由结点
若你的config结点不满3个,它会提示你在生产环境下最好至少三个config结点
七. 添加分片成员
mongo 127.0.0.1:27017/admin
进入mongos(路由结点)的shell
db.runCommand({ "addShard" : "127.0.0.1:28001" })
添加分片结点28001到集群中
如果不事先进入admin库,会报错,所以需要连接时指定admin库,或者use admin
db.runCommand({ "addShard" : "127.0.0.1:28002" })
添加分片结点28002到集群中
八. 创建一个测试库和集合
use 新库名
创建一个新的库(当然是在路由结点,即mongos的shell中进行)
db.新表名.insert({...})
插入若干条数据
db.新表名.ensureIndex({...})
为这个表建一个索引吧
例如我是db.usertable.ensureIndex({ userid : 1 },{ unique : true })
db.runCommand({ enablesharding : 新库名 })
使刚才创建的库能够被分片
(发现报错,提示必须在admin环境下,所以use admin,再执行这条命令)
db.runCommand({ shardcollection : "库名.表名", key : {...} })
为某个库中的某个表添加分片片键,例如我是 :
db.runCommand(
{
shardcollection : "weshare.usertable",
key : { "userid" : 1 },
unique : true
}
)
注意,强烈推荐片键是索引的一部分前缀,有利于达到查询的局部化
九. 查看集群状态
use config
进入config库,即元数据库
(当然这里还是在路由结点的mongos的shell里执行命令)
db.shards.find()
查看当前集群中有哪些shard结点
use 新库名
进入你刚才创建的那个库
db.表名.stats()
查看该库中的该表的集群状态
若发现里面最开始的sharded字段是true,则表示你的集群创建成功了
db.printShardingStatus()
查看分片状态
再来加入认证的配置
十. 生成密钥文件
openssl rand -base64 64 > keyfile.dat
生成64字节的密钥文件
chmod 600 keyfile.dat
建议把密钥文件的权限设置为600(针对启动mongo实例的那个用户)
接着需要把这个密钥文件拷贝到集群中每一个结点上(路由结点,元配置结点,分片结点上都要有这个密钥文件)
十一. 创建集群用户
mongo 127.0.0.1:27017/admin
进入mongos路由结点(我这里是本地的27017端口,请根据自身的地址和端口来进行)
db.createUser(
{
user : yourusername,
pwd : yourpassword,
roles :
[
{ role : "root", db : "admin" },
{ role : "clusterAdmin", db : "admin" }
]
}
)
创建针对admin库的管理员用户
use 新库
进入你之前创建的新库
db.createUser(
{
user : yourusername,
pwd : yourpassword,
roles :
[
{ role : "dbOwner", db : yourdb },
{ role : "clusterAdmin", db : "admin" }
]
}
)
创建针对某个这个新库的用户
注意,上述的两个用户,需要在每个结点(每个分片结点,每个路由结点)上都要创建
十二. 开启集群认证
keyFile=path/keyfile.dat
在每个结点(路由结点,元配置结点,分片结点)的配置文件中加入keyFile的配置项
auth=true
在每个元配置结点和分片结点(即除了mongos结点)的配置文件中加入auth=true的配置项
db.shutdownServer()
关闭原先的集群
注意,需要按照 路由结点 -> 配置结点 -> 分片结点 的顺序,依次关闭各结点的进程
在关闭某个进程时,需要先进入admin库,然后执行这条命令
重新启动集群,命令同第六步
十三. 验证集群的认证
mongo 127.0.0.1:27017/admin
进入路由结点(地址和端口请按照你的实际情况)
db.auth(yourusername,yourpassword)
admin库的认证
use 新库
进入之前你创建的新库
db.新表.insert({...})
往这个新库的新表里插入一条数据
发现报错没有权限,因为你需要进行auth,先执行db.auth(yourusr,yourpwd)
然后再执行这条命令
db.新表名.ensureIndex({...})
为这个新表添加索引
db.runCommand({ shardcollection : "库名.表名", key : {...} })
为这个新表添加片键。注意,强烈推荐片键是索引的一部分前缀,这样能够达到查询的局部化
注意,要先进入admin库,否则这条命令不会成功
db.表名.stats()
查看该库中的该表的集群状态
若发现里面最开始的sharded字段是true,则表示添加认证功能后的集群没有出现异常
db.printShardingStatus()
查看分片状态