MongoDB 7.0 搭建 Sharding 副本集群

打印 上一主题 下一主题

主题 675|帖子 675|积分 2025

本文是在ubuntu 22.03 系统版本上部署的,最低支持mongodb-6.0.4以上,所以这里安装mongodb7.0
1 安装mongo

安装方式有多种,本人是使用的第一种方式,时间也就20分钟吧,能接受。
1.1 方法一:使用apt安装


  • S1.导入 MongoDB GPG 公钥,用于验证下载的软件包的完整性,使用以下命令导入公钥
  1. curl -fsSL https://pgp.mongodb.com/server-7.0.asc |  sudo gpg -o /usr/share/keyrings/mongodb-server-7.0.gpg --dearmor
复制代码
具体需要导入的版本号,可以去https://www.mongodb.org/static/pgp 查询

  • S2. 创建一个 MongoDB 软件源列表文件,该文件告诉 apt 去哪里下载 MongoDB 软件包。在 /etc/apt/sources.list.d/ 目录中创建一个新的文件并将以下行添加到文件中,根据你的需要更改版本号:
  1. echo "deb [ arch=amd64 signed-by=/usr/share/keyrings/mongodb-server-7.0.gpg ] https://repo.mongodb.org/apt/ubuntu jammy/mongodb-org/7.0 multiverse" | sudo tee /etc/apt/sources.list.d/mongodb-org-7.0.list
复制代码

  • S3. 更新 apt 软件包索引
  1. sudo apt update
复制代码

  • S4. 现在已经配置了 MongoDB 软件源,可以通过 apt 命令安装 MongoDB 或更新到最新版本:
安装最新版本,此命令包含mongodb几乎所有的工具(本文档采用此种方式)
  1. sudo apt install -y mongodb-org       
复制代码
也可以安装指定的版本号,且为各个工具指定统一版本号
  1. sudo apt install mongodb-org=7.0 mongodb-org-server=7.0 mongodb-org-shell=7.0 mongodb-org-mongos=7.0 mongodb-org-tools=7.0
复制代码
此种方式安装,一是在配置GPG公钥和apt源容易配置错,同时,安装的时候也非常的慢,我没有去找国内的源,后续的朋友可以尝试换个国内的源
成功安装后,最后会有以下各个工具的版本信息:
  1. Preparing to unpack .../6-mongodb-org_7.0.5_amd64.deb ...
  2. Unpacking mongodb-org (7.0.5) ...
  3. Setting up mongodb-mongosh (2.1.1) ...
  4. Setting up mongodb-org-shell (7.0.5) ...
  5. Setting up mongodb-database-tools (100.9.4) ...
  6. Setting up mongodb-org-database-tools-extra (7.0.5) ...
  7. Setting up mongodb-org-database (7.0.5) ...
  8. Setting up mongodb-org-tools (7.0.5) ...
  9. Setting up mongodb-org (7.0.5) ...
  10. Processing triggers for man-db (2.10.2-1) ...
  11. needrestart is being skipped since dpkg has failed
  12. [1]+  Done                    sudo nohup mongod -f /mongodb/mongod-1.conf  (wd: /mongodb/node1)
  13. (wd now: /etc/apt/sources.list.d)
复制代码
各个工具的介绍如下:

  • mongodb-mongosh: Mongosh是MongoDB官方提供的命令行工具,用于连接和操作MongoDB数据库。
  • mongodb-org-shell: 这是MongoDB Shell的软件包,它是一个交互式的JavaScript环境,用于执行数据库操作和查询。
  • mongodb-database-tools: 这是MongoDB数据库工具的软件包,包括备份、还原、导入和导出等功能。
  • mongodb-org-database-tools-extra: 这是附加的MongoDB数据库工具软件包,提供了更多的数据库管理工具。
  • mongodb-org-database: 这是MongoDB数据库服务器的软件包,用于启动和管理MongoDB服务器实例。
  • mongodb-org-tools: 这是MongoDB工具集的软件包,包含了一些额外的辅助工具。


  • S5.启动mongodb
  1. sudo systemctl start mongod.service
复制代码
连接mongo
  1. mongosh
复制代码
再使用 show dbs; 查看当前默认的数据库

  • S6 设置为开机启动
  1. sudo systemctl enable mongod.service
复制代码
1.2 方法二:下载包,直接安装

