美文网首页
18.MongoDB的分片集群

18.MongoDB的分片集群

作者: 鸡蛋挂面 | 来源:发表于2021-06-28 16:02 被阅读0次

一、环境准备

系统:
CentOS 7.8.2003
版本:
V4.4.6
安装方式:
源码包安装
下载地址
https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.6.tgz
服务器:

image.png

二、目录规划

01.二进制包目录:

/usr/local/mongodb/bin

02.数据目录:

存在MongoDB所有服务的数据信息

/data/mongodb

03.所有配置文件:

所有服务的配置文件存在目录

/data/mongodb/conf

shard1:
存放第一分片的数据、日志和pid

/data/mongodb/shard1

shard2:
存放第二分片的数据、日志和pid

/data/mongodb/shard2

shard3:
存放第三分片的数据、日志和pid

/data/mongodb/shard3

config server:
存放存储服务的数据、日志和pid

/data/mongodb/config

mongos:
存放第路由的日志和pid

/data/mongodb/mongos

三、创建用户和目录并授权

useradd -s /sbin/nologin -M mongo

mkdir -p /data/mongodb/conf
mkdir -p /data/mongodb/{config,shard{1..3},mongos}/{data,log}

cd /usr/local/src/
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-4.4.6.tgz
tar xf mongodb-linux-x86_64-rhel70-4.4.6.tgz
ln -s /usr/local/src/mongodb-linux-x86_64-rhel70-4.4.6 /usr/local/mongodb

chown -R mongo:mongo /usr/local/mongodb/

四、创建各个服务的配置文件

01.shard1:

shard1.conf

cat >/data/mongodb/conf/shard1.conf <<EOF
systemLog:
  destination: file
  path: /data/mongodb/shard1/log/shard1.log
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /data/mongodb/shard1/data
  directoryPerDB: true
  #engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true
net:
  bindIp: `ifconfig eth0|awk 'NR==2{print $2}'`,127.0.0.1
  port: 27001
replication:
  oplogSizeMB: 2048
  replSetName: sh1
sharding:
  clusterRole: shardsvr
processManagement: 
  fork: true
EOF

02.shard2:

shard2.conf

cat >/data/mongodb/conf/shard2.conf <<EOF
systemLog:
  destination: file
  path: /data/mongodb/shard2/log/shard2.log
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /data/mongodb/shard2/data
  directoryPerDB: true
  #engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true
net:
  bindIp: `ifconfig eth0|awk 'NR==2{print $2}'`,127.0.0.1
  port: 27002
replication:
  oplogSizeMB: 2048
  replSetName: sh2
sharding:
  clusterRole: shardsvr
processManagement: 
  fork: true
EOF

03.shard3:

shard3.conf

cat >/data/mongodb/conf/shard3.conf <<EOF
systemLog:
  destination: file
  path: /data/mongodb/shard3/log/shard3.log
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /data/mongodb/shard3/data
  directoryPerDB: true
  #engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true
net:
  bindIp: `ifconfig eth0|awk 'NR==2{print $2}'`,127.0.0.1
  port: 27003
replication:
  oplogSizeMB: 2048
  replSetName: sh3
sharding:
  clusterRole: shardsvr
processManagement: 
  fork: true
EOF

04.config server:

config.conf

cat > /data/mongodb/conf/config.conf <<EOF
systemLog:
  destination: file
  path: /data/mongodb/config/log/config.log
  logAppend: true
storage:
  journal:
    enabled: true
  dbPath: /data/mongodb/config/data
  directoryPerDB: true
  #engine: wiredTiger
  wiredTiger:
    engineConfig:
      cacheSizeGB: 1
      directoryForIndexes: true
    collectionConfig:
      blockCompressor: zlib
    indexConfig:
      prefixCompression: true
net:
  bindIp: `ifconfig eth0|awk 'NR==2{print $2}'`,127.0.0.1
  port: 21000
replication:
  oplogSizeMB: 2048
  replSetName: configReplSet
sharding:
  clusterRole: configsvr
processManagement: 
  fork: true
EOF

05.mongos:

mongos.conf

cat > /data/mongodb/conf/mongos.conf <<EOF
systemLog:
  destination: file
  path: /data/mongodb/mongos/log/mongos.log
  logAppend: true
net:
  bindIp: `ifconfig eth0|awk 'NR==2{print $2}'`,127.0.0.1
  port: 20000
