定时任务优化总结(从半个小时优化到秒级)

💡 原文中文,约11000字,阅读约需27分钟。
📝

内容提要

本文介绍了一个站外广告投放平台在优化定时任务过程中遇到的问题和解决方案,包括按需查询、分批次游标查询、按数据库分片分组更新、精准定位数据等。通过引入定时任务和优化查询方式,减少了数据库交互次数和任务执行时间。同时,通过冗余数据和按时间戳查询的方式,减少了无效数据查询和计算。最后,通过分发任务到不同机器上执行,消除了单台机器CPU不稳定的问题。优化后,CPU利用率和查询次数都有明显改善。

🔎

延伸解读

游标查询的适用条件与优势

文章通过手写游标查询,将数据库交互从200万qpm降至2万,任务时间从5分钟缩至30秒。游标查询有效需满足两个条件:表有唯一键且基于唯一键升序排序;查询条件在区间内越稀疏越有效。这避免了深度分页的慢SQL问题,因为通过id > maxId直接过滤,无需扫描大量记录。

冗余next_time字段的优化与一致性保障

为减少无效查询,文章在dsp_show_status表冗余next_time字段,存储物料下次状态变更时间戳。查询时增加时间范围条件,使每次查询记录从130万降至1万,查询次数从1万次降至200次。但需注意异构数据一致性:若定时任务失败,next_time与投放时间段可能不一致,此时需关闭基于next_time的优化,回退到全量游标更新。

按分片分组更新避免长事务

批量更新时未带分片键导致JED网关报长事务错误,SQL被kill。解决方案是按数据库分片对单元ID分组,确保每组落到同一分片,并加上userId集合。这要求JED网关支持多分片键路由,经验证可行。此方法避免了跨分片更新,减少了事务超时风险。

负载均衡与资源消耗的极致追求

即使CPU仅增加28%,作者仍通过可重试总线将任务分发到多台机器,消除单机CPU不稳定。可重试总线支持自定义重试频率,避免MQ不可控的重试延迟。最终优化后,CPU增加仅1%,任务30秒内完成,查询数据库200次。文章强调程序员应时刻考虑资源消耗,避免无效日志和临时对象。

❓

Q&A

定时任务优化的主要目标是什么?

主要目标是减少数据库交互次数和任务执行时间,从而提高CPU利用率和查询效率。

优化过程中使用了哪些查询方式?

使用了按需查询、分批次游标查询和按时间戳查询等方式。

优化后任务执行时间和CPU利用率的变化如何?

任务执行时间从五分钟降至30秒,CPU利用率降至60%。

如何通过冗余数据来优化查询效率?

通过增加next_time字段来存储下次状态变更的时间戳,减少无效数据查询。

分发任务到不同机器上执行的好处是什么?

可以消除单台机器CPU不稳定的问题,提高任务执行效率。

在优化过程中遇到了哪些主要问题?

主要问题包括数据库交互次数过高和任务执行时间过长。

🏷️

标签

➡️

继续阅读