京东零售数据湖应用与实践

作者:陈洪健:京东零售大数据架构师,深耕大数据 10 年,2019 年加入京东,主要负责 OLAP 优化、大数据传输工具生态、流批一体、SRE 建设。

当前企业数据处理广泛采用 Lambda 架构。Lambda 架构的优点是保证了数据的完整性,但缺点是系统的复杂性较高,需要维护两套系统,并且服务层的复杂合并逻辑可能会导致延迟。为了解决数据的完整性和实时性之间的矛盾,京东零售在数据架构上做出了一系列的革新。

本文将从以下四个方面展开介绍:

1. 背景和痛点

2. 迭代和优化

3. 效果和收益

4. 未来展望和规划

01 背景和痛点 

1. 数据实时性和完整性的矛盾

Lambda 架构设计的初衷是同时提供即时的实时数据处理和高度精确的批量数据处理,但是这种架构也带来了数据实时性和完整性的矛盾。

在线分析和在线训练场景需要数据具备实时性(T+0)和一定的历史数据。但当前实时数据和历史数据分别存储在不同介质中,使得在需要同时具备实时性和完整性的数据应用场景下,用户需要分别对接不同的系统,使用不同的 API 实现需求,并且需要接受口径差异问题,这样的设计低效且不友好。

2. 架构维护成本高

当前京东的数据处理架构分为离线处理和实时处理两条链路,离线处理的流程分为业务接入、采集服务、埋点数据存储、数据入仓、数仓 BDM 层、数仓 FDM 层、数仓 GDM 层等。实时处理的流程分为业务接入、采集服务、Kafka 缓存/Topic 划分、Flink 处理、Kafka 缓存/Topic 划分等。这样的架构存在着以下问题:

  • 离线批处理的 ETL 任务繁重,当前的埋点日志入仓采用自运维的 Plumber 任务,对物理机资源有强依赖,日常需求达到百台,大促期间更需大量扩容。但整个互联网的趋势是降本增效,如何在减少物理机使用的情况下满足业务需求成为我们需要解决的问题。

  • 实时数据为达到秒级处理,通常采用 Kafka+Flink 的架构实现,整体计算和存储资源消耗较高。实际业务中存在着低优先级或者实时性要求不高的场景,在目前的架构下无法灵活实现,存在资源浪费的情况。

  • 离线处理的链路冗长,不含中间表的情况下,也需要至少四层的计算。另外,T+1 批处理的时间集中,如果遇到数据量级波动,网络堵塞,或者机器故障等情况,都会严重影响任务产出。比如波动时 GDM 资产完成时间可能超过 4:00,任务爆发雪崩并开始集中抢占资源,导致大量任务延迟。

3. 状态数据的更新和存储问题

在当前的数据仓库架构中,数据状态的更新是一种重量级操作,它的操作方式是将分区内全部数据重写,即使其中的大部分数据没有发生变化。这不仅浪费了大量的计算资源,也降低了系统的效率。另外,为了能快速查询到历史时刻的数据快照,我们每天或每小时都要存储全量数据,这同样消耗了大量的存储资源。

举个例子,对于流量数据,我们通常关注 PV 和 UV,也就是累加的数量和去重的数量,那么按天增量存储就很容易计算出相应的指标,计算最近三十天的访问量只需要累加最近三十天每天的数量即可;但是对于存在 Update 场景的数据,比如每天商品都会发生增加,删除和修改,那么我们计算 SKU 和 SPU 等指标,主流解决方案就是每天加工一份商品全量表,更进一步考虑如果每天商品的变化数量只在 10%,却要按天产出全量数据,那么数据的重复存储,以及数仓中每一层的大量计算,都使得数据产出的性价比较低。

02 迭代和优化 

针对上述架构、更新和存储中存在的问题,我们进行了一系列的改造。

1. 架构变更

  • 流量涉及的生产库写实时 Topic:原先埋点数据采集过后写入 CFS,HDFS 接入 CFS 数据开始入仓,改造后 CFS 上的数据成为实质上的 Topic。

  • 将处理的离线 MR 作业改为流处理的 Flink 作业:使用 Flink 任务采集 CFS 的 Topic 数据,来代替数仓中使用 MR 做引擎的 ETL 任务,提升数据时效。

  • 将数据通过 Flink 作业写入 Hudi 表:Hudi 旨在将流处理和批处理的优势结合起来,允许处理增量数据,这意味着可以仅处理自上次查询以来发生变化的数据,而不是每次都加载整个数据集;同时提供了索引和事务的支持,如 Bloom Filter 索引和列值索引有助于查询加速,对事务的支持可以保证多并发写入下的数据一致性。

  • 对数据进行逻辑加工和不同表的 JOIN,生成 GDM/RDDM 对外开放模型表。

