作者:
马尔科(吴浩亮)
小红书交易、基础数仓负责人,有多年数据架构经验,擅长离线、实时数仓、OLAP 技术和数据湖技术在多场景的实践落地
孙武(施裕豪)
小红书数据仓库工程师,现负责交易侧实时数仓,以及近实时数仓的探索实践工作。
黄猿(吴筱琦)
小红书数据仓库工程师,现负责渠道归因和数据任务性能优化
雨时(张克冰)
小红书数据平台开发工程师,现负责BI平台的查询能力建设
📌 导语:
随着移动互联网内容生态爆发,带来小红书日均千亿级的流量日志增长,与此同时,算法实验迭代的时效要求也在持续提高,传统的数据架构难以在低成本和低延迟之间取得很好的平衡。小红书与云器科技合作,基于增量计算与数据湖技术,以通用增量计算方案构建了一套近实时实验数仓体系。实践显示,该方案在满足实时业务需求的同时,带来了更少的资源投入,更准确一致的数据,更简洁的流批一体链路,更好的查询性能等优势,为后续大范围构建全域近实时数仓体系奠定基础。
背景
近年来,移动互联网用户的内容生态呈现出爆发式增长的趋势,一方面,用户规模持续扩张,覆盖人群不断拓宽;另一方面,用户使用频次显著提升,活跃度与日俱增,这种双重驱动效应导致系统日志规模呈指数级增长(日均千亿级日志)。与此同时,基于大数据的用户策略实验迭代的步伐持续加速,传统离线批处理模式已无法满足业务对分钟级甚至秒级时效性的需求。传统数据架构面临架构选择的难题:离线批处理虽成本低,但时效性也低,无法满足近实时看数/用数需求。实时计算延迟低,但需长期占用资源,运维复杂且成本高昂,通常只能小范围应用于关键链路或做数据采样处理。这些问题给增量计算带来了新的历史机遇。增量计算作为一种近实时的计算方式,通过动态处理增量数据,既避免了流计算的持续资源消耗,又将延迟压缩至分钟级,在统一计算模型下很好的平衡了成本与数据时效性。同时,增量计算支持灵活调整执行间隔,通过分散计算负载降低高峰期资源竞争风险,打破了流批界限,为用户提供了一种兼具经济性和时效性的新方案,"增量计算+近实时链路" 成为优化资源效率与数据价值转化的关键技术路径。
小红书作为国内领先的互联网公司,在推荐、搜索、商业化等场景下具备海量的近实时场景。同时,云器科技是国内较早探索增量计算这个领域的平台提供商,在这一领域有亚洲领先的技术和落地经验,本次成立联合项目组进行深度合作,共同探索高流量场景下的全链路增量计算,希望实现国内首个千亿级全链路流量数据场景的端到端增量计算pipeline,本文聚焦小红书算法实时实验指标场景,解密增量计算在小红书近实时场景下如何进行架构探索,并在相关场景完成落地实践。
1.1 业务重述
实时实验指标是算法实验上线过程中必不可少的观测工具,算法工程师在每一个实验开启过程中,都需要基于实时的实验数据,判断新开的算法实验中不同实验组的指标差异和数据准确性。同时,实时实验数据也能够帮助算法实时对参数进行局部调整(通常调参频次在30分钟一次),目的是希望在后续实验过程中能达到更好的业务效果。操作流程上,用户通常会筛选单个实验相关的用户数据和部分实验维度,并进行实时的 OLAP 指标结果分实验组聚合查询,该查询期望能够实时的返回结果。
针对实时实验场景有以下几个特点:1. 实时性要求分钟级延迟:根据算法的调参频次和数据观测要求,实时指标的算法需求为分钟级,期望有方案达到业务新鲜度需求和成本的平衡 2. 查询响应快:由于实时实验指标需要通过全量的用户行为日志进行逻辑计算(目前小红书的日志已经达到数千亿/日),如何能在秒级对千万日志数据进行快速计算是一项巨大的挑战 3. 数据精准度高:由于实验指标对指标的精准性要求很高,所以要求数据不经过采样,也不进行采样类的OLAP计算,同时,要求实时和离线的最终数据指标结果差异小于1%。
1.2 历史架构
小红书当前的实验数据架构,离线指标和实时指标从属于不同的架构方案,离线指标和实时指标的开发、查询完全分开。其中,离线方案通过ODS入湖,并在 Spark 中通过天级调度进行聚合、关联等操作,将生产的DWS层数据写入到ClickHouse 中,用户通过Clickhouse 进行指标数据的查询。
图:离线链路架构
实时链路主要的计算流程都在 Flink 中,ODS 到 Kafka 后,直接在 Flink 中进行 关联等操作,将相关数据的明细 DWD 层写入到 ClickHouse 中,用户通过 ClickHouse 进行指标数据的查询,同时,由于明细数据量大, 数据到 Clickhouse的过程还存在采样等操作。
图:实时链路架构
1.3 问题分析
实时离线指标存在差异
由于原有Lambda架构的问题,实时和离线本身存在差异,同时历史的实时数据存在抽样逻辑,导致实时数据无法和离线保持一致,数据不置信。离线链路基于全量数据聚合,覆盖维度完整,但时效性滞后,多为T+1数据新鲜度。且当Kafka因故障出现数据延迟时,需触发全量重刷,重新计算日数据千亿级历史分区,资源消耗无法承担,基本无法重刷。实时链路虽能实现秒级延迟,但流式处理需长期占用高配资源,存储成本高昂。同时,实时链路裁剪了非核心维度,导致指标丰富性弱于离线。这种时效性、成本与数据完整性的矛盾,使业务侧需维护两套逻辑相近但结果存异的统计体系,数据一致性保障困难。
链路改造复杂
小红书的实时链路实现由日志采集链路与维表更新链路组合而成。日志采集链路通过Flink导入,维表更新链路则由多个Flink任务写入 REDKV,然后在Flink作业中完成关联,最后Append Only写入Clickhouse。由于Flink的流式SQL语义与Spark批处理语义存在差异,且维表的产出逻辑也会存在差异。两条链路需要分别维护,维护成本高。
实时数据无法做大开窗
受限于流式计算的内存占用与状态管理机制,实时链路在处理大开窗时存在限制。实时处理需要将窗口内所有数据长期驻留内存以支持增量计算,若窗口时间跨度过长会导致状态数据急剧膨胀。同时,实时场景需处理乱序数据,过大的窗口会延长数据等待时间,造成计算延迟激增甚至数据丢失。当前小红书的实时链路一般通过缩小时间窗口的方式来保证数据时效性。
数据成本高
由于 Flink 的消耗资源是长驻资源,本身资源是独占的,随着流量日志的数据量持续增大,实时任务中的计算状态消耗也越大,对应投入的实时资源成本也与日俱增,需要考虑如何缩减成本。
1.4 改造目标
由于当前的离线链路和实时链路都存在对应的限制,离线虽然有全量指标但是数据时效性滞后,实时链路虽然能做到实时但是由于资源和开发复杂度的限制只能采用部分核心指标。且离线和实时链路在双重限制下难以取一个折中数据新鲜度。基于这个背景,小红书搭建了一条近实时链路来满足当前的业务需求。针对目前实时实验指标的一些问题,我们将升级目标定为:建设数据更精准,指标更全面、查询更快、链路更简洁、改造更高效的近实时链路, 我们在数据侧和产品侧做了一些升级,形成了一个初版的产品。
近实时技术方案选型
2.1 Paimon+Iceberg方案
目前市面上暂时没有直接的开源产品能够实现端到端的近实时方案。通过结合不同的开源组件,尤其是以下几个新的开源技术,可以构建一个分钟级的近实时数据链路:
-
随着 Paimon 文件格式的持续演进与完善,其动态维表特性和 Partial update 的更新能力能力显著增强,打破数据处理的常规模式。在传统数据处理模式下,针对多源维表的实时更新操作,通常依赖 Flink 流处理框架,结合 Redis 系统执行实时 lookup join 实现;而如今依托 Paimon 在数据湖上的 实时更新、实时关联能力,可高效实现多源维度表的增量更新和多表关联,并且该方案能够与离线 Spark 分钟级调度作业集成,实现分钟级调度的处理架构。
-
StarRocks 引擎作为一个MPP 架构的OLAP 引擎,StarRocks 能够直接消费 生产任务的 Iceberg 表数据,并能有效提升查询性能。同时,其活跃的开源社区持续持续活跃,为 StarRocks 在数据湖场景下的应用与发展提供了技术支撑与生态保障。
这个组合方案通过 Flink + Paimon 解决湖上维度表更新的卡点,将原来 T+1 的离线流程加速到 5Minutes 延迟来实现了数据产出的近实时化,并通过 StarRocks 直读数据湖的方式进一步缩短数据产出和消费之间的延迟。这套方案的一个风险在于组件数量较多,整合性比较差。并且,小红书目前最主要的数据湖技术框架是 Iceberg,Paimon作为一类新的技术框架,本身发布时间不长,在大数据量上的吞吐性能、调度稳定性方面还有很多问题,要做到在千亿级数据体量下端到端稳定运行,需要对各个模块进行针对性调优,且涉及优化和改造的细节较多。
图:Paimon+Iceberg方案架构
2.2 云器通用增量计算方案
商用产品主要通过增量计算能力来提供近实时方案。目前具备增量计算能力的产品有国外的 Snowflake,阿里的 MaxCompute 以及云器的 Lakehouse。其中以云器的 Lakehouse 增量计算开放性最好,通用性最强,具备在小红书内部落地验证的可行性。
通用增量计算(Generic incremental Compute,以下简称GIC),基于动态数据+增量计算原理 设计。是一种同时面向高性能和低延迟优化的新计算模式。当上游数据在不断发生变化的时候,通过只计算数据变化的部分,与之前的查询结果合并,快速的生成对应的最新查询结果。是一种以最小的运算成本,最快的速度计算出最新的查询结果的新技术。
云器科技(yunqi.tech)是国内较早探索通用增量计算技术团队,在2021年成立之初就将增量计算和Kappa架构作为核心目标,团队在2023年发布会首次提出“通用增量计算”(Generic Incremental Compute,简称GIC)概念并发布最初版本。
图:云器Lakehouse增量数据处理流程
简化技术栈
云器 Lakehouse 有着性能卓越的一体化引擎,一方面可以将增量计算的周期提速到分钟级别,另一方面也可以做高效的秒级别的 OLAP 查询。加上引擎内置读取 Kafka 数据的能力,可以使整个近实时链路的技术架构空前简化,能够支持使用一套标准化 SQL 进行实时ETL/离线ETL/在线查询的一体化开发,开发难度大大降低。
图:传统Lambda组合架构
图:云器Lakehouse一体化架构
基于开放格式建模
云器的 Lakehouse 底层存储遵循 Iceberg 标准,可以直接对接小红书的对象存储,可访问性非常好。
这意味着增量计算流程的搭建可以直接照搬离线的 ods/dwd/dws 建模,而且其中每一层的表都可查询,可以像离线开发一样基于现有流程构建新的分支,灵活性非常好。同时,云器的增量计算流程同样使用表来作为中间状态的表达方式,可以表达的近乎无限大小的窗口而无需担心成本过高。
另外,云器增量计算所使用的动态表也符合 Iceberg 标准的分区语义,当业务逻辑发生变化,需要对动态表定义进行修改时,可以基于分区很好的控制影响的数据边界。对于已经产出的历史分区,也可以像离线流程一样补数重算、甚至覆写,而不会影响到新数据的产出。
基于标准 SQL 开发
云器的增量计算中,pipe数据管道对标flink流式数据写入场景、dynamic table 动态表实现增量计算同时对标flink流式计算近实时场景及Spark离线计算场景。
核心的业务逻辑通过标准的 SQL 语法表达,通过定时refresh进行调度。可以直接复用离线 ETL 逻辑,也可以复用Hive UDF等自定义函数,显著降低了增量计算流程的改造范围和开发难度。
实时写入场景:
实时计算/离线计算场景:
可灵活调节
云器的增量计算流程可以通过参数或调节调度系统的调度周期,即可在实时性和计算成本之间做灵活调节。云器的增量计算使用标准表进行状态存储,存储和计算成本相比 Flink 应用几乎可以忽略不计,从而能够将数据开发注意力更加集中在业务逻辑上。
例如对于出入数据量相近的高通量流量 kafka 数据处理链路,可以将周期调节到 1 分钟级别,避免数据过度堆积导致短时间的巨大资源需求;对于更新维度表或者计算密集的动态表刷新环节,可以将调度周期放宽到 5 分钟,可以有效减少相同主键无效更新带来的小文件问题,以及最大化发挥向量化引擎的计算效能。这个调度周期即使在开发完成后也可以进行简单快速的调节。
方案选型:
-
性能:云器在离线任务调度的执行性能和在线分析的查询性能表现优于Paimon、Iceberg开源组合方案。云器在复杂数据结构的性能优化程度优于Paimon和社区Iceberg。Paimon目前在大数据量上的吞吐性能、调度稳定性方面还有不足。
-
增量补算:在实时场景下,实时数据晚到是一种很常见的情况,Spark无法自动识别晚到数据,同时针对晚到的数据进行按分区重刷,云器拥有完整的增量补算的能力,可以支持增量更新历史分区。
-
底层存储:小红书本身内部使用的数据湖框架是Iceberg,云器Lakehouse基于Iceberg开发,很好的兼容了小红书本身的数据湖框架,而Paimon 作为新发布的技术,会引入额外的存储格式,且在大数据量上的吞吐性能、调度稳定性还有很多问题。
最终,我们选择云器作为我们的近实时增量技术方案。
数据模型设计
3.1 业务场景
小红书的业务场景中,日均产生的日志量高达数千亿条。若采用传统方案,直接基于明细层数据,再聚合生成指标结果,同时完成处理筛选实验、关联用户维度等操作,并且性能要达到秒级响应,实际场景下将面临资源消耗剧增的挑战。这种方式不仅会造成资源的过度占用,还会大幅推高计算成本,难以获得理想的投入产出效益。因此,我们在近实时链路的数据模型中做了以下几点优化,在节省资源的同时,也达到了预期的查询性能。
3.2 模型设计方案
图:模型设计方案架构
分钟级聚合DWS层
对于小红书日均产生的数千亿条日志,直接查询性能要求很高。由于日常查询指标所筛选的都是用户的实验信息和用户维度信息,同时,查询的实时指标时间维度,通常是 5 分钟/10 分钟/半小时。因此,我们在模型设计层面,设计了<分钟,user_id> 粒度的数据,将用户和时间维度固化,其他则作为基础聚合指标的形式,通过5分钟的调度任务,把明细日志转化成了 5分钟+用户粒度的DWS层数据,同时在分钟级调度任务中关联用户维表,将相关维度信息以及用户对应的实验信息放到 DWS聚合层中,整体数据量从数千亿缩减到数亿,由于一个用户可能从属于多个实验,我们把实验字段存成数组的形式,在查询时加以筛选,最终查询P90优化到小于10S。
实时用户维表DIM 层
实时用户维表分为实时维度和离线维度,通过 Partial update 的方式,针对需要实时更新的维度,我们通过读取用户实时数据 的Kafka数据,对用户维表的数据进行 1分钟级调度更新,从而达到实时更新的效果。针对天级更新的维度,我们通过离线调度写入的方式,通过判断表中的时间戳,识别哪些记录应该被更新,从而实现按需更新。
实验数组查询优化
对于实验平台的算法来说,指标数量众多(可达上千个),且随时间会逐渐发生变化。使用传统的建模方式,需要将所有指标单独成列,构造上千列的大宽表,且每当有指标增减,就会涉及这个宽表的 schema evolution,进而使 ETL 链路的上下游都需要进行表结构订正和配套的作业更新,是个很繁重的工作。
因此,我们利用云器科技引擎所支持的 JSON 类型,将易变动的算法指标表达成 JSON 列,利用其半结构化表达能力以及丰富的内置 JSON 函数,让算法用户在 JSON 列中自助增减指标,显著提升了平台效率。
云器科技 Lakehouse 引擎支持文件级自动化类型推断技术,使 JSON 中的半结构化数据以多列的形式存储于 Parquet 文件当中,使得使用 JSON 列的半结构化表和传统的大宽表相比,只需要在落表时多消耗一些 CPU 进行类型推断,落表后的存储空间占用和后续的查询性能几乎没有区别。
用户实验维表设计
实验平台上每天都活跃着上千个实验,离线侧在计算用户所属实验的时候会设计一张用户id和实验分组id的映射表,但是这张表每天有上千亿条数据。在实时或者近实时场景下我们必然无法在短时间内生成如此庞大的映射关系。小红书之前的实时实验场景,是先通过白名单的形式限制了实验范围,并且只过滤了近一天有修改的实验,以此来减少用户实验的映射关系,然后使用用户行为日志去从实验平台的服务获取对应实验,记录到KV存储中,实时作业从KV中获取用户的实验分组id。这样的方式虽然解决了基本的实时实验看数需求,但是很多实验光靠一天的实验指标无法判断效果。
近实时链路中我们希望可以支持近7天的实验,并且执行时间尽可能在5分钟内。如果我们沿用离线思路,任何引擎在处理如此庞大数据量的时候都无法避免执行时间过长。而如果采用实时链路的思想,那么KV存储压力和读写压力会很大,很容易成为瓶颈。在深入了解实验分组过程之后,可以发现一个实验设定好之后,实验平台会将用户id和这个实验的配置信息放到一起去计算,最终会得出这个用户属于这个实验的哪一个分组(或者不在实验中),最终我们决定用实时计算的方式去将实验分组id计算出来。
计算一个用户的实验分组只需要两个信息,用户id和实验配置信息,其中只有实验配置信息会实时变化。因此我们将计算实验id的过程封装在了UDF中,使用心跳日志就可以计算出用户当前的实验分组id。计算出来的实验分组信息会存储在云器的用户实验维表中,这样就可以供各种近实时业务使用,而不用重复计算。
用户实验维表的格式为<user_id,exp_ids>,其中exp_ids我们选用了array<bigint>的数据结构,传统的查询方式必然是每条数据进行遍历。由于一个用户的实验分组id较多,可以达到数百个,所以这样的查询方式效率极低。云器可以对exp_ids建立倒排索引,新增倒排索引之后的用户实验维表,查询性能相对于原始查询方式提升了近20倍。
图:用户实验维表维度链路
优化效果
4.1 新实时实验数据链路方案对比
主要对比离线链路、近实时链路和实时链路的时效性和可观测实验等情况,以下为对比结论:
-
当前业务场景构造5分钟左右的近实时方案完全可以满足实验观测效果。相比于离线的天级数据,近实时数据能够很好的支持算法进行实时调参,又避免了实时数据开发复杂,资源损耗多的问题。同时,近实时方案可以灵活的根据业务需求变化调整数据延迟(数据新鲜度),根据需要调整数据的更新频率,以达到业务需求和成本的平衡。
-
在可观测的实验数方面,近实时方案可观测的实验也在离线方案和实时方案之间取得了很好的平衡。在实际生产中,用户更加关注实验刚上线或者放量后的几天内的数据情况,以便及时作出策略调整,近实时方案在也可以很好满足这类诉求。
因此从三个方案对比来看,近实时方案在满足业务对时效性要求、观察实验要求和指标开发难度等维度下,对比于实时方案和离线方案,是一个更好的选项。
4.2 业务价值提升
小红书基于云器增量计算的能力和Iceberg数据湖的开放存储,建设完成了新实验指标算法链路,同步完成和RedBI新平台的对接,并通过RedBI 提供完全兼容历史产品的查询能力,并且性能对比原始链路有了极大的优化。
图中主要对比了近实时链路和实时链路的资源消耗和准确性、延迟等情况,以下为对比结论:
相比于历史的实时方案,新方案在资源方面的投入消耗仅为原来的 36%,并且数据差异也比原来更小(1% with 5%),同时相对于实时数据链路,增量方案的指标由于其增量更新能力,指标拓展性更强,数据可以给离线复用。
另外传统的实时数据场景下,新加一个字段需要修改原有的表结构,通过修改 DDL,重启提交任务上线,二次开发来新增写入字段,整体流程和耗时都非常长,开发迭代也比较复杂。目前基于云器的json类型高度支持及json的高效查询性能 ,小红书将埋点feature 相关的字段 全量dump成 json,使得BI用户需要新增埋点字段,可以直接在数据集自助配置字段,不需要提加字段的需求。通过自助的更新埋点字段,可以快速、多样化的满足算法debug 和调参需求。
基于增量计算引擎 ,云器Lakehouse相比于原始的实时链路提供了更多的实验维度扩展数据,且达到了比原始的离线链路更优的性能效果。云器通过近实时的维度扩展实现,使BI用户可以进行更多维度指标的行为分析,因此近实时方案在当前场景优于实时方案。
展望
小红书基于云器技术开发的准实时链路,完全建立在开放数据湖格式(Iceberg)上。有了分钟级新鲜度的主日志数据,可以将更多离线 ETL低成本迁移成近实时链路。
近实时数据是流处理和批处理之间的一道桥梁,在保证实时和离线数据的一致性方面有得天独厚的优势。未来我们会着力将核心观测指标通过近实时链路进行部署,打造近实时核心业务指标体系。完成数仓从日志ODS,到业务DWD层,再到DWS层的近实时化。在此过程中我们会逐步建立起近实时数仓的核心表,这些核心表可以同时服务于实时、离线、近实时处理。
可以预见未来越来越多的业务将会认识到近实时数据的价值,越来越多的数据场景会在小红书的近实时链路生根发芽。
🎁 限时体验福利
✅ 新用户赠200元体验代金券
✅ 免费领取《云器Lakehouse技术白皮书》
➤ 即刻通过下方网址体验: