知识卡片
原子加API:让延迟到达的数据能正确叠加,而不是被迫扩大时间窗口消耗内存
内容
业务实时监控系统把OpenTSDB和实时计算系统(Storm)结合使用,用于聚合并存储实时metric数据——常规做法是在实时计算这一侧设置一个时间窗口,用于聚合落在这个窗口内的数据,再把聚合结果一次性写入时间序列数据库(TSDB)。但真实环境里,数据在采集、上报阶段经常会存在不可避免的延时,这意味着某些数据可能在它本该被计算进去的那个时间窗口已经结束之后才姗姗来迟,如果没有额外处理,这类延迟数据要么被直接丢弃(导致统计结果不准确),要么就得把时间窗口设置得足够大以尽量把这些延迟数据也兜进来(但窗口越大,需要在实时计算端持续保留和聚合的数据量就越大,内存消耗也随之上升,而且实时性也会因为要等待更长的窗口关闭才能出结果而打折扣)。某音乐公司给出的解法是在原有TSDB写入API的基础上,增加一个”原子加”(atomic add)的API:延迟到来的数据不再需要被塞进已经关闭的旧窗口重新计算,而是可以直接被原子性地叠加到之前已经写入TSDB的对应数据上——这样即使数据的采集和上报阶段不可避免地存在延迟,最终写入TSDB的统计结果依然能够保持准确;更重要的是,因为不再需要为了兜住延迟数据而把实时计算端的时间窗口设置得很大,这个改进同时节省了内存消耗、也提升了整体的实时性。这个案例给出了一条应对”数据延迟到达”这类问题的巧妙思路:面对”部分数据会不可避免地迟到”这个现实约束,与其试图靠扩大等待窗口去被动兜住所有可能迟到的数据(这个思路的代价会随着容忍的延迟程度增加而持续上升),不如反过来设计一种机制,让迟到的数据在到达之后依然能够被正确、安全地补算进最终结果里——把”如何应对延迟”这个问题,从”接收端要不要等得更久”转移到”迟到数据能不能被事后正确合并”,往往能同时兼顾准确性、内存效率和实时性。