2. 多流合并

如下图所示,商品后台包括自营、pop、book 和其它一些业态,从生产库实时抽取 binlog 日志,生成对应的流。在 BDM 层,直接通过 Flink 任务将对应的 binlog 日志,变成 Hudi 的 BDM 表。在 BDM 到 FDM 层,做了一些简单的加工。再往后是全量商品表和不同维度表的更新。在这一流程中,具体的改进点如下:

(1)存储模型变为分区表+MOR+Bucket 的组合来提升性能

  • 降低list 操作频次、计算离线往期分区大小,Bucket 不超过 2GB

  • 为了减少小文件,将非分区表改为了分区表

  • 限定保留版本数 288/分钟、25/小时(版本数*平均提交周期),定时 clean、Archive

  • Flink fdm 层'compaction.async.enabled' = 'false',spark 层创建合并任务进行异步 Compaction 操作

  • Flink 切换到 Spark 引擎 eventtime.field=ts 保持数据更新规则一致

(2)降低成本

  • 多表资源复用,把原本分散在各个业务形态中的数据进行了合并处理,从而降低资源成本

  • 建设 DMS 系统自动建表,表增删改统一管控收口,创建相关任务,并实现了对任务状态和异常的可视化,使异常定位和处理变得非常便捷,从而降低了人力成本

(3)数据一致性

  • 数据保序:表主键 Hash 分组传输

  • 数据完整性:根据 Hudi 的心跳机制和业务的时间窗去判断数据的完整性, Precombine=业务时间,多个时间编写多时间 payload 函数进行更新

(4)可持续性

  • 健壮性,对数据积压、任务异常、数据时延等创建监控策略进行监控

  • 元数据更新,业务变更带来的分析库结构变更

  • 稳定性,实现了资源隔离,保证上游集中刷数、定时跑批时的稳定性

3. 外键关联

Hudi 在大表的外键关联场景下存在问题,为了保证数据的完整性和准确性,我们的解决方案是整合 Flink 和 Spark。流转批 eventtime 下发,具体做法为,每 10min 一批次,执行以下操作:

  • SKU 增量数据关联维表(SPU)全量数据

  • SPU 增量数据关联 SKU FDM 全量数据

  • union 后写入 m03 表

关联复杂降低策略:分主体进行维度建模,分层存储,对中间业态采用临时表。

过载控制:记录级限流,资源配置模型。

开发方式:FlinkSQL+SparkSQL 能力增强:

  • Hudi 维度表的能力,维表 lookup

  • MOR 表增量读优化,优先读取 Log 文件

  • Spark 与 Flink 混写一致性优化(索引、数据格式、eventtime 等)。spark 任务 compaction 数据 call run_compaction(op => 'run', path => '{path}');

  • 状态后端表 TTL 设定,表级别 TTL

  • 持续稳定:异常恢复、监控告警增强,对数据积压、限流、checkpoint 失败、处理流量等问题及时处理。

4. 查询优化

(1)数据缓存

  • Hudi 元数据缓存

  • Block 级文件缓存:通过将外部存储系统的原始数据按照一定策略切分成多个 block 后,缓存至 StarRocks 的本地 BE 节点,从而避免重复的远端数据拉取开销,实现热点数据查询分析性能的进一步提升。

(2)异步物化视图

物化视图是特殊的物理表,能够存储基于基表的预计算结果。当对基表执行复杂查询时,StarRocks 可以自动复用物化视图中的预计算结果,实现查询透明加速、湖仓加速和数据建模等业务需求。

具体实现如下:

  • 本地存储加速:物化视图可以利用 StarRocks 的本地存储加速优势,如索引、分区分桶和 Colocate Group,从而相较直接从数据湖查询数据具有更好的查询性能。

  • 无需维护加载任务:物化视图通过自动刷新任务透明地更新数据,无需维护导入任务。此外,基于 Hive、Iceberg 和 Paimon Catalog 的物化视图可以检测数据更改并在分区级别执行增量刷新。

  • 智能查询改写:查询可以被透明改写至物化视图,无需修改应用使用的查询语句即可加速查询。

03 效果和收益 

以上介绍了我们整体架构的优化,在抽取数据时,通过 Flink 对数据进行加工,生成大表做连接时又利用了 Spark 的相关能力,最终在 BI 查询部分,又通过 StarRocks 进行了加速。这些优化为我们带来了诸多收益。

1. 时效提升

实现了离线数据的近线时效,原本 3:00-4:00 才能完成的计算现在提升到了 0:00-0:20,仅用 20 分钟即可完成。另外,通过增量式的数据处理链路,最大化地提高了数据产出的时效性。