sharding:
  configDB: configReplSet/192.168.10.66:21000,192.168.10.67:21000,192.168.10.68:21000
processManagement: 
  fork: true
EOF
chown -R mongo.mongo /data/mongodb

五、编写服务启动脚本:

shard1:

cat > /usr/lib/systemd/system/mongo-shard1.service << EOF
[Unit]

Description=mongodb-shard1
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard1.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard1.conf --shutdown
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

shard2:

cat > /usr/lib/systemd/system/mongo-shard2.service << EOF
[Unit]

Description=mongodb-shard2
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard2.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard2.conf --shutdown
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

shard3:

cat > /usr/lib/systemd/system/mongo-shard3.service << EOF
[Unit]

Description=mongodb-shard3
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard3.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/shard3.conf --shutdown
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

config server;

cat > /usr/lib/systemd/system/mongo-config.service << EOF
[Unit]

Description=mongodb-config
After=network.target remote-fs.target nss-lookup.target

[Service]
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/config.conf
ExecReload=/bin/kill -s HUP $MAINPID
ExecStop=/usr/local/mongodb/bin/mongod -f /data/mongodb/conf/config.conf --shutdown
PrivateTmp=true

[Install]
WantedBy=multi-user.target
EOF

mongos:

cat > /usr/lib/systemd/system/mongos.service << EOF
[Unit]
Description=Mongo Router Service
After=mongo-config.service
 
[Service]
Type=forking
User=mongo
Group=mongo
ExecStart=/usr/local/mongodb/bin/mongos --config /data/mongodb/conf/mongos.conf
Restart=on-failure

[Install]
WantedBy=multi-user.target
EOF

六、启动所有节点(先不启动mongos),并搭建复制集

注意启动顺序,这几个服务启动顺序无所谓,最重要的是mongos要留到最后配置好了之后再启动

# 重新加载system单元
systemctl daemon-reload

# 启动
systemctl start mongo-config
systemctl start mongo-shard1
systemctl start mongo-shard2
systemctl start mongo-shard3

# 添加到开机自启
systemctl enable mongo-config
systemctl enable mongo-shard1
systemctl enable mongo-shard2
systemctl enable mongo-shard3

01.搭建 config server 复制集(任意一台):

config服务是整个集群的大脑。所有的节点、认证、配置信息都会记录在这里,可以理解为k8s的etcd.

/usr/local/mongodb/bin/mongo --port 21000 admin

config = {_id: 'configReplSet', members: [
                        {_id: 0, host: '192.168.10.66:21000'},
                        {_id: 1, host: '192.168.10.67:21000'},
                        {_id: 2, host: '192.168.10.68:21000'}]
        }
rs.initiate(config)  
rs.status();

注:configserver 可以是一个节点,官方建议复制集。configserver不能有arbiter。
新版本中,要求必须是复制集。
注:mongodb 3.4之后,虽然要求config server为replica set,但是不支持arbiter

02.搭建 sh1 复制集:(在第一台服务器执行:66)

在不是将要成为仲栽节点arbiter的服务器上执行

/usr/local/mongodb/bin/mongo --port 27001 admin
config = {_id: 'sh1', members: [
                          {_id: 0, host: '192.168.10.66:27001'},
                          {_id: 1, host: '192.168.10.67:27001'},
                          {_id: 2, host: '192.168.10.68:27001',"arbiterOnly":true}]
           }

rs.initiate(config)
rs.status()
或者可以执行:
/usr/local/mongodb/bin/mongo --port 27001 admin
rs.initiate()
rs.add("192.168.10.67:27001")
rs.addArb("192.168.10.68:27001")

03.搭建 sh2 复制集:(在第二台服务器执行:67)

在不是将要成为仲栽节点arbiter的服务器上执行

/usr/local/mongodb/bin/mongo --port 27002 admin
config = {_id: 'sh2', members: [
                          {_id: 0, host: '192.168.10.66:27002',"arbiterOnly":true},
                          {_id: 1, host: '192.168.10.67:27002'},
                          {_id: 2, host: '192.168.10.68:27002'}]
           }
rs.initiate(config)
rs.status()
或者:
/usr/local/mongodb/bin/mongo --port 27002 admin
rs.initiate()
rs.add("192.168.10.68:27002")
rs.addArb("192.168.10.66:27002")

