共计 1609 个字符,预计需要花费 5 分钟才能阅读完成。
1. 背景
在大数据生产环境下,往往需要是越快越好,对于实时零碎开发,需要往往是一个状态值,比方多少次,多少个,而对于离线数据开发,因为不是实时,所以能够开发各种简单需要,另外一种基于 Lambda 架构或者 Kappa 架构的,往往场合时实时统计零碎,实时统计零碎在后面 Lambda 架构的设计中曾经谈过,本文时另外一种更简单的利用场景,对于 Lambda 架构中产生的流水,要尽可能快地满足范畴查问,什么意思呢,Lambda 架构中,虽说能够查问一个范畴统计的流水,然而为了尽可能地快,将离线计算结果是 count,count(distinct) 这两种能够更细地划分,做初步的聚合,比方生成一个 Set 的汇合,这样能够满足在查问层更快地合并数据,然而同时也减少了架构的复杂性和非通用性,同理本文的实时范畴查问,是基于需要的一种简单设计,解决的是这样的一个问题,我想求一段范畴的 count,怎么保障最快地计算结果。
## 原始数据表 t1 流水如下
transactionId,id1,id2,money,create_time
## 目标
## 输出 id1, 一段范畴 create_time, 失去 count(money)
2. 设计
后面背景中次要抛出一个问题,如何设计这样的零碎,满足疾速求工夫范畴的 count, 须要达到生产级别的实时查问零碎。
(1)为了疾速 count,必然不能只有流水,只有流水的 count,遇到数据量大的范畴 count,很耗时,所以设计预计算 count,即截至到 xx,某个 id 的所有 count(money)
(2) 在查问时候只须要查到开始工夫的最左工夫流水,和完结工夫的右迫近流水,相减即可
(3)为了疾速查问工夫和 id,必然须要这两个加索引
(4)如果需要是最近三个月的查问,那么回溯时候,能够认为设计开始工夫节点,从那里开始时 0,而后开始一直累加
留神:(4)看利用需要,能够将最原始节点卡在三个月前,令那个工夫点的截至数据 count 就是 0
示意图如下:
3. 实现计划
假如是(3)计划,更通用的计划,就是数据会存的更多一点
假如原始全量数据存在于 mysql 表中,那么须要新建设一张 t2 表,字段如下:
id1,create_time, money_sum
(1)首次计算如下
SELECT id1,
create_time,
sum() over(PARTITION BY money_sum
ORDER BY create_time) AS money_sum
WHERE create_time > NOW
(2) 增量计算
## 查问 t1 一条增量记录
select id1,create_time,money from t1
## 查问 t2 这个 id1 的最近一条记录
SELECT id1,
create_time,
monye_sum + MONEY AS money_sum
FROM
(SELECT id1,
create_time,
money_sum,
row_number() over(PARTITION BY id1
ORDER BY create_time DESC) r
FROM t2
WHERE id1 = xx )
WHERE r=1
## 将这条记录 insert 到 t2 即可
4. 总结 && 探讨
如果数据有同一时间的多条记录怎么办,如果重复记录有提早怎么办
针对第一个问题,如果有多条重复记录,就要看业务需要了,业务需要如果肯定要精准实时的,那么必须要等下个工夫的数据过去或者确定统计完结,能力将 money 加上,就是 3.(2) 中的 select xx from t1 可能有多条数据的状况,肯定要确保这个 id 不会有同一反复的记录才行,这时候就有两种解决形式,一种是默认等 1s,如果没有新数据就完结,另外一种是等新工夫点数据,如果来了就算完结,如果业务需要能够承受提早,那么同样的数据,不同的查问工夫点可能就会有不同的后果。
所以真的要看业务需要来看设计形式,比拟常见的形式是提早期待,没有新工夫就计算。
吴邪,小三爷,混迹于后盾,大数据,人工智能畛域的小菜鸟。
更多请关注