mongo 副本集部署

当前我们使用docker-compose 的方式部署mongodb 副本集。当然,最佳还是使用kubernetes进行mongodb副本集的部署。

环境准备

1.安装docker,docker-compose

生成keyFile

  • MongoDB使用keyFile认证,副本集中的每个MongoDB实例使用内容作为认证其他成员的共享密码。mongodb实例只有拥有正确的keyfile才可以加入副本集
  • keyFile的内容必须是6到1024个字符的长度,且副本集所有成员的keyFile内容必须相同。 这是MongoDB官方推荐keyFile的生成方式:
openssl rand -base64 756 > mongodb.key
chown 999:999 mongodb.key

docker-compose.yaml

这是一份docker-compose.yaml示例。其中需要提前在节点上创建对应的/data/mongo/data/mongo(i)目录;docker-compose.yaml需要与mongodb.key文件在同一目录下。

version: '3.3'


services:
  mongodb1:
    image: mongo:4.4.8
    volumes:
      - /data/mongo/data/mongo1:/data/db
      - ./mongodb.key:/data/mongodb.key
    user: root
    environment:
     - MONGO_INITDB_ROOT_USERNAME=root
     - MONGO_INITDB_ROOT_PASSWORD=admin
    container_name: mongodb1
    ports:
      - 37017:27017
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    restart: always
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@


  mongodb2:
    image: mongo:4.4.8
    volumes:
      - /data/mongo/data/mongo2:/data/db
      - ./mongodb.key:/data/mongodb.key
    user: root
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=admin
    container_name: mongodb2
    ports:
      - 37018:27017
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    restart: always
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@


  mongodb3:
    image: mongo:4.4.8
    volumes:
      - /data/mongo/data/mongo3:/data/db
      - ./mongodb.key:/data/mongodb.key
    user: root
    environment:
      - MONGO_INITDB_ROOT_USERNAME=root
      - MONGO_INITDB_ROOT_PASSWORD=admin
    container_name: mongodb3
    ports:
      - 37019:27017
    command: mongod --replSet mongos --keyFile /data/mongodb.key
    restart: always
    entrypoint:
      - bash
      - -c
      - |
        chmod 400 /data/mongodb.key
        chown 999:999 /data/mongodb.key
        exec docker-entrypoint.sh $$@

创建mongo 集群

切换到docker-compose.yaml文件所在目录,执行以下启动命令:

docker-compose up -d

预期结果:

[root@test01 mongo]# docker ps | grep mongo
97af9e11c66d   mongo:4.4.8   "bash -c 'chmod 400 …"   About an hour ago   Up About an hour   0.0.0.0:37019->27017/tcp, :::37019->27017/tcp   mongodb3
63ee9801d66f   mongo:4.4.8   "bash -c 'chmod 400 …"   About an hour ago   Up About an hour   0.0.0.0:37017->27017/tcp, :::37017->27017/tcp   mongodb1
9c15ed7476ba   mongo:4.4.8   "bash -c 'chmod 400 …"   About an hour ago   Up About an hour   0.0.0.0:37018->27017/tcp, :::37018->27017/tcp   mongodb2

此时,三个mongo实例已经运行起来了,接下来我们需要将这三个mongo实例配置为一个集群。

mongo集群初始化

连接集群

通过命令docker exec -it mongodb1 /bin/bash进入容器进行配置

进入集群后,执行 mongo -u root -p admin 连接集群,连接成功后如下所示:

root@63ee9801d66f:/# mongo -u root -p admin
MongoDB shell version v4.4.8
connecting to: mongodb://127.0.0.1:27017/?compressors=disabled&gssapiServiceName=mongodb
Implicit session: session {
    
     "id" : UUID("c69a9e0b-e52e-4224-bc81-3f2d09060434") }
MongoDB server version: 4.4.8
---
The server generated these startup warnings when booting: 
        2022-03-08T07:13:51.708+00:00: You are running on a NUMA machine. We suggest launching mongod like this to avoid performance problems: numactl --interleave=all mongod [other options]
        2022-03-08T07:13:51.708+00:00: /sys/kernel/mm/transparent_hugepage/enabled is 'always'. We suggest setting it to 'never'