可以从MongoDB 官网下载:https://www.mongodb.com/download-center/community/releases
Archive  是免安装版本,下载后,解压,里面的bin下面有各种 sh 执行文件
Server Pagekage  是服务器的包
Mongos Package  是分片集群需要安装的包,用于实现分片集群(Sharded Cluster)中的路由功能,因此,如果你需要使用MongoDB分片集群,就需要安装mongos软件包并配置mongos实例。而如果你只是想使用MongoDB数据库,那么只需要安装MongoDB服务器软件包即可


  • S2. 安装
进入到下载的文件目录,并执行安装命令
  1. sudo dpkg -i mongodb-org-server_7.0.5_amd64.deb
  2. sudo dpkg -i mongodb-org-mongos_7.0.5_amd64.deb
复制代码

  • S3 mongo-shell 的安装
由于mongodb 从6.0时代开始,不再提供 mongo-shell 的包,需要自己去下载对应的 mongodb-mongosh了。
这里是2.1.1 对应的下载地址:mongodb-mongosh_2.1.1_amd64.deb
其它更多的mongo-shell,参见 https://github.com/mongodb-js/mongosh/releases
下载后,安装如上一样的
MongoDB 7.0 更新了不少的内容,具体参见 https://www.mongodb.com/docs/v7.0/release-notes/7.0/#general-changes
2 部署集群

这里将采用3台服务器,搭建 MongoDB 的 Sharding 集群
服务器\mongo实例configmongosshard1(主shard)shard2shard3服务器1(192.168.0.4)主节点 27016主节点 27017主节点27018仲裁节点27019副节点27020服务器2(192.168.0.5)副节点27016副节点27017副节点27018主节点27019仲裁节点27020服务器3(192.168.0.6)副节点27016副节点27017仲裁节点27018副节点27019主节点27020
分片副本集是可以不用仲裁节点的,但是考虑到仲裁节点不需要考虑读写请求的负载,也不涉及数据同步,只是参与主节点选举并解决平票问题,所占用硬件资源(CPU、Memory)就小很多,这样就能减轻服务器压力,同时也让由三台服务器搭建的集群有不错的高可用性,挂掉任何一台服务器,都能正常运行
S1 在每台机器都创建以下目录
  1. sudo mkdir -p /data/mongodb/config/db
  2. sudo mkdir -p /data/mongodb/config/logs
  3. sudo mkdir -p /data/mongodb/mongos/logs
  4. sudo mkdir -p /data/mongodb/shard1/db
  5. sudo mkdir -p /data/mongodb/shard1/logs
  6. sudo mkdir -p /data/mongodb/shard2/db
  7. sudo mkdir -p /data/mongodb/shard2/logs
  8. sudo mkdir -p /data/mongodb/shard3/db
  9. sudo mkdir -p /data/mongodb/shard3/logs
  10. //最后更改到feizhu到权限
  11. sudo chown -R feizhu:feizhu /data/
复制代码
S2 再创建各个实例的配置文件

以服务器1 为例

  • config 实例的配置文件
sudo vim /data/mongodb/config/mongodb.conf
  1. # 数据库文件位置
  2. dbpath=/data/mongodb/config/db
  3. #日志文件位置
  4. logpath=/data/mongodb/config/logs/mongod.log
  5. # 以追加方式写入日志
  6. logappend=true
  7. # 是否以守护进程方式运行
  8. fork=true
  9. bind_ip=192.168.0.1
  10. port=27016
  11. # 表示是一个配置服务器
  12. configsvr=true
  13. #配置服务器副本集名称
  14. replSet=configsvr
复制代码

  • mongos 实例的配置文件
sudo vim /data/mongodb/mongos/mongodb.conf
  1. # mongos 不需要存储数据,所以不配置此项
  2. #dbpath=/data/mongodb/mongos/db
  3. #日志文件位置
  4. logpath=/data/mongodb/mongos/logs/mongod.log
  5. # 以追加方式写入日志
  6. logappend=true
  7. # 是否以守护进程方式运行
  8. fork=true
  9. bind_ip=0.0.0.0
  10. port=27017
  11. #配置服务器副本集名称
  12. replSet=mongossvr
  13. configdb=configsvr/192.168.0.1:27016,192.168.0.5:27016,192.168.0.6:27016
复制代码

  • Shard1 实例的配置文件
sudo vim /data/mongodb/shard1/mongodb.conf
  1. # 数据库文件位置
  2. dbpath=/data/mongodb/shard1/db
  3. #日志文件位置
  4. logpath=/data/mongodb/shard1/logs/mongod.log
  5. # 以追加方式写入日志
  6. logappend=true
  7. # 是否以守护进程方式运行
  8. fork=true
  9. bind_ip=192.168.0.1
  10. port=27018
  11. #声明开启分片
  12. shardsvr=true
  13. #指定分片shar1的副本集名称
  14. replSet=shard1
