docker-compose 搭建Mongodb 6.0 高可用分片集群


本文采用 mongo version: 6.0进行搭建
我们将创建一个包含以下详细信息的分片集群。
一个具有 3 个副本集的 Config Server。
一个分片,每个分片有 3 个副本集。
三个路由器 (mongos)
根据上述详细信息,Config Server 需要 3 台服务器(每个副本 1 台),Shard1 需要 3 台服务器(每个副本 1 台)Router (mongos) 需要 3 台服务器。

服务器配置及端口

IPROLEPORT
192.168.1.145configsvr10001
192.168.1.145shard120001
192.168.1.145shard220002
192.168.1.156mongos27017
192.168.1.146configsvr10001
192.168.1.146shard120001
192.168.1.146shard220002
192.168.1.146mongos27017
192.168.1.147configsvr10001
192.168.1.147shard120001
192.168.1.147shard220002
192.168.1.147mongos27017

创建目录

#三台服务器均执行
mkdir -p /mongo/{common,data,log}
mkdir -p /mongo/data/{config,mongo,shard1,shard2}
mkdir -p /mongo/log/{shard1,shard2}
chmod 0777 -R /mongo/log

编写docker-compose文件

# 三台服务器compose文件均相同
[root@node1 mongo]# cat /mongo/docker-compose.yml

version: '3'

services:
  configsvr1:
    container_name: config
    image: mongo:6.0.11
    command: mongod --configsvr --replSet config_rs --dbpath /data/db --port 27017
    ports:
      - 10001:27017
    volumes:
      - ./common/configsvr1:/data/db
      #- ./common/key.file:/home/key.file
  shard1:
    container_name: shard1
    image: mongo:6.0.11
    command: mongod --replSet shard1_rs --dbpath /data/db --port 27017 --bind_ip 0.0.0.0 --logpath /log/shard/mongo.log --shardsvr --wiredTigerCacheSizeGB 1
    ports:
      - 20001:27017
    volumes:
      - ${PWD}/data/shard1:/data/db
      #- ${PWD}/common/key.file:/home/key.file
      - ${PWD}/log/shard1:/log/shard
  shard2:
    container_name: shard2
    image: mongo:6.0.11
    command: mongod --replSet shard2_rs --dbpath /data/db --port 27017 --bind_ip 0.0.0.0 --logpath /log/shard/mongo.log --shardsvr --wiredTigerCacheSizeGB 1
    ports:
      - 20002:27017
    volumes:
      - ${PWD}/data/shard2:/data/db
      #- ${PWD}/common/key.file:/home/key.file
      - ${PWD}/log/shard2:/log/shard
  mongos:
    container_name: mongos
    image: mongo:6.0.11
    command: mongos --configdb config_rs/192.168.1.145:10001,192.168.1.146:10001,192.168.1.147:10001 --port 27017 --bind_ip_all
    ports:
      - 27017:27017
    volumes:
      - ./common/key.file:/home/key.file

启动容器

#三台服务器均执行
cd /mongo;
#启动容器
docker-compose up -d
#查看容器
[root@node1 test]# docker-compose ps -a
NAME                IMAGE               COMMAND                  SERVICE             CREATED             STATUS              PORTS
config              mongo:6            "docker-entrypoint.s…"   configsvr1          About an hour ago   Up About an hour    0.0.0.0:10001->27017/tcp, :::10001->27017/tcp
mongos              mongo:6             "docker-entrypoint.s…"   mongos              About an hour ago   Up About an hour    0.0.0.0:30000->27017/tcp, :::30000->27017/tcp
shardsvr1_1         mongo:6             "docker-entrypoint.s…"   shardsvr1_1         About an hour ago   Up About an hour    0.0.0.0:20001->27017/tcp, :::20001->27017/tcp
shardsvr1_2         mongo:6             "docker-entrypoint.s…"   shardsvr1_2         About an hour ago   Up About an hour    0.0.0.0:20002->27017/tcp, :::20002->27017/tcp
shardsvr1_3         mongo:6             "docker-entrypoint.s…"   shardsvr1_3         About an hour ago   Up About an hour    0.0.0.0:20003->27017/tcp, :::20003->27017/tcp
[root@node1 test]#

