docker搭建mongodb单节点副本集的实现
目录
- 背景
- 启动步骤
- 可能遇到的问题
- 解决办法
背景
在开发中,我们很容易通过docker启动一个普通的mongodb数据库服务。但是有时候为了保持与线上环境一致,或者为了利用mongodb副本集的某些特性,我们需要在本地部署mongodb副本集。副本集往往需要启动多个mongodb服务作为副本集成员,而通常用于开发的笔记本资源比较有限。鉴于此,官方文档给了解决办法,可以直接将一个单节点mongodb服务转换为单节点副本集(standlone replica set)(https://www.mongodb.com/docs/manual/tutorial/convert-standalone-to-replica-set/)
启动步骤
按照官方文档的说明,如果利用docker部署服务,那么依次有如下步骤:
第一步, 假如已经存在一个运行中的普通mongodb容器服务。此时,需要关闭服务,并通过指定
--replSet参数重启该服务或者重新启动一个新的mongodb容器。假如mongodb的服务名及容器名均为
mongodb_rs,运行端口映射为27017:27017,副本集名称为rs0,数据存储目录指定为/srv/mongodb/db0,数据卷挂载目录为./data:/srv/mongodb/db0。那么docker-compose.yaml文件可编写如下:version: "3" services: mongodb_rs: network_mode: bridge container_name: mongodb_rs image: mongo:latest ports: - "27017:27017" restart: always # environment: # MONGO_INITDB_ROOT_USERNAME: username # MONGO_INITDB_ROOT_PASSWORD: pwd command: mongod --port 27017 --replSet rs0 --dbpath /srv/mongodb/db0 volumes: - ./data:/srv/mongodb/db0第二步,执行如下命令启动mongodb服务
docker-compose up -d mongodb_rs
第三步,进入容器mongosh,执行初始化副本集命令
docker exec -it mongodb_rs mongo
# mongosh rs.initiate() # --- # > rs.initiate() # { # "info2" : "no configuration specified. Using a default configuration for the set", # "me" : "f76081e20602:27017", # "ok" : 1 # } # rs0:SECONDARY> # rs0:PRIMARY>|第四步,退出容器,容器服务正常运行
可能遇到的问题
按照上述步骤执行后,通常情况下容器服务可以正常运行,应用程序可以正常进行连接,到这里基本就成功了。以golang代码测试:
package main
import (
"context"
"fmt"
"log"
"go.mongodb.org/mongo-driver/bson"
"go.mongodb.org/mongo-driver/mongo"
"go.mongodb.org/mongo-driver/mongo/options"
)
func main() {
clientOpts := options.Client().ApplyURI("mongodb://localhost:27017/?replicaSet=rs0")
client, err := mongo.Connect(context.TODO(), clientOpts)
if err != nil {
log.Fatal(err)
}
colls, _ := client.Database("admin").ListCollectionNames(context.TODO(), bson.M{})
fmt.Printf("colls: %v\n", colls)
}
// colls: [system.keys system.version]
但是有时候可能会出现本地程序代码无法连接副本集服务,控制台会报类似连接错误的问题,报错的原因在于副本集无法识别成员host。
在单节点副本集下,本机既是主也是从,在容器的mongo shell中可进行查看, members只有一个成员,其name为"f76081e20602:27017", 所以如果你遇到无法连接或者其他类似错误,根本原因在于本地启动的这个副本集无法识别f76081e20602这个host。
rs.status()
---
rs0:PRIMARY> rs.status()
{
"set" : "rs0",
"date" : ISODate("2022-05-06T18:59:21.417Z"),
# ...
"members" : [
{
"_id" : 0,
"name" : "f76081e20602:27017",
"health" : 1,
"state" : 1,
"stateStr" : "PRIMARY",
"uptime" : 1433,
"optime" : {
"ts" : Timestamp(1651863555, 1),
"t" : NumberLong(1)
},
# ...
}
],
# ...
}
解决办法
曾经遇到上述问题,百度csdn上有多篇内容一样的文章,都说这种情况需要将应用程序也通过容器进行启动,并将应用程序与mongdb副本集服务置于同一个docker网络中,就可以正常连接了。这样做确实也可行,但似乎过于麻烦了,有点走歪路的感觉。
从上述内容已经知道是副本集成员host的识别问题,那么在初始化mongodb副本集时,我们可以显式的去指定成员host,不使用默认的副本集配置。具体而言,将启动步骤中的第三步更改为:
进入
mongoshdocker exec -it mongodb_rs mongo
自定义配置
# mongosh conf = { _id : "rs0", members: [ { _id: 0, host: "<本机ip地址>:27017" }, ] }初始化副本集
# mongosh rs.initiate(conf)
如此,通过指定成员ip,mongo单节点副本集就可以准确的识别到副本集成员,对于多节点副本集如果出现连接问题,此方法同样适用。
您可能感兴趣的文章
- 12-20Kubernetes中使用临时容器进行故障排查的方法
- 12-20Nginx设置HTTPS的方法步骤
- 12-20二进制方式安装 Kubernetes1.18.3版本实现脚本
- 12-20Nginx工作模式及代理配置的使用细节
- 12-20ZooKeeper分布式协调服务设计核心概念及安装配置
- 12-20Kubernetes部署可视化地图的十个步骤
- 12-20关于docker清理Overlay2占用磁盘空间的问题(亲测有效)
- 12-20Docker compose配置文件写法及命令使用示例
- 12-20openwrt安装docker并启动的操作方法
- 12-20云原生Kubernetes初始化容器Init使用教程


阅读排行
推荐教程
- 12-07一文教你怎么选择Tomcat对应的JDK版本
- 12-07新版Eclipse集成Tomcat时找不到server选项的解决方法
- 12-06IIS7 应用程序池自动回收关闭的解决方案
- 12-05Windows Server 2019安装VMware
- 12-05Windows服务器默认IE浏览器无法下载文件的解决方法
- 12-05Docker安装Jenkins全过程
- 12-19Zabbix SAML SSO 登录绕过漏洞的操作流程
- 12-15Docker-Compose搭建Spark集群的实现方法
- 12-14Docker Desktop无法正常启动解决(failed to start...)
- 12-14k8s 与docker空间使用分析与清理方法





