如果处于加载状态,则MongoDB TTL不会删除文档

时间:2019-03-06 14:38:05

标签: mongodb

用例

我正在使用MongoDB保留来自消息队列系统(例如RabbitMQ / Kafka)的消息。每条消息都有一个时间戳,基于该时间戳,我想在1小时后使文档过期。因此,我有一个deleteAt字段,该字段已被索引并设置了expireAfterSeconds: 0。一切正常,除非MongoDB负载沉重。

我们正在每秒向单个副本集中插入5-7k条消息。 TTL线程似乎比传入消息的速度慢得多,因此存储量正在迅速增长(我们希望通过TTL避免这种情况。)

为了更准确地描述行为,当我按deleteAt升序对消息进行排序(最早的日期在前)时,我看到它有时几个小时都不会删除任何这些消息。基于这种观察,我相信TTL线程有时会卡住或根本不活动。

我的问题

我该怎么做才能确保TTL线程不会受到传入消息速率的负面影响?根据我们的指标,即使SSD磁盘I / O也很高,我们的唯一瓶颈似乎是CPU。

我是否需要调整某些内容(例如为MongoDB提供更多用于删除文档的线程),以便TTL线程可以跟上写入速率?

3 个答案:

答案 0 :(得分:2)

我相信我正面临MongoDB的Jira仪表板中所述的已知错误:https://jira.mongodb.org/browse/SERVER-19334

答案 1 :(得分:0)

您可以使用“稀疏”创建索引,这应该在后台的单独线程上执行清理。

答案 2 :(得分:0)

来自enter image description here

  

删除过期文档的后台任务每60秒运行一次。结果,在文档到期和运行后台任务之间的一段时间内,文档可能会保留在集合中。

     

由于删除操作的持续时间取决于mongod实例的工作负载,因此过期数据可能会在后台任务两次运行之间的60秒间隔内存在一段时间。

我不知道有什么方法可以调整TTL线程,而且我怀疑您需要运行自己的cron来进行批量删除。

要查看的另一件事可能是占用CPU和IO的东西,看看是否有任何方法可以减少该负载。