分片配置

本节,我们将创建2个分片。先创建一个分片导入数据,然后创建第二个分片,验证数据均衡。

创建第一个分片,初始化副本集

#这里的操作,在192.168.1.145执行。
#192.168.1.145
docker exec -it  shard1 mongosh (进入CLI工具)

 rs.initiate(
...    {
...      _id: "shard1_rs",
...      members: [
...        { _id : 0, host : "192.168.1.145:20001" },
...        { _id : 1, host : "192.168.1.146:20001" },
...        { _id : 2, host : "192.168.1.147:20001" }
...      ]
...    }
...  );
{ ok: 1 }


#查看状态
rs.status()
shard1_rs [direct: other] test> rs.status();
{
  set: 'shard1_rs',
  date: ISODate("2024-08-11T08:19:39.865Z"),
  myState: 1,
  term: Long("1"),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long("2000"),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 3,
  optimes: {
    lastCommittedOpTime: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
    lastCommittedWallTime: ISODate("2024-08-11T08:19:30.810Z"),
    readConcernMajorityOpTime: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
    appliedOpTime: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
    durableOpTime: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
    lastAppliedWallTime: ISODate("2024-08-11T08:19:30.810Z"),
    lastDurableWallTime: ISODate("2024-08-11T08:19:30.810Z")
  },
  lastStableRecoveryTimestamp: Timestamp({ t: 1723364329, i: 1 }),
  electionCandidateMetrics: {
    lastElectionReason: 'electionTimeout',
    lastElectionDate: ISODate("2024-08-11T08:19:00.778Z"),
    electionTerm: Long("1"),
    lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1723364329, i: 1 }), t: Long("-1") },
    lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1723364329, i: 1 }), t: Long("-1") },
    numVotesNeeded: 2,
    priorityAtElection: 1,
    electionTimeoutMillis: Long("10000"),
    numCatchUpOps: Long("0"),
    newTermStartDate: ISODate("2024-08-11T08:19:00.797Z"),
    wMajorityWriteAvailabilityDate: ISODate("2024-08-11T08:19:01.548Z")
  },
  members: [
    {
      _id: 0,
      name: '192.168.1.145:20001',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: 453,
      optime: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2024-08-11T08:19:30.000Z"),
      lastAppliedWallTime: ISODate("2024-08-11T08:19:30.810Z"),
      lastDurableWallTime: ISODate("2024-08-11T08:19:30.810Z"),
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      electionTime: Timestamp({ t: 1723364340, i: 1 }),
      electionDate: ISODate("2024-08-11T08:19:00.000Z"),
      configVersion: 1,
      configTerm: 1,
      self: true,
      lastHeartbeatMessage: ''
    },
    {
      _id: 1,
      name: '192.168.1.146:20001',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 49,
      optime: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
      optimeDurable: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2024-08-11T08:19:30.000Z"),
      optimeDurableDate: ISODate("2024-08-11T08:19:30.000Z"),
      lastAppliedWallTime: ISODate("2024-08-11T08:19:30.810Z"),
      lastDurableWallTime: ISODate("2024-08-11T08:19:30.810Z"),
      lastHeartbeat: ISODate("2024-08-11T08:19:38.805Z"),
      lastHeartbeatRecv: ISODate("2024-08-11T08:19:39.812Z"),
      pingMs: Long("0"),
      lastHeartbeatMessage: '',
      syncSourceHost: '192.168.1.145:20001',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 1,
      configTerm: 1
    },
    {
      _id: 2,
      name: '192.168.1.147:20001',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 49,
      optime: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
      optimeDurable: { ts: Timestamp({ t: 1723364370, i: 1 }), t: Long("1") },
      optimeDate: ISODate("2024-08-11T08:19:30.000Z"),
      optimeDurableDate: ISODate("2024-08-11T08:19:30.000Z"),
      lastAppliedWallTime: ISODate("2024-08-11T08:19:30.810Z"),
      lastDurableWallTime: ISODate("2024-08-11T08:19:30.810Z"),
      lastHeartbeat: ISODate("2024-08-11T08:19:38.805Z"),
      lastHeartbeatRecv: ISODate("2024-08-11T08:19:39.812Z"),
      pingMs: Long("0"),
      lastHeartbeatMessage: '',
      syncSourceHost: '192.168.1.145:20001',
      syncSourceId: 0,
      infoMessage: '',
      configVersion: 1,
      configTerm: 1
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1723364370, i: 1 }),
    signature: {
      hash: Binary.createFromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA=", 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1723364370, i: 1 })
}

