使用 pymongo 的 mongo 副本集出现 ServerSelectionTimeoutError

问题描述 投票:0回答:2

我正在尝试使用 pymongo 连接到 MongoDB 副本集,但我不断收到错误:

pymongo.errors.ServerSelectionTimeoutError: No replica set members match selector
。在错误消息中,还指定我的拓扑类型是
ReplicaSetNoPrimary
,这很奇怪,因为与 mongo bash 连接显示了清晰的主节点。

请注意,副本集工作正常,并且可以通过主节点上的 mongo bash 使用。 此外,我还添加了防火墙规则以允许指定端口上的入站和出站流量,只是为了确保这不是问题。 我正在使用 docker-compose 作为集群。文件:

version: "3.9"
services:
  mongo-master:
    image: mongo:latest
    container_name: mongo_master
    volumes:
      - ./data/master:/data/db
    ports:
      - 27017:27017
    command: mongod --replSet dbrs & mongo --eval rs.initiate(`cat rs_config.json`)
    stdin_open: true
    tty: true

  mongo-slave-1:
    image: mongo:latest
    container_name: mongo_slave_1
    volumes:
      - ./data/slave_1:/data/db
    ports:
      - 27018:27017
    command: mongod --replSet dbrs
    stdin_open: true
    tty: true

  mongo-slave-2:
    image: mongo:latest
    container_name: mongo_slave_2
    volumes:
      - ./data/slave_2:/data/db
    ports:
      - 27019:27017
    command: mongod --replSet dbrs
    stdin_open: true
    tty: true

上面使用的rs_config.json文件:

{
    "_id" : "dbrs",
    "members" : [
        {
            "_id" : 0,
            "host" : "mongo_master:27017",
            "priority" : 10
        },
        {
            "_id" : 1,
            "host" : "mongo_slave_1:27017"
        },
        {
            "_id" : 2,
            "host" : "mongo_slave_2:27017"
        }
    ]
}

此处最后一行出现错误:

self.__client = MongoClient(["localhost:27017", "localhost:27018", "localhost:27019"], replicaset="dbrs")
self.__collection = self.__client[self.__db_name][collection.value]
self.__collection.insert_one(dictionary_object)

为了简洁起见,我省略了一些代码,但您可以假设所有类属性和dictionary_object都根据pymongo文档定义良好。 另请注意,我尝试了许多不同的方法来初始化 MongoClient,包括连接字符串(如文档中所示),以及一些博客中建议的

connect=False
可选参数。问题依然存在...

编辑:我尝试将“mongo_master”添加到指向 127.0.0.1 的 etc/hosts 文件中,并将连接字符串从 localhost 更改为该地址,并且它可以与副本集一起使用。这是一个糟糕的解决方法,但也许可以帮助找到解决方案。

预先感谢您的帮助!

mongodb pymongo database-replication
2个回答
1
投票

要从外部客户端连接到 MongoDB 副本集,您必须能够从本地客户端解析主机名。

https://docs.mongodb.com/manual/tutorial/deploy-replica-set/#connectivity

确保网络流量可以在集合的所有成员和网络中的所有客户端之间安全地传递。

因此,将以下内容添加到您的 /etc/hosts 文件中:

127.0.0.1 mongodb-1
127.0.0.1 mongodb-2
127.0.0.1 mongodb-3

为了能够内部和外部连接,您需要在不同的端口上运行每个 MongoDB 服务。