复制代码

  • Shard2 实例的配置
shard2 和shard3实例跟shard1基本是一样的,只需要把上面的shard路径和端口写对即可
sudo vim /data/mongodb/shard2/mongodb.conf
  1. # 数据库文件位置
  2. dbpath=/data/mongodb/shard2/db
  3. #日志文件位置
  4. logpath=/data/mongodb/shard2/logs/mongod.log
  5. # 以追加方式写入日志
  6. logappend=true
  7. # 是否以守护进程方式运行
  8. fork=true
  9. bind_ip=192.168.0.1
  10. port=27019
  11. #声明开启分片
  12. shardsvr=true
  13. #指定分片shard2的副本集名称
  14. replSet=shard2
复制代码

  • Shard3 实例的配置
sudo vim /data/mongodb/shard3/mongodb.conf
  1. # 数据库文件位置
  2. dbpath=/data/mongodb/shard3/db
  3. #日志文件位置
  4. logpath=/data/mongodb/shard3/logs/mongod.log
  5. # 以追加方式写入日志
  6. logappend=true
  7. # 是否以守护进程方式运行
  8. fork=true
  9. bind_ip=192.168.0.1
  10. port=27020
  11. #声明开启分片
  12. shardsvr=true
  13. #指定分片shard3的副本集名称
  14. replSet=shard3
复制代码
最后将/data更改到 feizhu 权限
sudo chown -R feizhu:feizhu /data/
S3 启动 config server

把每台服务器的 config server 实例启动
mongod -f /data/mongodb/config/mongodb.conf
3台服务器的config server都启动后,从任意一台服务器登录到主节点的config server,我们对照上面的实例部署表,服务器1是config的主节点
  1. mongosh --host 192.168.0.1  --port 27016
复制代码
所以,登录主节点这个config实例,然后初始化
  1. rs.initiate()
复制代码
初始化后,在回车,我们就发现已经显示 configsvr [direct: primary] 的字样,说明成功了,然后将另外两个副节点加入即可
  1. rs.add("192.168.0.5:27013")
  2. rs.add("192.168.0.6:27013")
复制代码
最后使用 rs.status() 查看一下结果,很明显3个实例的config副本集就搭建了,接下来就是启动 shard 实例了
S4 启动 shard 实例

启动 shard 实例,以启动 shard1 为例,进入各个服务器,分别启动各自的shard1实例
  1. mongod -f /data/mongodb/shard1/mongodb.conf
复制代码
然后使用任意服务器登录到shard1主节点,我们希望shard1是以服务器1为主节点,那么就登录到服务器1的shard1实例
  1. mongosh --host 192.168.0.1 --port 27018
复制代码
登录后,输入以下命令,初始化
  1. rs.initiate()
复制代码
此时,就是以当前节点为主节点,再加入副节点和仲裁节点
  1. rs.add("192.168.0.5:27018")
  2. rs.addArb("192.168.0.6:27018")
复制代码
rs.status() 查看状态,发现已经成功了,以此方式,同等启动shard2 和shard3,这里就不过多描述
最后将上面的mongodb目录,复制一份到服务器2和服务器3,将里面的配置文件相应的 bind_id 改成本机的即可
S5 启动 mongos 实例


  • 配置 mongos 的配置文件,
sudo vim /data/mongodb/mongos/mongodb.conf
  1. # mongos 不需要存储数据,所以不配置此项
  2. #dbpath=/data/mongodb/mongos/db
  3. #日志文件位置
  4. logpath=/data/mongodb/mongos/logs/mongod.log
  5. # 以追加方式写入日志
  6. logappend=true
  7. # 是否以守护进程方式运行
  8. fork=true
  9. # 允许所有IP 访问
  10. bind_ip=0.0.0.0
  11. port=27017
  12. #配置config server
  13. configdb=configsvr/192.168.0.1:27016,192.168.0.5:27016,192.168.0.6:27016