---
---
        Enable MongoDB's free cloud-based monitoring service, which will then receive and display
        metrics about your deployment (disk utilization, CPU, operation statistics, etc).


        The monitoring data will be available on a MongoDB website with a unique URL accessible to you
        and anyone you share the URL with. MongoDB may use this information to make product
        improvements and to suggest MongoDB products and deployment options to you.


        To enable free monitoring, run the following command: db.enableFreeMonitoring()
        To permanently disable this reminder, run the following command: db.disableFreeMonitoring()
---

初始化副本集

在没有初始化副本集的集群中,执行rs.status();命令会得到以下结果:

> rs.status()
{
    
    
	"ok" : 0,
	"errmsg" : "command replSetGetStatus requires authentication",
	"code" : 13,
	"codeName" : "Unauthorized"
}

根据mongo服务的地址进行集群初始化:

> rs.initiate({
    
     _id: "mongos", members: [  
   {
    
     _id : 0, host : "10.81.138.205:37017" },  
   {
    
     _id : 1, host : "10.81.138.205:37018" },  
   {
    
     _id : 2, host : "10.81.138.205:37019" },
 ]});

其中 “mongos”是在docker-compose.yaml文件中指定的副本集名称,可根据实际情况修改。

host 后面紧跟着的是刚刚部署的三台mongo的地址(hostIP + port),端口号为docker-compose.yaml中映射的端口号,可根据服务器上的端口使用情况进行调整。

预期结果:

{
    
     "ok" : 1 }

初始化完成后执行rs.status(); 此时命令行中会输出以下文本:

mongos:SECONDARY> rs.status();
{
    
    
	"set" : "mongos",
	"date" : ISODate("2022-03-08T06:37:31.168Z"),
	"myState" : 1,
	"term" : NumberLong(1),
	"syncSourceHost" : "",
	"syncSourceId" : -1,
 ... ...
	"members" : [
		{
    
    
			"_id" : 0,
			"name" : "10.81.138.205:37017",
			"health" : 1,
			"state" : 1,
			"stateStr" : "PRIMARY",
			"uptime" : 32,
			"optime" : {
    
    
				"ts" : Timestamp(1646721451, 1),
				"t" : NumberLong(1)
			},
			"optimeDate" : ISODate("2022-03-08T06:37:31Z"),
			"syncSourceHost" : "",
			"syncSourceId" : -1,
			"infoMessage" : "Could not find member to sync from",
			"electionTime" : Timestamp(1646721450, 1),
			"electionDate" : ISODate("2022-03-08T06:37:30Z"),
			"configVersion" : 1,
			"configTerm" : 1,
			"self" : true,
			"lastHeartbeatMessage" : ""
		},
... ...

到这里集群的部署就完成了。

连接集群

你需要知道的

MongoDB复制集里Primary节点是不固定的,当遇到复制集轮转升级、Primary宕机、网络分区等场景时,复制集可能会选举出一个新的Primary,而原来的Primary则会降级为Secondary,即发生主备切换。

总而言之,MongoDB复制集里Primary节点是不固定的,不固定的,不固定的,重要的事情说3遍。

当连接复制集时,如果直接指定Primary的地址来连接,当时可能可以正确读写数据的,但一旦复制集发生主备切换,你连接的Primary会降级为Secondary,你将无法继续执行写操作,这将严重影响到你的线上服务。

所以生产环境千万不要直连Primary,千万不要直连Primary,千万不要直连Primary

正确的连接方式

要正确连接复制集,需要先了解下MongoDB的Connection String URI,所有官方的driver都支持以Connection String的方式来连接MongoDB。

下面就是Connection String包含的主要内容

mongodb://[username:password@]host1[:port1][,...hostN[:portN]][/[defaultauthdb][?options]]
  • mongodb:// 前缀,代表这是一个Connection String
  • username:password 如果启用了鉴权,需要指定用户密码
  • hostX:portX 复制集成员的ip:port信息,多个成员以逗号分割
  • /database 鉴权时,用户帐号所属的数据库
  • ?options 指定额外的连接选项

以205上的mongo副本集为例,正确的连接方式如下:

mongodb://root:[email protected]:37017,10.81.138.205:37018,10.81.138.205:37019/?replicaSet=mongos&readPreference=primary

猜你喜欢

转载自blog.csdn.net/qq_26356861/article/details/131288057