#查看master节点
db.isMaster
shard1_rs [direct: primary] test> db.isMaster();
{
  topologyVersion: {
    processId: ObjectId("66b87256c5f141da61558f12"),
    counter: Long("7")
  },
  hosts: [
    '192.168.1.145:20001',
    '192.168.1.146:20001',
    '192.168.1.147:20001'
  ],
  setName: 'shard1_rs',
  setVersion: 1,
  ismaster: true,      ###145为master
  secondary: false,
  primary: '192.168.1.145:20001',
  me: '192.168.1.145:20001',
  electionId: ObjectId("7fffffff0000000000000001"),
  lastWrite: {
    opTime: { ts: Timestamp({ t: 1723364410, i: 1 }), t: Long("1") },
    lastWriteDate: ISODate("2024-08-11T08:20:10.000Z"),
    majorityOpTime: { ts: Timestamp({ t: 1723364410, i: 1 }), t: Long("1") },
    majorityWriteDate: ISODate("2024-08-11T08:20:10.000Z")
  },
  isImplicitDefaultMajorityWC: true,
  maxBsonObjectSize: 16777216,
  maxMessageSizeBytes: 48000000,
  maxWriteBatchSize: 100000,
  localTime: ISODate("2024-08-11T08:20:17.527Z"),
  logicalSessionTimeoutMinutes: 30,
  connectionId: 2,
  minWireVersion: 0,
  maxWireVersion: 17,
  readOnly: false,
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1723364410, i: 1 }),
    signature: {
      hash: Binary.createFromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA=", 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1723364410, i: 1 }),
  isWritablePrimary: true

配置 Config Server 环境

进入第一台虚拟机 (192.168.1.145) 的 config-server 容器(仅需要在一台执行即可)
执行docker exec -it config  mongosh --port 27017 
  rs.initiate(
   {
     _id: "config_rs",
     configsvr: true,
     members: [
       { _id : 0, host : "192.168.1.145:10001" },
       { _id : 1, host : "192.168.1.146:10001" },
       { _id : 2, host : "192.168.1.147:10001" }
     ]
   }
 );


测试configsvr 
docker exec -it config mongosh --port 27017 --eval "db.runCommand({ ping: 1 })" | grep ok
  ok: 1,

Mongos 配置

#192.168.1.145 
docker exec -it  mongos mongosh 
[direct: mongos] test> sh.addShard("shard1_rs/192.168.1.145:20001,192.168.1.146:20001,192.168.1.147:20001")
{
  shardAdded: 'shard1_rs',
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1723365952, i: 7 }),
    signature: {
      hash: Binary.createFromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA=", 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1723365952, i: 7 })
}

##**查看mongos状态**

[direct: mongos] test> sh.status()
shardingVersion
{ _id: 1, clusterId: ObjectId("66b8766df5f2eabc84fc6b34") }
---
shards
[
  {
    _id: 'shard1_rs',
    host: 'shard1_rs/192.168.1.145:20001,192.168.1.146:20001,192.168.1.147:20001',
    state: 1,
    topologyTime: Timestamp({ t: 1723365952, i: 4 })
  }
]
---
active mongoses
[ { '6.0.11': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently enabled': 'yes',
  'Failed balancer rounds in last 5 attempts': 0,
  'Currently running': 'no',
  'Migration Results for the last 24 hours': 'No recent migrations'
}
---
databases
[
  {
    database: { _id: 'config', primary: 'config', partitioned: true },
    collections: {}
  }
]

功能测试

创建分片集合

1.链接到mongos,创建分配集合
docker exec -it mongos mongosh
mongos>sh.status()
#为了集合支持分片,需要先开启database的分片功能
[direct: mongos] admin> use graph;
switched to db graph
[direct: mongos] graph> sh.enableSharding("graph")  ##开启
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1723366451, i: 4 }),
    signature: {
      hash: Binary.createFromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA=", 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1723366451, i: 2 })
}
##对集合进行分片初始化
[direct: mongos] graph> sh.shardCollection("graph.emp",{_id: 'hashed'})
{
  collectionsharded: 'graph.emp',
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1723366617, i: 29 }),
    signature: {
      hash: Binary.createFromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA=", 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1723366617, i: 25 })
}

