变更流生产建议
如果删除或重命名一个集合或数据库,并打开了相应变更流,则变更流游标会在变更流前进到 oplog 中的该点时关闭。使用 选项的变更流游标可能会对查找文档返回 fullDocument :
updateLookup
null
。
变更流的响应文档必须遵循 16MB 的 BSON 文档大小限制。根据您启用变更流的集合中文档的大小,若生成的通知文档超出 16MB,则通知可能会失败。例如,将变更流配置为“返回整个更新后的文档以响应”条件下的文档更新操作,或对文档大小等于或略低于限制的文档进行插入/替换操作。
重要
从版本6.0.9开始, 您可以使用 $changeStreamSplitLargeEvent
聚合阶段将事件分割为较小的片段。
副本集
对于具有仲裁节点的副本集,如果有足够的数据承载节点不可用,则变更流可能会保持空闲状态,从而导致操作无法多数提交。
例如,试想一个由两个数据承载节点和一个仲裁节点组成的三节点副本集。如果其中的从节点出现故障(例如由于错误或升级),写入操作无法提交到多数节点。变更流将保持打开状态,但不会发送任何通知。
在这种情况下,只要应用程序收到的最后一个操作仍在副本集的 oplog 中,应用程序就可以同步上停机期间发生的所有操作。
如果估计会出现长时间的停机(例如升级或重大灾难),请考虑增加 oplog 的大小,以便操作的保留时间长于估计的停机时间。使用 rs.printReplicationInfo()
获取有关 oplog 状态的信息,包括 oplog 的大小和操作的时间范围。
分片集群
变更流通过一个全局逻辑时钟为跨分片的变更提供统一的排序。MongoDB 确保变更顺序得到保留,并且可以按照接收的顺序合理地解释变更流通知。例如,在为 3 个分片组成的分片集群启用变更流游标时,游标将按照这 3 个分片上变更发生的总体顺序返回变更通知。
为了保证变更的总体排序,对于每个变更通知,mongos
都会检查每个分片,确认该分片是否已看到更新的变更。如果分片集群中有一个或多个分片针对该集合没有或者几乎没有活动(称为“冷”分片),因为 mongos
仍必须检查这些冷分片以保证变更的总体排序,所以该分片集群会对变更流的响应时间造成不利影响。对于地理上分布的分片或大多数操作发生在集群中的分片子集上的工作负载,这种影响可能会更加明显。要尽量减少冷分片的延迟,可以指定一个较低的 periodicNoopIntervalSecs
值。
如果分片集合的活动水平很高,则 mongos
可能无法跟上所有分片的变更。请考虑对这些类型的集合使用通知筛选器。例如,传递配置为仅筛选 insert
操作的 $match
管道。
索引与性能
change stream 不能使用索引。MongoDB 不支持在 oplog 集合上创建索引。因此,请避免打开大量具有针对性的 change stream,因为它们可能会影响服务器的性能。
变更流优化
从 MongoDB 5.1 开始,我们对变更流进行了优化,提高了资源利用率,并加快了某些聚合管道阶段的处理速度。
变更流和孤立文档
从 MongoDB 5.3 开始,在范围迁移期间,不会为孤立文档的更新生成 change stream 事件。