精准水位在流批一体数据仓库的探索和实践
2024-10-05 来自: 三菱 浏览次数: 1
产品介绍
随着实时计算技术在大数据中的广泛应用,数据的时效性得到大幅度,但是实际应用场景中,除了时效性,还面临着更高的技术要求。
本文结合实时计算的水位技术在流批一体数据仓库中的探索和实践,重点阐述了水位技术的概念和相关理论实践,尤其就水位在实时计算系统中的特性、边界定义和应用,最后重点描述了一种改进的精准水位的设计和实现。该技术架构目前在百度实际业务场景下表现成熟和稳定,借此分享给大家,希望对大家有参考价值。
为了提升产品研制、策略迭代、数据分析以及运营决策的效率,业务对数据的时效性要求越来越高。
虽然我们很早就基于实时计算实现了实时数据仓库的建设,但是还是没有任何办法取代离线数据仓库,实时和离线数据仓库各自一套开发和维护的成本高,最重要的是业务的口径还不能100%对齐。所以我们从始至终在致力于建设一套流批一体数据仓库,在实现整体数据加工效率提速的同时,还能保证数据如离线%业务场景,以此来实现整体降本提效。
要想端到端实现流批一体数据仓库,作为底层技术架构的实时计算系统,面临着很多技术难点和挑战:
以上2和3点,都需要高可靠的水位机制来确保实时数据的进度感知和精准切分。
于是本篇文章就精准水位在流批一体数据仓库中的探索和实践的经验,分享给大家。
在实际实时数据处理过程中,数据是无边界的(Unbounded), 那么基于Window这种窗口计算或其他类似场景就面临一个实际的问题:
大多数情况下,个人会使用Event Time来触发窗口计算(或者数据分区切分,对标离线)。然而实际的情况是实时日志总有不同程度的延迟(在日志采集、日志传输和日志处理等阶段),即如下图所示,实际上会发生水印的倾斜(即数据会出现乱序)。在这种情况下 , Watermark机制就很有必要存在,来确保数据的完整性。
水位(watermark)的定义目前业界没有统一的说法,结合Streaming Systems一书(作者是Google Dataflow 研发团队)中定义,个人以为比较确切:
然而在实际生产系统中,水位如何去计算,以及实际的效果是啥样子?结合目前业界不同的实时计算系统,对于水位的支持还是不一样的。
但是以上水位的实现机制和效果,在日志源端出现大面积日志延迟传输的情况下,水位还依旧会更新(新旧数据乱序传输)推进,会导致对应的窗口数据不完整,窗口计算不准确。因此,在百度内部,我们基于日志采集和传输系统、实时计算系统探索了一种改进的、相对精准的水位机制,以确保实时数据在窗口计算、数据落地(sink 到AFS/Hive)等应用场景下,窗口数据的完整性问题,以满足实现流批一体数据仓库的要求。
为了使得水位在实时计算中更精准,我们设计出一种中心化的水位管理思路,即实时计算的各个节点,包含source、operator、sinker等都会把自己计算的水位信息,统一上报给全局的Watermark Server,由Watermark Server 来进行水位信息的统一管理。
但是在实际系统模块设计中,low watermark又可根据算子处理的边界区分如下:
输入最低水位,能够理解为将要输入当前算子,即上游算子处理过的数据的watermark。
输出最低水位,能够理解为当前算子未处理过数据的最早的(oldest)水位,即处理过数据的水位。
目前实时计算系统在实时数据仓库的应用场景,我们都是使用low watermak来触发窗口计算(因为这样更可靠),从3.1中low watermark的定义我们可知:low watermark是层级迭代计算的,水位是否精准,取决于最上游(即source)水位的精准度。于是为提升源头水位计算的精准度,我们应该前提条件:
首先作为独立的线程(thread)启动。根据配置的日志传输任务的BNS(Baidu Naming Service,百度名字服务,提供服务名称到服务端所有运行实例的映射)来解析日志源的服务器列表(hostname list);根据配置的APP拓扑关系,初始化watermark信息表,并持久化写入Table(百度分布式kv存储引擎)。
接收到Client到水位信息并更新对应粒度(Processor粒度或者keygroup粒度)的水位,对局部水位进行更新。
现实中,如果要求源端的日志100%都精确的到达,会造成频繁的延迟或者延迟太久(如果下发采用全局Low watermark逻辑)。原因是:在日志端服务器实例太多的情况下(比如实际上我们有的日志有实例6000 - 10000个),总有线上服务的实例会出现日志实时上传的延迟的情况,那么这就需要在数据的完整性和时效性之间做一个折中,比如以百分比的形式来精准控制允许延迟的实例个数(比如配置99.9% 或者99.99%来设置允许源端日志出现延迟的比例),来精准控制最源端水位的精确度。
精准水位需要特殊配置,根据Source端实时上报的服务器和日志进度的映射关系,以及配置的允许延迟实例的比例,来计算Source端的output low watermark。
额外需要请求一个全局的Low Watermark 来决定数据的输出窗口是否关闭。
很多时候,实时系统并不是孤立的,多个实时计算系统之间有着数据的交互,最常见的方式是两个实时数据处理系统是上下游的关系。
具体表现为:两个实时数据处理系统之间通过消息队列(比如社区的Apache Kafka)来实现数据的传递,那么在这样的一种情况下,怎么来实现精准水位的传递呢?
上游实时计算系统的日志源,保证日志是点对点发布的,这样做才能够保证全局水位的精准度(具体比例是可调的);
在上游实时计算系统的输出端(sinker/exporter 到消息队列端),需要保证使用全局low watermark的下发,目前我们采用把全局水位信息打印到每条日志上面来实现传递;
在下游实时数据计算系统的Source端,需要解析日志携带的水位信息字段(来自上游实时计算系统),并开始作为水位的输入(Input Low Watermark),开启层层水位的迭代计算和全局水位的计算;
在下游实时数据计算系统的Operator/Sinker端,可仍旧可以用日志的Event Time来实现具体数据切分,来作为窗口计算的输入,但是触发窗口计算的机制,仍旧以Watermark Server 返回的全局Low Watermark为准,以保证数据数据的完整性。
实际线上测试,采用精准水位(配置水位精度99.9%,即只允许千分之一的源端实例延迟),在日志没有延迟的情况下,实时落地的数据和离线数据,在同一个时间窗口(Event Time)下效果对比如下(基本都是十万分以下):
在源端日志出现延迟的情况下(=0.1%源端日志实例延迟的情况下,水位还会持续更新),数据diff效果整体基本在千分之1 左右(受到日志源端点对点日志本身有几率存在数据不均情况的影响):
在源端日志出现大面积延迟的情况下(0.1%源端日志实例延迟的情况下),由于使用了精准的水位机制(水位精度99.9%),全局水位不会更新,实时数据写AFS的窗口不会关闭,一直等待延迟数据的到来和全局水位得更新才会关闭窗口,以保证数据的完整性,实测结果如下(在千分之1.1-千分之1.2之间,受到日志源端实例本身存在不均情况的影响):
经过实际精准水位的研究和实际线上的应用,基于精准水位的实时数据仓库,在具备时效性提升的同时,具备了更高、灵活数据的精度机制,在稳定性优化后,实际上完全已经替代之前的离线和实时两套数据仓库系统,实现了真正意义上的流批一体数据仓库。
同时基于中心化的水位机制,也后续面临着性能优化、高可用(故障恢复机制的完善)和更精细粒度精准水位的挑战(在窗口计算触发机制下)。
随着AI、云计算等新兴技术应用场景继续扩展,IT生态受到全方位重塑。技术路线的变化推动工作方式的转变,传统的IT架构、数据库管理与开发运维交互模式正面临前所未有的挑战与机遇。为此,dbaplus社群携手货拉拉三位技术专家,围绕“货拉拉微服务架构演进与数据库中间件、DevOps建设之路”这一主题开展线上直播分享,和大家一起深度探讨服务治理、中间件、DataMesh、DevOps等议题。