04.搭建 sh3 复制集:(在第三台服务器执行:68)

在不是将要成为仲栽节点arbiter的服务器上执行

/usr/local/mongodb/bin/mongo --port 27003 admin
config = {_id: 'sh3', members: [
                          {_id: 0, host: '192.168.10.66:27003'},
                          {_id: 1, host: '192.168.10.67:27003',"arbiterOnly":true},
                          {_id: 2, host: '192.168.10.68:27003'}]
           }
rs.initiate(config)
rs.status()
或者:
/usr/local/mongodb/bin/mongo --port 27003 admin
rs.initiate()
rs.add("192.168.10.66:27003")
rs.addArb("192.168.10.67:27003")

注意查看主从关系是否正确,如果副本集出错,可以手动删除再添加

七、启动mongos(三台)

在确定复制集都准确无误之后,在三台服务器上启动mongos服务

systemctl start mongos
systemctl enable mongos

八、分片集群添加节点

连接到任意一个mongos(192.168.10.66),做以下配置

(1)连接到mongs的admin数据库

/usr/local/mongodb/bin/mongo --port 20000 admin

(2)添加分片

db.runCommand( { addshard : "sh1/192.168.10.66:27001,192.168.10.67:27001,192.168.10.68:27001",name:"shard1"} )
db.runCommand( { addshard : "sh2/192.168.10.66:27002,192.168.10.67:27002,192.168.10.68:27002",name:"shard2"} )
db.runCommand( { addshard : "sh3/192.168.10.66:27003,192.168.10.67:27003,192.168.10.68:27003",name:"shard3"} )

(3)整体状态查看

sh.status();

九、使用分片集群

(1) RANGE分片配置及测试

01.激活数据库分片功能

登入任意一台服务器的mongos节点,然后启用数据库分片

/usr/local/mongodb/bin/mongo --port 20000 admin

db.runCommand( { enablesharding : "test" } )

02.指定分片键对集合分片

### 创建索引
use test
db.vast.ensureIndex( { id: 1 } )
### 开启分片
use admin
db.runCommand( { shardcollection : "test.vast",key : {id: 1} } )

03.集群分片验证

