MongoDB CDC 方案 Change Stream

说明:

​ 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

  • 5
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值