以下脚本将启动 3 节点 MongoDB 复制集并运行测试客户端。我建议使用 Bitnami 映像,因为它会为您处理 replset 启动。 (大量借用这个配置

#!/bin/bash

PROJECT_NAME=replset_test

MONGODB_VERSION=4.4
PYTHON_VERSION=3.9.6
PYMONGO_VERSION=4.0.1

cd "$(mktemp -d)" || exit

cat << EOF > Dockerfile
FROM python:${PYTHON_VERSION}-slim-buster
COPY requirements.txt /tmp/
RUN pip install -r /tmp/requirements.txt
COPY ${PROJECT_NAME}.py .
CMD [ "python", "./${PROJECT_NAME}.py" ]
EOF

cat << EOF > requirements.txt
pymongo==${PYMONGO_VERSION}
EOF

cat << EOF > ${PROJECT_NAME}.py
from pymongo import MongoClient

connection_string = 'mongodb://root:password123@mongodb-1:27017,mongodb-2:27018,mongodb-3:27019/mydatabase?authSource=admin&replicaSet=replicaset'
client = MongoClient(connection_string)
db = client.db
db['mycollection'].insert_one({'a': 1})
record = db['mycollection'].find_one()
if record is not None:
    print(f'{__file__}: MongoDB connection working using connection string "{connection_string}"')
EOF

cp ${PROJECT_NAME}.py ${PROJECT_NAME}_external.py

cat << EOF > docker-compose.yaml
version: '3.9'

services:
  mongodb-1:
    image: docker.io/bitnami/mongodb:${MONGODB_VERSION}
    ports:
      - 27017:27017
    environment:
      - MONGODB_ADVERTISED_HOSTNAME=mongodb-1
      - MONGODB_PORT_NUMBER=27017
      - MONGODB_REPLICA_SET_MODE=primary
      - MONGODB_ROOT_PASSWORD=password123
      - MONGODB_REPLICA_SET_KEY=replicasetkey123
    volumes:
      - 'mongodb_master_data:/bitnami/mongodb'

  mongodb-2:
    image: docker.io/bitnami/mongodb:${MONGODB_VERSION}
    ports:
      - 27018:27018
    depends_on:
      - mongodb-1
    environment:
      - MONGODB_ADVERTISED_HOSTNAME=mongodb-2
      - MONGODB_PORT_NUMBER=27018
      - MONGODB_REPLICA_SET_MODE=secondary
      - MONGODB_INITIAL_PRIMARY_HOST=mongodb-primary
      - MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD=password123
      - MONGODB_REPLICA_SET_KEY=replicasetkey123

  mongodb-3:
    image: docker.io/bitnami/mongodb:${MONGODB_VERSION}
    ports:
      - 27019:27019
    depends_on:
      - mongodb-1
    environment:
      - MONGODB_ADVERTISED_HOSTNAME=mongodb-3
      - MONGODB_PORT_NUMBER=27019
      - MONGODB_REPLICA_SET_MODE=secondary
      - MONGODB_INITIAL_PRIMARY_HOST=mongodb-primary
      - MONGODB_INITIAL_PRIMARY_ROOT_PASSWORD=password123
      - MONGODB_REPLICA_SET_KEY=replicasetkey123

  ${PROJECT_NAME}:
    container_name: ${PROJECT_NAME}
    build: .
    depends_on:
      - mongodb-1
      - mongodb-2
      - mongodb-3

volumes:
  mongodb_master_data:
    driver: local
EOF

docker rm --force $(docker ps -a -q --filter name=mongo) 2>&1 > /dev/null
docker rm --force $(docker ps -a -q --filter name=${PROJECT_NAME}) 2>&1 > /dev/null
docker-compose up --build -d
python ${PROJECT_NAME}.py
docker ps -a -q --filter name=${PROJECT_NAME}
docker logs $(docker ps -a -q --filter name=${PROJECT_NAME})

如果一切正常,您将获得确认内部和外部连接的输出:

/tmp/tmp.QM9tQPE8Dj/replset_test.py: MongoDB connection working using connection string "mongodb://root:password123@mongodb-1:27017,mongodb-2:27018,mongodb-3:27019/mydatabase?authSource=admin&replicaSet=replicaset"
d53e8c41ad20
//./replset_test.py: MongoDB connection working using connection string "mongodb://root:password123@mongodb-1:27017,mongodb-2:27018,mongodb-3:27019/mydatabase?authSource=admin&replicaSet=replicaset"

0
投票

我在 cpanel 服务器上托管它时遇到此错误。我也可以获得帮助吗?

尚未找到副本集成员,超时:5.0s,拓扑描述:]>

© www.soinside.com 2019 - 2024. All rights reserved.