首页 > 解决方案 > 运行 cron 作业从一个巨大的预定作业记录表中进行轮询是不是很糟糕?

问题描述

我有一个表,cron 作业会每分钟轮询一次,以向其他服务发送消息。表中的记录本质上是计划在特定时间运行的活动。cron 作业只是检查哪些活动已准备好运行,并通过 SQS 向其他服务发送该活动的消息。

当 cron 作业发现某个活动已准备好运行时,该记录将被标记为done在通过 SQS 发送消息之后。有一个 API 允许其他服务检查计划的活动是否已经完成。因此,done需要保留这些记录的历史记录。

然而,我在这里关心的是,从长远来看,这样的设计是否具有可扩展性。每天大约有 20 万个预定活动,有时甚至更多。由于我通过将记录标记为done完成后来保存记录,因此我担心该表最终会变得非常庞大,包含数百万行,并成为 cron 作业频繁运行的问题。

即使有正确索引的表,我的担忧是否有效?否则,如果我必须以某种方式将这些计划的活动持久化为 cron 或进行轮询并检查它们何时准备好运行,我还能设计什么其他替代方案?

我正在使用 Postgres 数据库。

标签: node.jspostgresqldatabase-designarchitecturecron

解决方案


使用正确的索引,cron 作业应该没有严重的问题。你可以有一个部分/过滤的索引,比如

create index on jobs (id) where status <> 'done'.

保持索引的大小很小。查询必须匹配索引 where 子句。

我使用(id)只是因为不允许空列表,所以必须有一些东西。根据您的评论,schedule_dt可能是更好的选择。如果包含您选择的所有列,则可以获得仅索引扫描。但是如果你不这样做,它仍然会使用索引,它只需要访问表来获取那些特定行的列。我怀疑仅索引扫描尝试对您来说不值得,因为您需要的页面可能不会被标记为全部可见,因为就在一分钟前对相邻元组进行了修改。

但是,将作业标记为已完成似乎有点奇怪,因为它只是被安排而不是完成。

有一个 API 允许其他服务检查计划的活动是否已经完成。

一个无限制地增加大小的表可能会出现除 cron 作业之外的管理问题。当然,这些服务不必回顾几个月就可以做到这一点,是吗?几天后你能删除“完成”的工作吗?如果一个服务试图查找一个工作,而不是找到它“完成”,它根本没有找到它怎么办?

我不认为 cron 工作本质上是一个问题,但没有它会更干净。为什么插入作业的人不实时调用 SQS?


推荐阅读