use test
for(i=1;i<10000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
db.vast.stats()

04.分片结果测试

shard1:
/usr/local/mongodb/bin/mongo --port 27001
db.vast.count();

shard2:
/usr/local/mongodb/bin/mongo --port 27002
db.vast.count();

shard3:
/usr/local/mongodb/bin/mongo --port 27003
db.vast.count();

(2) Hash分片配置及测试

对oldboy库下的vast大表进行hash
创建哈希索引
(1)对于oldboy开启分片功能
mongo --port 38017 admin
use admin
admin> db.runCommand( { enablesharding : "oldboy" } )
(2)对于oldboy库下的vast表建立hash索引
use oldboy
oldboy> db.vast.ensureIndex( { id: "hashed" } )
(3)开启分片 
use admin
admin > sh.shardCollection( "oldboy.vast", { id: "hashed" } )
(4)录入10w行数据测试
use oldboy
for(i=1;i<100000;i++){ db.vast.insert({"id":i,"name":"shenzheng","age":70,"date":new Date()}); }
(5)hash分片结果测试
mongo --port 38021
use oldboy
db.vast.count();
mongo --port 38024
use oldboy
db.vast.count();

十、启动顺序

systemctl start mongo-config
systemctl start mongo-shard1
systemctl start mongo-shard2
systemctl start mongo-shard3
systemctl start mongos

十一、停止顺序

systemctl stop mongos
systemctl stop mongo-shard1
systemctl stop mongo-shard2
systemctl stop mongo-shard3
systemctl stop mongo-config

十二、用户安全认证

01.在未开启用户访问控制的实例下创建管理员账户

/usr/local/mongodb/bin/mongo --port 27001 admin
db.createUser(
  {
    user: "myUserAdmin",
    pwd: "123456", 
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)

02.查看创建的用户

db.getUsers()

03.配置文件添加权限认证参数

vim /data/mongodb/conf/shard1.conf
...
security:     
  authorization: enabled

04.重启shard1

systemctl restart mongo-shard1

05.使用admin用户登录

/usr/local/mongodb/bin/mongongo --authenticationDatabase "admin" -u "myUserAdmin" -p

十三、优化告警

01.优化一:

告警:

Access control is not enabled for the database. Read and write access to data and configuration is unrestricted

描述:没有开启访问控制

解决办法:
开启安全账户功能


02.优化二:

告警:

/sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
/sys/kernel/mm/transparent_hugepage/defrag is 'always'. We suggest setting it to 'never'

描述:关闭大内存页
解决办法:

echo "never" > /sys/kernel/mm/transparent_hugepage/enabled
echo "never" > /sys/kernel/mm/transparent_hugepage/defrag

注意:改完要重启

03.优化三:

告警:

Soft rlimits too low
        currentValue: 1024
        recommendedMinimum: 64000

描述:rlimits太低

解决办法:

cat >> /etc/profile<<EOF
ulimit -f unlimited
ulimit -t unlimited
ulimit -v unlimited
ulimit -n 64000
ulimit -m unlimited
ulimit -u 64000
EOF
source /etc/profile

04.优化四:

告警:

** WARNING: This replica set has a Primary-Secondary-Arbiter architecture, but readConcern:majority is enabled

描述:在MongoDB 3.2及往后版本支持read concern,介绍详见https://docs.mongodb.com/v4.0/reference/read-concern/index.html。 在PSA结构中,可以将read concern关掉

解决办法:

在配置中增加enableMajorityReadConcern=false。

05.优化五:

告警:

**          for this node. This is not a recommended configuration. Please see
**          https://dochub.mongodb.org/core/psa-disable-rc-majority

描述:

解决办法:


06.优化六:

告警:

** WARNING: The configured WiredTiger cache size is more than 80% of available RAM.
See http://dochub.mongodb.org/core/faq-memory-diagnostics-wt

描述:内存不足

解决办法:
方法1: 加大机器内存
方法2: 调小配置文件里的缓存大小 cacheSizeGB: 0.5

07.优化七:

告警:

** WARNING: You are running this process as the root user, which is not recommended.

描述:不建议以root身份运行

解决办法:
方法1: 创建普通用户mongo,然后切换到mongo用户启动
方法2: 使用system方式登陆,指定运行用户为普通用户mongo


08.优化八:

告警:

** WARNING: Using the XFS filesystem is strongly recommended with the WiredTiger storage engine

描述:数据目录磁盘不是XFS格式
解决办法:
把磁盘格式转成XFS


十四、备份恢复

01.备份恢复工具介绍

(1)**   mongoexport/mongoimport
(2)***** mongodump/mongorestore

02.备份工具区别在哪里?

应用场景总结:
mongoexport/mongoimport:json csv 
1、异构平台迁移  mysql  <---> mongodb
2、同平台,跨大版本:mongodb 2  ----> mongodb 3
mongodump/mongorestore
日常备份恢复时使用.

03.导出工具mongoexport

mongoexport具体用法如下所示:
$ mongoexport --help  
参数说明:
-h:指明数据库宿主机的IP
-u:指明数据库的用户名
-p:指明数据库的密码
-d:指明数据库的名字
-c:指明collection的名字
-f:指明要导出那些列
-o:指明到要导出的文件名
-q:指明导出数据的过滤条件
--authenticationDatabase admin

1.单表备份至json格式
mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log -o /mongodb/log.json

注:备份文件的名字可以自定义,默认导出了JSON格式的数据。

2. 单表备份至csv格式
如果我们需要导出CSV格式的数据,则需要使用----type=csv参数:

 mongoexport -uroot -proot123 --port 27017 --authenticationDatabase admin -d test -c log --type=csv -f uid,name,age,date  -o /mongodb/log.csv

04.导入工具mongoimport

$ mongoimport --help
参数说明:
-h:指明数据库宿主机的IP
-u:指明数据库的用户名
-p:指明数据库的密码
-d:指明数据库的名字
-c:指明collection的名字
-f:指明要导入那些列
-j, --numInsertionWorkers=<number>  number of insert operations to run concurrently                                                  (defaults to 1)
//并行
数据恢复:
1.恢复json格式表数据到log1
mongoimport -uroot -proot123 --port 27017 --authenticationDatabase admin -d oldboy -c log1 /mongodb/log.json
2.恢复csv格式的文件到log2
上面演示的是导入JSON格式的文件中的内容,如果要导入CSV格式文件中的内容,则需要通过--type参数指定导入格式,具体如下所示:
错误的恢复

注意:
(1)csv格式的文件头行,有列名字
mongoimport   -uroot -proot123 --port 27017 --authenticationDatabase admin   -d oldboy -c log2 --type=csv --headerline --file  /mongodb/log.csv

(2)csv格式的文件头行,没有列名字
mongoimport   -uroot -proot123 --port 27017 --authenticationDatabase admin   -d oldboy -c log3 --type=csv -f id,name,age,date --file  /mongodb/log.csv
--headerline:指明第一行是列名,不需要导入。

十五、基于分片集群的安全认证

借鉴于:

https://www.cnblogs.com/pl-boke/p/10064489.html

00.在未开启用户访问控制之前创建管理员账户

# 连接任意mongos
# 注意在admin库下操作
/usr/local/mongodb/bin/mongo --port 20000 admin 
db.createUser(
  {
    user: "root",
    pwd: "123456", 
    roles: [ { role: "userAdminAnyDatabase", db: "admin" }, "readWriteAnyDatabase" ]
  }
)
# 验证用户是否创建成功
db.auth("root","123456")
# 返回为1说明创建成功

对分片集群执行访问控制需要配置两个方面:
1、副本集和共享集群的各个节点成员之间使用内部身份验证,可以使用密钥文件或x.509证书。密钥文件比较简单,本文介绍的也是使用密钥文件,官方推荐如果是测试环境可以使用密钥文件,但是正是环境,官方推荐x.509证书。原理就是,集群中每一个实例彼此连接的时候都检验彼此使用的证书的内容是否相同。只有证书相同的实例彼此才可以访问

2、使用客户端连接到mongodb集群时,开启访问授权。对于集群外部的访问。如通过可视化客户端,或者通过代码连接的时候,需要开启授权。

01.生成密钥文件

在keyfile身份验证中,副本集中的每个mongod实例都使用keyfile的内容作为共享密码,只有具有正确密钥文件的mongod或者mongos实例可以连接到副本集。

# 注意文件的权限和拥有者
openssl rand -base64 756 > /data/mongodb/conf/KeyFile.file
chmod 400 /data/mongodb/conf/KeyFile.file

密钥文件的内容必须在6到1024个字符之间,并且在unix/linux系统中文件所有者必须有对文件至少有读的权限。

02.把密钥文件分发给另外两台服务器

cd /data/mongodb/conf/
scp testKeyFile.file root@192.168.10.67:`pwd`
scp testKeyFile.file root@192.168.10.68:`pwd`

03.关闭整个分片集群

注意关闭的顺序

systemctl stop mongos
systemctl stop mongo-shard1
systemctl stop mongo-shard2
systemctl stop mongo-shard3
systemctl stop mongo-config

04.修改配置文件(三台服务器)

向config.conf、shard1.conf、shard2.conf、shard3.conf配置文件追加以下信息:

security:
  keyFile: /data/mongodb/conf/testKeyFile.file
  authorization: enabled

向mongos.conf文件追加以下信息:

security:
  keyFile: /data/mongodb/conf/testKeyFile.file

注意实际的文件位置
解释:
mongos比mongod少了authorization:enabled的配置。
原因是,副本集加分片的安全认证需要配置两方面的,副本集各个节点之间使用内部身份验证,用于内部各个mongo实例的通信,只有相同keyfile才能相互访问。所以都要开启keyFile: /data/mongodb/testKeyFile.file
然而对于所有的mongod,才是真正的保存数据的分片。mongos只做路由,不保存数据。所以所有的mongod开启访问数据的授权authorization:enabled。这样用户只有账号密码正确才能访问到数据

05.启动服务(三台服务器)

systemctl start mongo-config
systemctl start mongo-shard1
systemctl start mongo-shard2
systemctl start mongo-shard3
systemctl start mongos

06.连接mongos测试

# 不用账户密码也能连接进来
/usr/local/mongodb/bin/mongo --port 20000 admin
# 但是show dbs返回空
mongos> show dbs

连接时加上账户和密码再试试看

/usr/local/mongodb/bin/mongo --port 20000 admin  -uroot -p123456
mongos> show dbs
admin   0.000GB
config  0.003GB

相关文章

网友评论

      本文标题:18.MongoDB的分片集群

      本文链接:https://www.haomeiwen.com/subject/vswqultx.html