1. MongoDB 副本集安装
1.1 项目结构
monstache-sync/
├── docker-compose.yml
├── init-replica.js
├── mongo-keyfile
1.1 创建 mongo-keyfile
MongoDB 副本集需要共享认证密钥。创建密钥文件:
sudo openssl rand -base64 756 | tr -d '\n' > mongo-keyfile
chmod 600 mongo-keyfile
chown 999:999 mongo-keyfile
1.2 创建 init-replica.js
副本集初始化脚本:
rs.initiate({
_id: "rs0",
members: [
{ _id: 0, host: "mongo1:27017" },
{ _id: 1, host: "mongo2:27017" },
{ _id: 2, host: "mongo3:27017" }
]
})
1.3 docker-compose.yml
services:
mongo1:
image: mongo:latest
container_name: mongo1
ports:
- 27017:27017
environment:
MONGO_INITDB_ROOT_USERNAME: root
MONGO_INITDB_ROOT_PASSWORD: 123456
command: ["mongod", "--replSet", "rs0", "--auth", "--keyFile", "/etc/mongo-keyfile"]
volumes:
- ./data/mongo1:/data/db
- ./mongo-keyfile:/etc/mongo-keyfile:ro
networks:
- mongo-cluster
mongo2:
image: mongo:latest
container_name: mongo2
ports:
- 27018:27017
command: ["mongod", "--replSet", "rs0", "--auth", "--keyFile", "/etc/mongo-keyfile"]
volumes:
- ./data/mongo2:/data/db
- ./mongo-keyfile:/etc/mongo-keyfile:ro
networks:
- mongo-cluster
mongo3:
image: mongo:latest
container_name: mongo3
ports:
- 27019:27017
command: ["mongod", "--replSet", "rs0", "--auth", "--keyFile", "/etc/mongo-keyfile"]
volumes:
- ./data/mongo3:/data/db
- ./mongo-keyfile:/etc/mongo-keyfile:ro
networks:
- mongo-cluster
mongo-init-replica:
image: mongo:latest
container_name: mongo-init-replica
depends_on:
- mongo1
- mongo2
- mongo3
volumes:
- ./init-replica.js:/init-replica.js
- ./mongo-keyfile:/etc/mongo-keyfile:ro
entrypoint: ["bash", "-c", "sleep 5 && mongosh --host mongo1 --username root --password 123456 --authenticationDatabase admin /init-replica.js"]
networks:
- mongo-cluster
networks:
mongo-cluster:
driver: bridge
1.4 启动副本集
在 monstache-sync 目录下运行:
docker-compose up -d
5. 验证副本集是否初始化成功
进入 mongo1:
docker exec -it mongo1 mongosh -u root -p 123456 --authenticationDatabase admin
然后执行:
rs.status()
2. 配置 Monstache 同步服务
2.1 项目结构
monstache-sync/
├── config.toml
2.2 创建config.toml
# 连接 MongoDB (其中mongo1是容器名,可替换为实际的IP,不是同一个网络内)
mongo-url = "mongodb://root:123456@mongo1:27017/admin"
# 连接 Elasticsearch (真实的IP或者容器名,但是容器名确保同一个网络)
elasticsearch-urls = ["http://192.168.167.175:9200"]
# Elasticsearch 用户名
elasticsearch-user = "elastic"
# Elasticsearch 密码
elasticsearch-password = "someliber"
# 启动时一次性全量读取 MongoDB 数据写入 Elasticsearch(格式为 数据库.集合)
direct-read-namespaces = ["test.records"]
# 实时监听 MongoDB 变更(需要副本集)插入、更新、删除会自动同步到 Elasticsearch
change-stream-namespaces = ["test.records"]
# 写入 Elasticsearch 时仅更新变动字段(节省 IO)
index-as-update = true
# 断点续传设置(推荐开启)
resume = true
resume-name = "default"
resume-strategy = 1
# 批处理优化(适合千万级别数据)
direct-read-concur = 4
# 启用统计信息输出
stats = true
index-stats = false
[[mapping]]
namespace = "test.records"
index = "records_index" # 设置 ES 中的目标索引名
更多配置参考:https://rwynn.github.io/monstache-site/config
2.3 启动monstache
2.3.1 如果使用的是 Docker 内部 MongoDB 副本集
docker run -d --name monstache --network monstache-sync_mongo-cluster -v $(pwd)/config.toml:/config.toml rwynn/monstache:6.7.22 -f /config.toml
注意:–network 必须是 docker-compose 自动创建的网络名称,可用 docker network ls 查看。
2.3.2 如果 MongoDB 是物理机(非 Docker)
docker run -d --name monstache -v $(pwd)/config.toml:/config.toml rwynn/monstache:6.7.22 -f /config.toml
3. 使用 Kibana 验证同步效果
3.1 查询索引信息
Kibana → Dev Tools:
# 查看ES全部索引,是否存在records_index索引
GET /_cat/indices
# 查看records_index索引的结构是否跟数据库结构一致。
GET /records_index/_mapping
# 查看records_index索引下的全部文档数,即数据量
GET /records_index/_count
# 查看records_inde索引的前10条数据
GET /records_index/_search
3.2 数据同步验证
插入新数据
Mongo 中插入新记录:
db.records.insertOne({ name: "Test", value: 123 })
然后检查 Kibana 中 /records_index/_count是否增加。
修改已有数据
Mongo 中更新字段:
db.records.updateOne({ name: "Test" }, { $set: { value: 456 } })
Kibana 中再次 /records_index/_search,确认是否同步更新。
4.总结
本案例实现了:
(1)MongoDB 副本集部署与认证配置
(2)实时监听 MongoDB 的变更
(3)自动同步到 Elasticsearch
(4)支持断点续传、增量更新
(5)可结合 Kibana 做可视化分析