###
sh.status()

shardingVersion
{ _id: 1, clusterId: ObjectId("66b8766df5f2eabc84fc6b34") }
---
shards
[
  {
    _id: 'shard1_rs',
    host: 'shard1_rs/192.168.1.145:20001,192.168.1.146:20001,192.168.1.147:20001',
    state: 1,
    topologyTime: Timestamp({ t: 1723365952, i: 4 })
  }
]
---
active mongoses
[ { '6.0.11': 2 } ]
---
autosplit
{ 'Currently enabled': 'yes' }
---
balancer
{
  'Currently enabled': 'yes',
  'Currently running': 'no',
  'Failed balancer rounds in last 5 attempts': 0,
  'Migration Results for the last 24 hours': 'No recent migrations'
}
---
databases
[
  {
    database: { _id: 'config', primary: 'config', partitioned: true },
    collections: {
      'config.system.sessions': {
        shardKey: { _id: 1 },
        unique: false,
        balancing: true,
        chunkMetadata: [ { shard: 'shard1_rs', nChunks: 1024 } ],
        chunks: [
          'too many chunks to print, use verbose if you want to force print'
        ],
        tags: []
      }
    }
  },
  {
    database: {
      _id: 'graph',
      primary: 'shard1_rs',
      partitioned: false,
      version: {
        uuid: new UUID("d8e56cbd-86e1-47a1-b6e7-af18747e7af0"),
        timestamp: Timestamp({ t: 1723366450, i: 1 }),
        lastMod: 1
      }
    },
    collections: {
      'graph.emp': {
        shardKey: { _id: 'hashed' },   ##这里已经查看到id为hashed
        unique: false,
        balancing: true,
        chunkMetadata: [ { shard: 'shard1_rs', nChunks: 2 } ],
        chunks: [
          { min: { _id: MinKey() }, max: { _id: Long("0") }, 'on shard': 'shard1_rs', 'last modified': Timestamp({ t: 1, i: 0 }) },
          { min: { _id: Long("0") }, max: { _id: MaxKey() }, 'on shard': 'shard1_rs', 'last modified': Timestamp({ t: 1, i: 1 }) }
        ],
        tags: []
      }
    }
  }
]

数据测试

docker exec -it mongos mongosh

##插入数据测试
use graph
for (var i = 0;i <=10000;i++) 
{
   db.emp.insert({i:i});
}
##查询数据及分布情况
[direct: mongos] graph> db.emp.getShardDistribution()
Shard shard1_rs at shard1_rs/192.168.1.145:20001,192.168.1.146:20001,192.168.1.147:20001
{
  data: '283KiB',
  docs: 10001,
  chunks: 2,
  'estimated data per chunk': '141KiB',
  'estimated docs per chunk': 5000
}
---
Totals
{
  data: '283KiB',
  docs: 10001,
  chunks: 2,
  'Shard shard1_rs': [
    '100 % data',
    '100 % docs in cluster',
    '29B avg obj size on shard'
  ]
}
###查询数量
[direct: mongos] graph> db.emp.find().count()
10001

创建第二个分片,验证数据均衡

构建复制集

### 初始化复制集shard2
docker exec -it shard2 mongosh 
test>  rs.initiate(
.1.146:20002" },
       { _id : 2, host : "192.168.1.147:20002" }
     ]
   }
