处理亿级数据的“定时任务”,如何缩短执行时间?

简介: 一次性集中处理大量数据的定时任务,优化思路是:同一份数据,减少重复计算次数;分摊CPU计算时间,尽量分散处理(甚至可以实时),而不是集中处理;减少单次计算数据量。

image.png

继续答水友提问。

问题抽象(1)用户会员系统;(2)用户会有分数流水,每个月要做一次分数统计,对不同分数等级的会员做不同业务处理; 数据假设
image.png

(1)假设用户100w级别(2)假设用户日均1条流水,也就是说日增流水数据量在100W级别,月新增流水在3kW级别,3个月流水数据量亿级别 常见解决方案用一个定时任务,每个月的第一天计算一次。

//(1)查询出所有用户

uids[] = select uid from t_user;

//(2)遍历每个用户

foreach $uid in uids[]{

         //(3)查询用户3个月内分数流水

         scores[]= select score from t_flow

                   where uid=$uid and time=[3个月内];

         //(4)遍历分数流水

         foreach $score in scores[]{

                   //(5)计算总分数

                   sum+= $score;

         }

         //(6)根据分数做业务处理

         switch(sum)

         升级降级,发优惠券,发奖励;

}

  一个月执行一次的定时任务,会存在什么问题? 计算量很大,处理的数据量很大,耗时很久,按照水友的说法,需要1-2天。 画外音:外层循环100W级别用户;内层循环9kW级别流水;业务处理需要10几次数据库交互。   可不可以多线程并行处理? 可以,每个用户的流水处理不耦合。   改为多线程并行处理,例如按照用户拆分,会存在什么问题? 每个线程都要访问数据库做业务处理,数据库有可能扛不住。   这类问题的优化方向是: (1) 同一份数据,减少重复计算次数 (2) 分摊CPU计算时间,尽量分散处理,而不是集中处理 (3) 减少单次计算数据量   如何减少同一份数据,重复计算次数?
image.png

如上图,假设每一个方格是1个月的分数流水数据(约3kW)。

  3月底计算时,要查询并计算1月,2月,3月三个月的9kW数据; 4月底计算时,要查询并计算2月,3月,4月三个月的9kW数据;   会发现,2月和3月的数据(粉色部分),被重复查询和计算了多次。
画外音:该业务,每个月的数据会被计算3次。   新增 月积分流水汇总表 ,每次只计算当月增量

flow_month_sum(month, uid, flow_sum)

(1)每到月底,只计算当月分数,数据量减少到1/3,耗时也减少到1/3; (2)同时,把前2个月流水加和,就能得到最近3个月总分数(这个动作几乎不花时间); 画外音:该表的数量级和用户表数据量一致,100w级别。   这样一来, 每条分数流水只会被计算一次   如何分摊CPU计算时间,减少单次计算数据量呢? 业务需求是一个月重新计算一次分数,但一个月集中计算,数据量太大,耗时太久, 可以将计算分摊到每天
image.png

如上图,月积分流水汇总表,升级为, 日积分流水汇总表
把每月1次集中计算,分摊为30次分散计算,每次计算数据量减少到1/30,就只需要花几十分钟处理了。 甚至,每一个小时计算一次,每次计算数据量又能减少到1/24,每次就只需要花几分钟处理了。   虽然时间缩短了,但毕竟是定时任务, 能不能实时计算 分数流水呢? 每天只新增100w分数流水,完全 可以 实时累加计算“日积分流水汇总”。
image.png

使用DTS(或者canal)增加一个分数流水表的监听,当用户的分数变化时,实时进行 日分数流水累加 ,将1小时一次的定时任务计算,均匀分摊到“每时每刻”,每天新增100w流水,数据库写压力每秒钟10多次,完全扛得住。 画外音:如果不能使用DTS/canal,可以使用MQ。   总结 ,对于这类一次性集中处理大量数据的定时任务,优化思路是: (1) 同一份数据,减少重复计算次数 (2) 分摊CPU计算时间,尽量分散处理 (甚至可以实时),而不是集中处理; (3) 减少单次计算数据量   希望大家有所启示,思路比结论重要。

本文转自“架构师之路”公众号,58沈剑提供。

目录
相关文章
|
7月前
|
SQL 前端开发 JavaScript
数据库查询 定时
数据库查询 定时
104 1
|
7月前
|
程序员 开发工具 git
批处理--节约你的开发时间
批处理--节约你的开发时间
|
1月前
|
SQL 分布式计算 运维
如何优化超长定时任务:慢节点优化实践
本文介绍了一个复杂的ODPS任务优化过程。通过对任务耗时卡点的分析,发现主要问题是数据倾斜和join任务资源不足。通过提高join任务资源分配、对空值加随机值打散、视图物化落表、节点拆分、前置裁剪和使用Distributed Mapjoin等方法,成功将宽表产出时间从下午一点提前到早上八点半,节省了4小时以上。优化过程中还拆分了宽表节点,降低了回刷成本。文章强调了在设计开发初期应避免代码耦合度过高,以提高代码运行效率和可维护性。
38 0
|
4月前
|
存储 监控 Java
实时计算 Flink版产品使用问题之随着时间增加,作业的CPU繁忙度增加,是什么原因
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
5月前
|
关系型数据库 数据处理 对象存储
实时计算 Flink版产品使用问题之定时器执行存在延迟好几个小时,该如何处理
实时计算Flink版作为一种强大的流处理和批处理统一的计算框架,广泛应用于各种需要实时数据处理和分析的场景。实时计算Flink版通常结合SQL接口、DataStream API、以及与上下游数据源和存储系统的丰富连接器,提供了一套全面的解决方案,以应对各种实时计算需求。其低延迟、高吞吐、容错性强的特点,使其成为众多企业和组织实时数据处理首选的技术平台。以下是实时计算Flink版的一些典型使用合集。
|
前端开发 算法 测试技术
【软考学习5】流水线基本概念、周期执行时间、吞吐率、加速比和效率的计算
【软考学习5】流水线基本概念、周期执行时间、吞吐率、加速比和效率的计算
971 0
|
关系型数据库 MySQL 调度
定时任务优化
简单描述一下定时任务的优化
145 0
|
SQL 关系型数据库 MySQL
mysql查询优化实战:查询用时一分半降到三毫秒
项目中的课程预约记录查询功能,线下门店反馈说进入到页面需要等2分钟
mysql查询优化实战:查询用时一分半降到三毫秒
|
C++ Windows
c++计算代码执行时间的方法,毫秒级
方法一、 #include#includeusing namespace std;class CTimer{public:CTimer(){_start=clock();}~CTimer(){_end=clock();cout
1149 0
|
JavaScript 算法 前端开发
不到一秒才叫优化
之前做完的一个项目,业务逻辑写完之后,首屏渲染能到3~4秒,这对于用户体验是不能接受的,所以忙里偷闲把项目优化完之后http发送到响应时间:705ms,DOM构建完毕:452ms,页面加载完毕:678ms,清爽的感觉很上头~看来优化还是很有必要的!所以本篇记录一下优化过程。
250 0