MongoDB 3.6已经GA有一段时间,网络上对于该版本新特性的详细介绍文章比较少为此借机会对部分新特性做一个相对详细的介绍。基于早期MongoDB版本实现如跨平台数据同步、消息通知、ETL及oplog备份等服务时大多依赖于 Tailable Cursors 的方式。当然这样的实现一来相对复杂同时也存在着一些风险(如不同版本oplog兼容性及过滤特定操作类型等)。
Change streams(暂且叫变更流)的出现不仅为业务提供了实时获取数据库数据变化的简易接口,同时又避免了原来使用tail oplog 的复杂和风险性。下面我们来看看如何来正确使用 Change stream 。
PS:丰富的一线技术、多元化的表现形式,尽在“HULK一线技术杂谈”,点关注哦!
Change stream
使用条件限制
只用于 replica sets 和 sharded clusters ,单节点因为没有oplog故不支持。
复制协议必须是pv1 存储引擎必须是 WiredTiger
驱动实现接口
MongoDB Shell 接口说明
MongoDB 3.6 版本只实现了集合粒度的 change stream 具体方法如下:
db.collection.watch(pipeline, options)
该方法实际上是在集合collection上开启一个change stream的游标。
测试用例(mongo shell环境+副本集primary节点):
1
创建一个简单 Change Stream 游标并进行循环迭代
游标创建后通过对游标进行迭代,只能获取test集合上insert操作类型的信息。其他支持的操作类型update、delete、replaceOne 及输出信息详细说明可参见:Change Events
https://docs.mongodb.com/manual/reference/change-events/
3
ChangeStream 的”断线恢复”功能
ChangeStream还支持”断线恢复”功能即当游标因为意外情况关闭后可以通过之前的token信息进行恢复(前提条件是token对应的oplog没有被覆盖),具体使用如下:
其他的使用场景,读者自行测试即可。
注意事项
1.尝试在单节点(非副本集节点)上创建ChangeStream游标会报如下错误:
2. ChangeStream 只发布持久化到大多数(majority-committed)节点的数据变化通知
3.要想在集合上创建ChangeStream游标用户必须对集合具有读权限
4.对于分片集合带有multi:true 的更新操作可能会导致发布孤立文档的变更消息
5.对于如创建索引的操作游标迭代时直接忽略该操作但是如果 dropDatabase 或对集合进行 rename、drop 操作则会触发游标退出并输出如下信息:
6. 当 ChangeStream 游标因特定操作导致退出后,Mongo Shell 下不会自动恢复,而对于3.6版本系列的各语言驱动则会尝试一次自动恢复。
7. 当对应的 token 信息对应的 oplog 不存在然后尝试恢复ChangeStream 游标时不会报错但尝试对集合进行数据操作后会报如下错:
MongoDB 4.0 的变化
因为4.0版本需要支持集群及库级别的ChangeStream 故会增加如下的pipeline 命令行语法:
另外,4.0版本在游标恢复时增加了一个 startAtOperationTime(表示操作时间)参数该参数指定从哪个操作的时间点开始恢复游标,可以通过事件的输出clusterTime 字段获得(其实对应了oplog里的操作时间),值得注意的是该参数不能和resumeAfter同时使用。
再则,4.0版本为了支持多文档事务在事件输出文档中增加了另外两个参数txnNumber 和 lsid 分别表示事务号及会话ID ,需要注意的是同一个会话内事务ID从0开始自增。
ChangeStream 的介绍都到此为止,因为时间和精力有限难免有些错误还请及时反馈,祝各位玩得开心。
参考链接:
https://docs.mongodb.com/manual/changeStreams/
https://docs.mongodb.com/manual/reference/method/db.collection.watch/#db.collection.watch
https://docs.mongodb.com/manual/administration/change-streams-production-recommendations/
https://docs.mongodb.com/manual/reference/change-events/
https://docs.mongodb.com/manual/reference/method/cursor.isExhausted/#cursor.isExhausted
https://github.com/mongodb/specifications/blob/master/source/change-streams/change-streams.rst
HULK一线技术杂谈
由360云平台团队打造的技术分享公众号,内容涉及云计算、数据库、大数据、监控、泛前端、自动化测试等众多技术领域,通过夯实的技术积累和丰富的一线实战经验,为你带来最有料的技术分享