...    {
...      _id: "shard2_rs",
...      members: [
...        { _id : 0, host : "192.168.1.145:20002" },
...        { _id : 1, host : "192.168.1.146:20002" },
...        { _id : 2, host : "192.168.1.147:20002" }
...      ]
...    }
...  );
{ ok: 1 }
##查看状态
shard2_rs [direct: other] test> rs.status()
{
  set: 'shard2_rs',
  date: ISODate("2024-08-11T09:13:59.622Z"),
  myState: 1,
  term: Long("1"),
  syncSourceHost: '',
  syncSourceId: -1,
  heartbeatIntervalMillis: Long("2000"),
  majorityVoteCount: 2,
  writeMajorityCount: 2,
  votingMembersCount: 3,
  writableVotingMembersCount: 3,
  optimes: {
    lastCommittedOpTime: { ts: Timestamp({ t: 1723367639, i: 6 }), t: Long("1") },
    lastCommittedWallTime: ISODate("2024-08-11T09:13:59.441Z"),
    readConcernMajorityOpTime: { ts: Timestamp({ t: 1723367639, i: 6 }), t: Long("1") },
    appliedOpTime: { ts: Timestamp({ t: 1723367639, i: 6 }), t: Long("1") },
    durableOpTime: { ts: Timestamp({ t: 1723367639, i: 6 }), t: Long("1") },
    lastAppliedWallTime: ISODate("2024-08-11T09:13:59.441Z"),
    lastDurableWallTime: ISODate("2024-08-11T09:13:59.441Z")
  },
  lastStableRecoveryTimestamp: Timestamp({ t: 1723367626, i: 1 }),
  electionCandidateMetrics: {
    lastElectionReason: 'electionTimeout',
    lastElectionDate: ISODate("2024-08-11T09:13:58.158Z"),
    electionTerm: Long("1"),
    lastCommittedOpTimeAtElection: { ts: Timestamp({ t: 1723367626, i: 1 }), t: Long("-1") },
    lastSeenOpTimeAtElection: { ts: Timestamp({ t: 1723367626, i: 1 }), t: Long("-1") },
    numVotesNeeded: 2,
    priorityAtElection: 1,
    electionTimeoutMillis: Long("10000"),
    numCatchUpOps: Long("0"),
    newTermStartDate: ISODate("2024-08-11T09:13:58.176Z"),
    wMajorityWriteAvailabilityDate: ISODate("2024-08-11T09:13:59.405Z")
  },
  members: [
    {
      _id: 0,
      name: '192.168.1.145:20002',
      health: 1,
      state: 1,
      stateStr: 'PRIMARY',
      uptime: 3713,
      optime: { ts: Timestamp({ t: 1723367639, i: 6 }), t: Long("1") },
      optimeDate: ISODate("2024-08-11T09:13:59.000Z"),
      lastAppliedWallTime: ISODate("2024-08-11T09:13:59.441Z"),
      lastDurableWallTime: ISODate("2024-08-11T09:13:59.441Z"),
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      electionTime: Timestamp({ t: 1723367638, i: 1 }),
      electionDate: ISODate("2024-08-11T09:13:58.000Z"),
      configVersion: 1,
      configTerm: 1,
      self: true,
      lastHeartbeatMessage: ''
    },
    {
      _id: 1,
      name: '192.168.1.146:20002',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 12,
      optime: { ts: Timestamp({ t: 1723367626, i: 1 }), t: Long("-1") },
      optimeDurable: { ts: Timestamp({ t: 1723367626, i: 1 }), t: Long("-1") },
      optimeDate: ISODate("2024-08-11T09:13:46.000Z"),
      optimeDurableDate: ISODate("2024-08-11T09:13:46.000Z"),
      lastAppliedWallTime: ISODate("2024-08-11T09:13:59.441Z"),
      lastDurableWallTime: ISODate("2024-08-11T09:13:59.441Z"),
      lastHeartbeat: ISODate("2024-08-11T09:13:58.165Z"),
      lastHeartbeatRecv: ISODate("2024-08-11T09:13:59.169Z"),
      pingMs: Long("0"),
      lastHeartbeatMessage: '',
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      configVersion: 1,
      configTerm: 0
    },
    {
      _id: 2,
      name: '192.168.1.147:20002',
      health: 1,
      state: 2,
      stateStr: 'SECONDARY',
      uptime: 12,
      optime: { ts: Timestamp({ t: 1723367626, i: 1 }), t: Long("-1") },
      optimeDurable: { ts: Timestamp({ t: 1723367626, i: 1 }), t: Long("-1") },
      optimeDate: ISODate("2024-08-11T09:13:46.000Z"),
      optimeDurableDate: ISODate("2024-08-11T09:13:46.000Z"),
      lastAppliedWallTime: ISODate("2024-08-11T09:13:59.441Z"),
      lastDurableWallTime: ISODate("2024-08-11T09:13:59.441Z"),
      lastHeartbeat: ISODate("2024-08-11T09:13:58.165Z"),
      lastHeartbeatRecv: ISODate("2024-08-11T09:13:59.169Z"),
      pingMs: Long("0"),
      lastHeartbeatMessage: '',
      syncSourceHost: '',
      syncSourceId: -1,
      infoMessage: '',
      configVersion: 1,
      configTerm: 0
    }
  ],
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1723367639, i: 6 }),
    signature: {
      hash: Binary.createFromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA=", 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1723367639, i: 6 })
}


