说明:
1 前提条件 MongoDB 3.6 + 才可以使用 Change Stream
2 必须集群模式 MongoDB
3 复制协议 pv1 、存储引擎 WiredTiger
一 概述
1.1 文档说明
本文档实现使用 MongoDB 功能 Change Stream 实现 CDC 。
1.2 选型
各大厂商 CDC 功能基本都为收费,所以免费 CDC 思路基本采用触发器或日志解析方式。MongoDB 通过探索与寻找最终确定两个范围 :
1 阿里巴巴 MongoShake
MongoShake is a universal data replication platform based on MongoDB’s oplog
2 MongoDB 3.6 + change Stream
因 3.6 以后 MongoDB 自己就支持 MangoDB CDC 功能,所以选择官方提供的 Change Stream 风险、复杂度、性能对比下更优。
1.3 环境说明
Linux : Linux version 2.6.32-573.el6.x86_64
CentOS release 6.7
集群数量: 三节点
MongoDB: Version 4.4.2
JDK: 1.8.0_111
实现语言: Java
1.4 适用情况
1.4.1 Change Stream 需要 MongoDB 3.6+ (3.6 支持 Change Stream 表级监控,4x 以上增加对库级)
1.4.2 MongoDB 必须为集群模式 复制协议必须为 pv1、存储引擎 WiredTiger
二 MongoDB 4.4.2 集群安装篇(Linux)
2.1 本次安装包地址
wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel62-4.2.11.tgz
其他版本自行选择,官网地址:
https://www.mongodb.com/try/download/community
选择如图:
2.2 解压缩,初始化文件夹
2.1 解压缩
tar -zxvf ***.tar
2.2 进入文件目录下并创建初始文件夹
mkdir -p data/log
mkdir -p data/db
mkdir -p /var/lib/mongo
mkdir -p /var/log/mongodb
2.3 修改配置文件
cd bin
echo ''> mongo.conf
#mongo.conf 内容如下:
# 端口默认 不冲突不必修改
port = 27017
#数据目录 根据自己目录来,我这个是不标准的测试环境,没有数据盘所以放入 /home 下。别学我
dbpath = /home/opt/mongoDB/mongodb-linux-x86_64-rhel62-4.2.11/data/db
#日志所在目录
logpath = /home/opt/mongoDB/mongodb-linux-x86_64-rhel62-4.2.11/data/logs/mongodb.log
#日志输出方式
logappend = true
# 在后台启动
fork=true
# 0.0.0.0 表示任意IP均可连接
bind_ip=0.0.0.0
#副本集名称
replSet=testmongo
2.4 启动集群服务
3 个节点都要启动
启动命令:
/home/opt/mongoDB/mongodb-linux-x86_64-rhel62-4.2.11/bin/mongod -f mongo.conf
关闭命令:
mongod -f /usr/local/mongodb/bin/mongo.conf --shutdown
2.5 设置集群
进入 mongo
use admin
设置变量
testmongo= {
_id: "testmongo",
members: [
{
_id: 0,
host: "192.168.3.64",
"priority":2
},
{
_id: 1,
host: "192.168.3.65",
"priority":1
}
,
{
_id: 2,
host: "192.168.3.107",
"priority":3
}
]
}
执行初始化
rs.initiate(testmongo)
退出 客户端并再次进入可以看到 client 变化。
附状态查看命令:
集群名.status()
2.6 测试集群
use dbtest
db.test_str.insert({"id":"xxx24x"})
db.test_str.find().pretty()
slave 节点查询报错 输入
testmongo.slaveOk()
rs.initiate(testmongo)
退出 客户端并再次进入可以看到 client 变化。
查看命令:
集群名.status()
2.6 测试集群
use dbtest
db.test_str.insert({"id":"xxx24x"})
db.test_str.find().pretty()
slave 节点查询报错 输入
testmongo.slaveOk()
三 Change Stream(UDISR)
3.1 Change Stream 跟踪事件
Change Stream 是MongoDB用于实现变更追踪的解决方法,类似关系数据库的触发器。
Change Stream能够跟踪的变更事件包括
- insert/update/delete
- drop
- rename
- dropDatabase
- invalidate
注:drop/rename/dropDatabase将导致invalidate被触发,并关闭Change Stream
3.2 Change Stream 注意事项
- Change Stream依赖于oplog,中断时间不能超过oplog回收的最大时间窗,如果超过oplog回收的最大时间窗,将无法使Change Stream从上次断点的位置重新触发
- 执行update操作时,如果只更新了部分数据,那么Change Stream通知的也是增量部分
- 执行delete操作时,Change Stream通知的也只是删除数据的_id,并不会通知全部数据
3.3 官方Change Stream 资料地址 :
ChangeStream 说明:
https://docs.mongodb.com/manual/changeStreams/
事件说明:
https://docs.mongodb.com/manual/reference/change-events/
四 增删改捕获数据展示
4.1 insert
# 测试语句
db.tdt.insert({_id:222,name:"kafka"})
db.tdt.find()
捕获数据如下:
4.2 update
db.tdt.insert({_id:123,name:"flink"})
db.getCollection('tdt').update({name:"flink"},{$set:{"name": "fflliinnkk"}})
捕获数据如下:
4.3 delete
db.tdt.insert({_id:3,name:"kafka"})
db.tdt.insert({_id:5,name:"kafka"})
db.tdt.remove({name:'kafka'})
捕获数据如下(本次删除两条匹配数据,会触发两条监听):
观察可以得到 每个事件返回的格式不一样。需要定制解析
MongoDB 语法参考:
https://www.cnblogs.com/ywjfx/p/10129007.html
4.4 注意 update 捕获问题
update 和 save 的特殊性
如图 update 更新不存在的列时,会形成追加数据形式。如果是 MongoDB CDC MongoDB 自然没问题。 可更多是 CDC 到 Hive,HBase 等数据中,故需要特殊制定存储策略。 我们很难影响客户(数据源)来做为自己做特殊改变,所以一般需要自己进行二次处理。
参考说明:
MongoDB 使用 update() 和 save() 方法来更新集合中的文档
参数说明:
query : update的查询条件,类似sql update查询内where后面的。
update : update的对象和一些更新的操作符(如inc…)等,也可以理解为sql update查询内set后面的
upsert : 可选,这个参数的意思是,如果不存在update的记录,是否插入objNew,true为插入,默认是false,不插入。
multi : 可选,mongodb 默认是false,只更新找到的第一条记录,如果这个参数为true,就把按条件查出来多条记录全部更新。
writeConcern :可选,抛出异常的级别。
1 、添加一个字段. table 代表表名 , 添加字段 content,字符串类型。
db.table.update({}, {$set: {content:”“}}, {multi: true})
2、删除一个字段
db.table.update({},{$unset:{content:”“}},false, true)
五 代码部分 Java 实现
代码如下:
https://download.csdn.net/download/cs261244787/13187852