2. 作业效率提升

降低了构建大宽表的资源成本,将数据修改原子化(刷数、刷岗),使效率得到了大幅提升。当前 BC 每月例行刷数,需要刷 ADM 层-APP 层-在线存储层(ClickHouse)至少三层,涉及交易、用户、财务主题,约数十任务,每个任务都需重新处理数千 E 左右数据,但是 BC 维度变化影响数据量不足 5%,其中有 95% 的不变数据在浪费资源,后续可做到只修改变化数据。

3. 存储节约

数据由快照改为增量存储,降低了存储代价,同时支持回看有状态的历史快照。当前全量商品数千亿,为了能回看历史每天全量存储,一年共消耗约数 PB,使用 Time travel +Savepoint 能力,一年减少存储 90%。

4. 统一口径和 API

采用流批一体的计算链路,统一了计算引擎,天然做到了数据口径一致,较 Lambda 架构降低了 50% 的维护和对接成本。对外实现了离近线一套查询 API,业务方无须异构取数,有效提高了算法侧迭代和 AB 实验的效率。

5. 查询分层

使数仓具备索引能力,降低了模型使用的开销,提升了查询效率,同时可以直接对接主流引擎(Trino、ClickHouse、StarRocks 等),实现了查询分层。

04 未来展望和规划 

目前我们正在推进以下改进:

  • 容灾措施(机房宕机、任务重启、数据修复等)。

  • 与批任务的资源隔离,实现弹性伸缩能力,优化资源消耗。

  • 针对 Hudi 流式写入带来的小文件问题,我们尝试了通过定时的 compaction,以及分桶、分区等方式,进一步将开发一些插件使问题得到自动的解决。

  • 数据免疫系统建设。

  • 提升 Hudi 表的自管理能力,降低维护成本。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/444818.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【论文阅读】Learning a Few-shot Embedding Model with Contrastive Learning

使用对比学习来学习小样本嵌入模型 引用:Liu, Chen, et al. “Learning a few-shot embedding model with contrastive learning.” Proceedings of the AAAI conference on artificial intelligence. Vol. 35. No. 10. 2021. 论文地址:下载地址 论文代码…

强化学习笔记之【SAC算法】

强化学习笔记之【SAC算法】 前言: 本文为强化学习笔记第三篇,第一篇讲的是Q-learning和DQN,第二篇DDPG,第三篇TD3 TD3比DDPG少了一个target_actor网络,其它地方有点小改动 CSDN主页:https://blog.csdn.n…

思迈特:在AI时代韧性增长的流量密码

作者 | 曾响铃 文 | 响铃说 “超级人工智能将在‘几千天内’降临。” 最近,OpenAI 公司 CEO 山姆奥特曼在社交媒体罕见发表长文,预言了这一点。之前,很多专家预测超级人工智能将在五年内到来,奥特曼的预期,可能让这…

图论day57|建造最大岛屿(卡码网)【截至目前,图论的最高难度】