复制代码

  • 启动 mongos 实例
    ​         mongos -f /data/mongodb/mongos/mongodb.config
    注意是前面是 mongos 而不是 mongod
    因为我们这里是 mongos 集群,所以需要分别在三台服务器上都启动
  • 将 3 个shard 加入到分片集群
    登录任意一个 mongos 添加各个分片集群
    1. use admin
    2. sh.addShard("shard1/192.168.0.1:27018,192.168.0.5:27018,192.168.0.5:27018")
    3. sh.addShard("shard2/192.168.0.5:27019,192.168.0.5:27019,192.168.0.6:27019")
    4. sh.addShard("shard3/192.168.0.1:27020,192.168.0.5:27020,192.168.0.6:27020")
    复制代码
    然而在加入集群的时候报以下错误:
    1. [direct: mongos] admin> sh.addShard("shard3/192.168.0.1:27020,192.168.0.5:27020,192.168.0.6:27020")
    2. MongoServerError: Cannot add shard3/192.168.0.1:27020,192.168.0.5:27020,192.168.0.6:27020 as a shard since the implicit default write concern on this shard is set to {w : 1}, because number of arbiters in the shard's configuration caused the number of writable voting members not to be strictly more than the voting majority. Change the shard configuration or set the cluster-wide write concern using the setDefaultRWConcern command and try again.
    复制代码
    在 mongos 实例中  我们使用命令 db.adminCommand({ "getDefaultRWConcern": 1 })  可以查看到当前mongos 默认设置的写入安全机制defaultWriteConcern,默认是 majority (多数确认),这是mongodb5.0后开始的默认设置 ,这意味着当进行写操作时,至少要有超过大多数的数据节点确认写操作成功,才会返回成功的响应,目前我们是3个节点,mongo系统定义的一半节点数是 (3+1)/2=2,需要超过2,也就是至少要有3个节点写入成功才行,但是我们设置了一个 仲裁节点,导致3个shard节点中,只有2个可写数据的节点,怎么也不会写成功了,所以导致失败
    解决方法,将写入安全级别调低,使用以下命令
    1. db.adminCommand({  "setDefaultRWConcern" : 1,  "defaultWriteConcern" : {    "w" : 1  }})
    复制代码

    • "w" : 1 只要主节点写入成功,就直接返回成功的响应,而不管副节点的同步情况
    • "w" : majority  超过节点半数【(节点数+1)/2】写入成功,才返回成功响应
    • "w" : 0 不等待任何节点确认写操作,只需写入到内存就返回成功,这是最低级别的写安全级别,这个配置可以提供写入性能,但也有一定的风险
    • "w" : 等待指定数量的节点确认写成功

S6 创建 database


  • 登录到 mongos 集群中,创建 jfj 数据库
  1. use jfj
  2. db.createCollection('test')
  3. db.test.insert({"name":"tom","sex":"1"})
复制代码

  • 创完后,使用sh.status() 查看,可以看到以下这样一段
  1. {
  2.     database: {
  3.       _id: 'jfj',
  4.       primary: 'shard1',
  5.       partitioned: false,
  6.       version: {
  7.         uuid: UUID('21e70f6b-cd5a-485a-b8d6-baa9430c2d11'),
  8.         timestamp: Timestamp({ t: 1705977864, i: 2 }),
  9.         lastMod: 1
  10.       }
  11.     },
  12.     collections: {}
  13.   }
复制代码
意思是 jfj 的数据库默认使用的主节点是 shard1,也就是一些不使用分片的集合,会落在 shard1 上,如果想更改database的主shard,可以使用以下命令更改
  1. db.adminCommand( { movePrimary: <databaseName>, to: <newPrimaryShard> } )
  2. // 例如以下命令,会将数据库 jfj 挪到shard2分片副本集上
  3. db.adminCommand( { movePrimary : "jfj", to : "shard2" } )
复制代码

  • 开启分片,并为集合创建片键
  1. use admin
  2. sh.enableSharding("jfj") // mongodb7.0 不需要这一步也可以
  3. #以"name"作为分片键对集合 jfj.test进行分片
  4. sh.shardCollection("jfj.test", {"name" : "hashed"})
复制代码
至此,shard集群+副本集的mongodb集群就搭建完成了,使用 mongosh --host ip --port 可以连接到mongos进行操作
后面是安全认证的,生产环境的需要配置了
登录到mongos实例,使用以下的这段shell脚本导入数据试试
  1. var users = [];
  2. for (var i = 1; i <= 1000; i++) {
  3.     users.push({"id": i, "name": "jiangfj" + i});
  4. }
  5. db.users.insertMany(users);
复制代码
Keyfile 的内容
  1. openssl rand -base64 512 > ./keyfile
