腾讯内容千亿级实时计算和规则引擎实践优化之路( 四 )


腾讯内容千亿级实时计算和规则引擎实践优化之路
文章图片
图3-8延迟流数据滚动大窗口计算
我们窗口计算转换为Key的分类聚合问题 , 通过对要参与聚合计算的Key进行巧妙设计 , 进而实现聚合统计 。
步骤1:计算数据所属的窗口起始值 , 窗口起始时间值=事件时间/窗口大小*窗口大小 , 窗口大小是根据业务需求来指定的 。 对于超自然数据 , 需要基于业务场景进行时间矫正 。
步骤2:根据窗口的起始值对数据进行分配 , 正常数据直接放入正确的窗口中 , 延迟数据由于只是晚到 , 但是数据的生成时间是正确的 , 所以可以根据窗口标记找到对应的窗口 , 放入对应的窗口中 。
步骤3:对窗口中的数据生成独有的聚合Key , 聚合Key=计算Key+日期+窗口起始时间值 。
步骤4:按照聚合Key的值进行Shuffle分组 , 聚合Key相同的数据会被发送到同一个计算任务 , 进行聚合或者更加复杂的计算 , 并且清理内存中过期的聚合Key , 避免程序随着时间推移出现性能下降问题 。
3.2.3TB级实时流数据拼接
Flink原生实现进行TB级数据拼接时 , 计算较慢 , 且状态备份时可能异常导致难以升级APP 。
因此 , 我们构建了可以解决大状态下多流拼接的时效性和稳定性问题的技术方案 , 并保证最终一致性 。
腾讯内容千亿级实时计算和规则引擎实践优化之路
文章图片
图3-9基于HBase实现TB级实时多流拼接
主要思路如上图所示 , 我们借助第三方HBase存储完成多流关联 。 阶段1:特征拼接 , 每个源单独加工 , 抽取自身特征后 , 进行如下过程:步骤1:将自身特征同步到HBase中 , 每个源只更新自身属性对应的列 。 HBase中会包含每个内容最新最全的属性 。 步骤2:将有变更的内容推送到消息队列中 。 当前实现是将所有有变更的内容实时推送下游 , 可改造该过程 , 多流水位对齐后再推送 , 以支持多流拼接的多种语义 。
在本阶段的存储设计中 , HBase的Rowkey为待关联的Key , 列分别为属性Key和属性值 。 同时 , 我们进行了大量优化设计:批量访问:每50个Key合并访问 , 减少IO 。 随机主键:将Key进行md5哈希 , 让数据均匀分布在HBase中 , 防止热点 , 提高随机访问性能 。 存储压缩:部分属性值较大 , 将其序列化后 , 使用GZIP压缩 , 减少存储 。 过期机制:按需设置TTL , 防止数据无限膨胀 。 阶段2:特征输出 , 通过一个程序统一加工处理 , 可将每个内容的全量特征输出到目标业务系统中 。 步骤3:实时感知特征有变更的内容 。 步骤4:批量拉取内容的全量特征 , HBase中每一列对应一个特征 , 某个内容的全部列即为其全部特征 。 步骤5:入库 , 将从HBase中获取的全量特征 , 转换成目标存储格式 , 输出到目标系统 。
3.2.4融合批数据重建流状态
在内容生态的实时计算场景中 , 我们经常会遇到累计指标的统计 , 比如某一条内容的实时总点击数、展现数等 。 传统的方式主要是用Lambda架构进行加工 , 面对口径发生变化等情形时 , 会有如下问题:批处理计算和实时流计算两份代码可能由多人维护开发 , 因此容易造成计算结果不一致 。 批处理计算和实时流计算切换的时候出现数据抖动 , 影响用户体验 。
因此 , 我们设计了批流状态融合架构 , 主要优点如下:只需要维护一份实时流计算代码 , 通用性较好 , 适合所有实时流需要计算业务历史数据的场景 。 解决了实时流计算批量回溯历史数据时的算力问题 , 利用存量批处理计算资源回溯历史全量数据 , 同时 , 结合仅需从T日零点零分零秒开始的实时流数据 , 得到口径变化后的完整指标数据 。 规避了数据的抖动 , 提供好了良好的用户体验 。