图论day57|建造最大岛屿(卡码网)【截至目前所做的题中,图论的最高难度】 思维导图分析 104.建造最大岛屿(卡码网)【截至目前所做的题中,图论的最高难度】 思维导图分析 104.建造最大岛屿(卡码网…

i18n多语言项目批量翻译工具(支持84种语言)

这里写自定义目录标题 打开‘i18n翻译助手’小程序快捷访问 打开‘i18n翻译助手’小程序 1.将需要翻译的json文件复制到输入框(建议一次不要翻译过多,测试1000条以内没什么问题) 2.等待翻译 3.翻译完成,复制结果 快捷访问

从容应对DDoS攻击:小网站的防守之战

前几天收到云服务商短信,服务器正在遭受DDoS攻击 说实话,我的网站只是一个小型站点,平时访问量并不高,没想到会成为攻击的目标。当我看到这次DDoS攻击的通知时,我其实既惊讶又有点小小的“荣幸”,毕竟我的小…

火山引擎边缘智能×扣子,拓展AI Agent物理边界

9月21日, 火山引擎边缘智能扣子技术沙龙在上海圆满落地,沙龙以“探索端智能,加速大模型应用”为主题,边缘智能、扣子、地瓜机器人以及上海交大等多位重磅嘉宾出席,分享 AI 最新趋势及端侧大模型最新探索与应用实践。 …

Java项目-----图形验证码登陆实现

原理: 验证码在前端显示,但是是在后端生成, 将生成的验证码存入redis,待登录时,前端提交验证码,与后端生成的验证码比较. 详细解释: 图形验证码的原理(如下图代码).前端发起获取验证码的请求后, 1 后端接收请求,生成一个键key(随机的键) 然后生成一个验证码作为map的valu…

JAVA接入GPT开发

Spring AI Alibaba:Java开发者的GPT集成新标准 目前,像OpenAI等GPT服务提供商主要提供HTTP接口,这导致大部分Java开发者在接入GPT时缺乏标准化的方法。为解决这一问题,Spring团队推出了Spring AI Alibaba,它作为一套标…

基于Java的可携宠物酒店管理系统的设计与实现(论文+源码)_kaic

摘 要 随着社会经济的不断发‎‏展,现如今出行并住酒店的人越来越多,与之而来的是酒店行业的工作量日益增加,酒店的管理效率亟待提升。此外很多人出门旅游时会有携带宠物的情况,但是现如今酒店对宠物的限制,导致许多…

Java学习-JVM

目录 1. 基本常识 1.1 JVM是什么 1.2 JVM架构图 1.3 Java技术体系 1.4 Java与JVM的关系 2. 类加载系统 2.1 类加载器种类 2.2 执行顺序 2.3 类加载四个时机 2.4 生命周期 2.5 类加载途径 2.6 双亲委派模型 3. 运行时数据区 3.1 运行时数据区构成 3.2 堆 3.3 栈…

【RabbitMQ高级——过期时间TTL+死信队列】

1. 过期时间TTL概述 过期时间TTL表示可以对消息设置预期的时间,在这个时间内都可以被消费者接收获取;过了之后消息将自动被删除。RabbitMQ可以对消息和队列设置TTL。 目前有两种方法可以设置。 第一种方法是通过队列属性设置,队列中所有消…

基于Springboot的宠物咖啡馆平台的设计与实现(源码+定制+参考)

博主介绍: ✌我是阿龙,一名专注于Java技术领域的程序员,全网拥有10W粉丝。作为CSDN特邀作者、博客专家、新星计划导师,我在计算机毕业设计开发方面积累了丰富的经验。同时,我也是掘金、华为云、阿里云、InfoQ等平台…

【操作系统】四、文件管理:1.文件系统基础(文件属性、文件逻辑结构、文件物理结构、文件存储管理、文件目录、基本操作、文件共享、文件保护)

文件管理 文章目录 文件管理八、文件系统基础1.文件的属性2.文件的逻辑结构2.1顺序文件2.2索引文件2.3索引顺序文件2.4多级索引顺序文件 3.目录文件❗3.1文件控制块FCB3.1.1对目录进行的操作 3.2目录结构3.2.1单级目录结构3.2.2两级目录结构3.2.3多级目录结构(树形目…

【大模型部署】本地运行自己的大模型--ollama

ollama简介 ollama是一款开源的、轻量级的框架,它可以快速在本地构建及运行大模型,尤其是一些目前最新开源的模型,如 Llama 3, Mistral, Gemma等。 官网上有大量已经开源的模型,部分针对性微调过的模型也可以选择到,…

Qt源码-Qt多媒体音频框架

Qt 多媒体音频框架 一、概述二、音频设计1. ALSA 基础2. Qt 音频类1. 接口实现2. alsa 插件实现 一、概述 环境详细Qt版本Qt 5.15操作系统Deepin v23代码工具Visual Code源码https://github.com/qt/qtmultimedia/tree/5.15 这里记录一下在Linux下Qt 的 Qt Multimedia 模块的设…

Javascript笔试题目(一)

1.JS查找文章中出现频率最高的单词? 要在JavaScript中查找文章中出现频率最高的单词,你可以按照以下步骤进行操作: 将文章转换为小写:这可以确保单词的比较是大小写不敏感的。移除标点符号:标点符号会干扰单词的计数。将文章拆…

基于Web的停车场管理系统(论文+源码)_kaic

摘要 我国经济的发展愈发迅速,车辆也随之增加的难以想象,因此车位的治理也越来越繁杂,为了方便停车位相关信息的管理,设计开发一个合理的停车位管理系统尤为重要。因而,具有信息方便读取和操作简便的停车位管理系统的设…

在启智AI平台实践ChatGLM4-9B聊天机器人@MindSpore

前段时间在昇思训练营发现一个好东西,就是昇思AI实验室:昇思大模型平台 在官方提供的jupyter AI编程实践样例中,发现了这个项目:ChatGLM4-9B实践样例 GLM-4-9B是智谱 AI 推出的最新一代预训练模型 GLM-4 系列中的开源版本。 在语…

两个数相加(c语言)

1./给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target // 的那 两个 整数,并返回它们的数组下标。 //你可以假设每种输入只会对应一个答案,并且你不能使用两次相同的元素。你可以按任意顺序返回答案。 /…