首页 > 解决方案 > 跟踪截止日期以发送提醒的设计模式

问题描述

我需要在某个截止日期前几天向用户发送通知。我目前的设计是使用 Cloud Scheduler 定期调用作业,然后在截止日期的功能中查找所有匹配的记录,然后提醒它们。一切都很好,除了我需要按时创建一个索引,这对于缩放来说不是一个好主意,因为索引单调增加的值会产生热点。那么,对于这种有效的业务需求,最好的可扩展设计选择是什么?请注意,我已经熟悉为时间戳添加一些值的前缀,以便在分区内跟踪排序。但是,调度作业需要发现所有的最后期限,并且它'

标签: google-cloud-platformgoogle-cloud-datastore

解决方案


恕我直言,您的特定使用上下文对热点问题并不像您想象的那么敏感。

当您对范围很窄的按字典顺序关闭的文档(在您的情况下是基于时间戳的通知计划索引)具有非常高的读/写率时,该问题确实适用。

当您修改计划时,会发生对索引的写入。正如您在评论中提到的,这不是一个大问题,因为您可以轻松控制此类更新的速率。

即使您偶尔有广泛的日程更新,我也会提交,在这种情况下由于争用导致的索引更新延迟峰值并不是什么大问题:您提到通知是在截止日期前几天发送的——谁在乎这些通知是否延迟几分钟?此外 - 在读取方面,您可以使用keys_only 查询,然后使用直接键查找来消除最终一致性(这对争用/索引更新延迟很敏感)。

至于读取方面-您通常一次对索引进行一次读取操作-查询获取要在一个时间间隔内发送的通知列表。一旦作业获得列表,通常就不需要再访问索引:作业只是安排负责发送列表中通知的后续作业(可能访问相应的通知实体,但不能访问索引本身!)。当然,我假设您将这些查询作业彼此分开安排。

即使您使用游标来解决查询返回的列表中的通知数量太多而无法一次性处理的情况(每个游标使用都需要重新创建原始查询上下文,很可能访问再次索引) - 您可以错开此类操作以限制并发操作的数量或使它们完全不重叠。请参阅如何从谷歌数据存储中删除所有条目?有关使用 GAE 延迟任务的这种交错的示例(使用现在可用的更通用的Cloud Tasks也可以使用类似的方法,它支持未来的计划时间)。


推荐阅读