添加到mongos中

docker exec -it mongos mongosh 
sh.addShard("shard2_rs/192.168.1.145:20002,192.168.1.146:20002,192.168.1.147:20002")
创建用户
docker exec -it  mongos mongosh --port 27017
use admin;db.createUser({user:"root",pwd:"boya1234",roles:[{role:"clusterAdmin",db:"admin"},{role:"clusterManager",db:"admin"},{role:"clusterMonitor",db:"admin"}]});
db.auth('root','boya1234');db.createUser({user: "rootTestSub",pwd: "boya1234",  roles: [{ role: "dbAdminAnyDatabase", db: "admin" },{ role: "readWriteAnyDatabase", db: "admin" }]});
##结果如下
,{role:"clusterManager",db:"admin"},{role:"clusterMonitor",db:"admin"}]});
{
  ok: 1,
  '$clusterTime': {
    clusterTime: Timestamp({ t: 1719207433, i: 4 }),
    signature: {
      hash: Binary.createFromBase64("AAAAAAAAAAAAAAAAAAAAAAAAAAA=", 0),
      keyId: Long("0")
    }
  },
  operationTime: Timestamp({ t: 1719207433, i: 4 })
}

<think>嗯,用户在使用docker-compose部署MongoDB分片副本集时,初始化后执行分片脚本总是失败。这个问题可能由多个因素引起,我需要一步步分析可能的原因,并提供解决方案。 首先,用户可能遇到网络连接问题。在Docker环境中,各个容器之间的通信依赖于正确的网络配置。如果分片服务、配置服务器和路由服务(mongos)不在同一个Docker网络中,它们可能无法相互访问。需要确认docker-compose.yml中所有服务都连接到同一个自定义网络,并且使用容器名称作为主机名进行通信。 接下来,服务启动顺序可能是一个问题。MongoDB的副本集初始化需要在所有节点启动并准备好之后才能进行。如果脚本在容器启动后立即执行,可能某些节点还未完成启动过程,导致连接失败。可以考虑在脚本中添加等待机制,例如使用循环检查端口是否开放,或者使用类似wait-for-it的工具来确保依赖服务已就绪。 然后,副本集配置是否正确也很关键。初始化分片前,每个分片的副本集必须正确配置,包括正确的成员信息和正确的优先级。用户需要检查副本集的初始化脚本,确认rs.initiate()命令是否正确指定了所有成员,并且配置服务器副本集是否已经成功初始化。此外,分片添加到集群时需要使用副本集名称作为主机地址,例如shard1/shard1-1:27017,shard1-2:27017,而不是单独的容器IP。 权限问题也不容忽视。如果启用了MongoDB的身份验证,执行脚本时需要提供正确的用户名和密码。需要确认mongos连接字符串中包含认证信息,并且用户拥有足够的权限执行分片操作。此外,Docker卷的权限可能导致初始化脚本无法写入数据,需要检查宿主机的目录权限是否允许容器内的MongoDB进程读写。 脚本语法错误或执行顺序错误可能也是一个原因。比如,必须先初始化所有分片的副本集,然后初始化配置服务器副本集,最后启动mongos并添加分片。如果顺序颠倒,会导致添加分片失败。需要确保脚本中的命令按照正确的顺序执行,并且每个步骤都成功完成后再进行下一步。 此外,日志分析是解决问题的关键。用户应检查各个容器的日志,查看是否有错误信息。使用docker-compose logs [服务名]可以获取详细的日志输出,帮助定位问题所在。例如,副本集初始化失败时,日志中可能会有连接超时或认证失败的信息。 举个例子,用户可能在添加分片时使用了错误的副本集名称或主机地址。正确的做法是使用副本集名称和容器名称组成的地址,确保mongos能够正确解析并连接到各个分片节点。另外,MongoDB的版本兼容性也可能导致问题,不同版本在配置上可能有差异,需要确认所有容器使用相同或兼容的版本。 最后,建议用户分步骤验证每个环节。首先确认各个副本集初始化成功,然后检查配置服务器是否正常,接着验证mongos能否正确连接配置服务器,最后逐步执行添加分片的命令。如果可能,提供一个示例的docker-compose文件和初始化脚本供用户参考,确保配置的正确性。</think>以下针对Docker-compose部署MongoDB分片副本集时初始化分片失败的常见问题,给出分步排查指南: --- ### 一、网络连接问题排查 #### 1. 检查Docker网络配置 ```yaml # docker-compose.yml关键配置示例 services: shard1-rs1: networks: - mongo_cluster # 必须使用相同网络 mongos: networks: - mongo_cluster networks: mongo_cluster: driver: bridge ``` #### 2. 验证容器间通信 ```bash # 进入mongos容器执行 docker-compose exec mongos bash ping shard1-rs1 # 应能解析容器IP telnet shard1-rs1 27017 # 验证端口可达性 ``` --- ### 二、服务启动时序问题 #### 1. 添加等待机制脚本 ```bash # wait-for.sh示例(需放入容器) until nc -z shard1-rs1 27017; do echo "等待shard1节点启动..." sleep 2 done ``` #### 2. 在初始化脚本中添加延迟 ```bash # 初始化分片脚本示例 sleep 20 # 等待副本集选举完成 mongosh --host mongos --eval "sh.addShard('shard1/shard1-rs1:27017')" ``` --- ### 三、副本集配置验证 #### 1. 检查副本集状态 ```javascript // 连接到分片容器执行 rs.status() // 应返回: // { // "set": "shard1", // "members": [ ... ], // "ok": 1 // } ``` #### 2. 正确的分片添加命令格式 ```javascript // 必须使用副本集名称+成员列表格式 sh.addShard("shard1/shard1-rs1:27017,shard1-rs2:27017,shard1-rs3:27017") ``` --- ### 四、典型错误解决方案 #### 1. 认证失败问题 ```yaml # mongos服务环境变量需包含 environment: MONGO_INITDB_ROOT_USERNAME: root MONGO_INITDB_ROOT_PASSWORD: example ``` ```javascript // 带认证的连接命令 mongosh -u root -p example --host mongos --eval "..." ``` #### 2. 数据持久化问题 ```yaml volumes: - ./shard1/data:/data/db # 确保宿主机目录存在且有写权限 ``` ```bash chmod -R 777 ./shard1/data # Linux系统权限修复 ``` --- ### 五、调试命令参考 #### 1. 查看实时日志 ```bash docker-compose logs -f shard1-rs1 # 查看指定分片日志 ``` #### 2. 强制重新初始化 ```bash docker-compose down -v # 清除旧数据卷 docker-compose up -d ``` --- ### 六、完整配置示例 ```yaml version: '3.7' services: configsvr1: image: mongo:6.0 command: mongod --configsvr --replSet cfgrs --bind_ip_all networks: - mongo_cluster shard1-rs1: image: mongo:6.0 command: mongod --shardsvr --replSet shard1 --bind_ip_all networks: - mongo_cluster mongos: image: mongo:6.0 command: mongos --configdb cfgrs/configsvr1:27017 --bind_ip_all ports: - "27017:27017" depends_on: - configsvr1 networks: - mongo_cluster networks: mongo_cluster: ``` --- ### 排查流程图 1. 检查网络连通性 → 2. 验证副本集状态 → 3. 检查认证配置 → 4. 查看错误日志 → 5. 验证分片添加命令格式 通过以上步骤,90%以上的分片初始化失败问题可以得到解决。若仍存在问题,建议提供具体的错误日志信息以便进一步分析。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值