复制代码
为了确保文件的安全性,设置只有 feizhu 用户可读写
  1. feizhuguOI1434VBHZcv8m+VafAe8041IkkaZt7Ag8vytW21qkRtYkZX7b4z4SBdp
  2. ELYVMd7wf3HKdTH85ehehZa2fuALkld9sDF3HZSDZ5cKF4t2H9d0u8r8EQmEk8RU
  3. pNopBCTMvwPMn9ve0coMvUrSiERNTYOLxSB7hSmUNleau9E6xAriyEIw7vYUEoSJ
  4. SPahSYn6JqrQax4tX014lT957m3tSPMnvSjgsvbTX6YsD1t25TlWimDdrnpCEk+X
  5. oRtDIg7HGJdxX4twY8dK0IQcyouw/twE9VugTMsbdk8DCvNI6qWoTVK37zHotGLF
  6. k/QnXkF1KXdpmN9axj+Lo0ObJ86feizhuDlAo8XQIfRR5kENAzRdvPgRGliusnWxN
  7. CuxD2qkR9UmtBze95Ztrb+zgioEhRe8O8Go1XXYzJhZz+yC6RoFELr2XZlallpFm
  8. +5m9pK2RgHV38lQeQcVh72py+1ukwE5F46Em801PF8JIQ50mjnq4UL512824+DOv
  9. TE+A/2SEdjLxUau9HuiSQ1R2zocyXIV1DCGcCqYq1qD/o1BH1STd8md+UCDMdAWY
  10. E91kQUnf9ygiLxHCFAZUwYKlWzYfIX+UvMBp/sxyjwFldV33fCYXkRUKjE3ZlLvh
  11. 6bPrELnjy27YMSgoCGXaeP2+XaW5ZtzwJMGMBLfeizhu=
复制代码
将上面的 keyfile 文件复制到每个实例的目录中,或者复制到每台服务器上去,一台服务器都走同一个keyfile文件即可
S2 添加超级管理员用户

连接任意一个 mongos 创建超级管理员 root
  1. chmod 600 keyfile
复制代码
在 mongos上添加的用户,用户信息实际保存在config server上,mongos 本身不存储任何数据,包括用户信息
同时,mongos上创建的用户,也不会自动添加到各个shard分片服务器上的,不管是主节点还是副节点都没有
所以,为了以后方便维护shard 各个分片集群,分别登录到每个分片服务器的primary节点,添加 root 用户
  1. use admin;
  2. db.createUser({user:"root",pwd:'password',roles:[{"role":"root","db":"admin"}]});
复制代码
如果前期没有为各个shard副本集上创建root用户,但是后续又想用,就需要关闭config 实例和shard实例,在改配置文件,去掉安全认证的配置,在重启config和shard实例,在创建用户,完之后在改回来,特别麻烦,所以先创建好root,后续想干什么都行
S3 配置 mongodb.conf

配置各个 mongod 实例的 mongodb.conf 文件,在最后加上安全认证的配置
  1. use admin
  2. db.createUser({user:"root",pwd:'password',roles:[{"role":"root","db":"admin"}]});
复制代码
配置各个 mongos 实例的 mongodb.conf 文件
  1. #auth
  2. auth=true
  3. keyFile=/data/mongodb/keyfile
复制代码
mongos 不需要 auth=true
S4 重启实例

停止集群所有 mongod 和 mongos 的进程
最后,按照如下顺序启动所有程序
1 config  集群 > 2 shard  集群 > 3 mongos  集群
在启动shard的时候,至少需要config2个节点起来,也就是config集群可用才行
重启完之后,可以登录任一mongos实例
  1. keyFile=/data/mongodb/keyfile
复制代码
S5 创建 jfj 数据库的用户权限

使用管理员账号登录到mongos,创建一个 jfj 的只读用户
  1. mongosh -u root -p password 192.168.0.1:27017/admin
复制代码
连接试试
  1. use jfj
  2. db.createUser({user:"feizhu",pwd:'password',roles:[{"role":"readWrite","db":"jfj"}]});
复制代码
至此,整个shard集群就搭建好了~!~
4 其它

4.卸载MongoDB

1.停止MongoDB
  1. mongosh -u feizhu -p password  192.168.0.1:27017/jfj
复制代码
集群的话就需要进去实例里面执行一下命令,或者直接kill
  1. sudo service mongod stop
  2. //或者
  3. sudo systemctl stop mongod.service
  4. // 或者直接kill
复制代码
2.删除包
  1. use admin
  2. db.shutdownServer()
复制代码
3.删除数据目录


  • 删除MongoDB数据库和日志文件

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

惊雷无声

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表