Change Stream是MongoDB用于实现变更追踪的解决方法,类似关系数据库的触发器。
Change Stream与关系数据库的触发器的对比
Change Stream | 关系数据库的触发器 | |
---|---|---|
触发方式 | 异步 | 同步 |
触发位置 | 应用回调事件 | 数据库触发器 |
触发次数 | 每个订阅事件的客户端 | 1次 |
故障恢复 | 可以从上次断点重新触发 | 事务回滚 |
Change Stream能够跟踪的变更事件包括
- insert/update/delete
- drop
- rename
- dropDatabase
- invalidate
注:drop/rename/dropDatabase将导致invalidate被触发,并关闭Change Stream
Change Stream也可以通过聚合管道的过滤,使它仅仅跟踪某些变更的事件,例:
db.collection.watch([{
$match: {
operationType: {
$in: ['insert', 'delete']
}
}
}])
上述例子用于跟踪操作为insert和delete的事件。
Change Stream的故障恢复:
# <_id>为上一次回调所返回的_id值,用于恢复到那次断点
db.collection.watch([],{resumeAfter: <_id>})
Change Stream开启条件
- 配置文件添加replication.enableMajorityReadConcern: true,才可以使用Change Stream
- 若集群中无法满足{w: “majority”}时,将不会触发Change Stream
例如PSA架构中的S因故障宕机,执行操作时将满足{w: “majority”},也就将无法触发Change Stream,故PSA架构不建议使用。
使用场景
- 跨集群的变更复制----源集群中订阅Change Stream,一旦得到任何变更立即写入目标集群
- 微服务联动----一个微服务变更数据库时,通知其他服务做出相应变化
- 需要系统联动的场景
注意
- Change Stream依赖于oplog,中断时间不能超过oplog回收的最大时间窗,如果超过oplog回收的最大时间窗,将无法使Change Stream从上次断点的位置重新触发
- 执行update操作时,如果只更新了部分数据,那么Change Stream通知的也是增量部分
- 执行delete操作时,Change Stream通知的也只是删除数据的_id,并不会通知全部数据
注:MongoDB实例使用Change Stream的代码将在后面有时间的时间粘贴上去