京东零售数据仓库演进之路
Posted 过往记忆
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了京东零售数据仓库演进之路相关的知识,希望对你有一定的参考价值。
尹翔,京东零售数据仓库技术负责人,负责数仓体系的建设,2013年加入京东,一路伴随京东大数据的发展,在这个过程中,数据仓库也经历了几次升级。本文主要介绍京东零售数据仓库建设上的发展历程与一些实践。
今天的分享主要分为三个部分,首先回顾一下大数据在国内的发展历程,第二部分,会介绍随着京东的快速发展,大数据在内部经历的几个主要阶段,重点是第三部分,京东零售数仓核心能力和场景实践。
本文根据尹翔老师在2021年10月20日【第十二届中国数据库技术大会(DTCC2021)】现场演讲内容整理而成。
大数据的发展,大体来讲可以分为三个阶段:
第一阶段,2010年之前,是企业级数据仓库的时代,也叫EDW,以关系型数据库为主。当时Oracle、Teradata等传统软件厂商占据了大部分市场,基本上提供了数据仓库建设从硬件、软件到实施一体化的解决方案,建设成本非常高,当时主要集中在金融、电信、保险等行业,数据仓库的主要应用场景是提供报表,用于经营决策。
第二个阶段,大概在2010年前后,随着移动互联网的高速发展、数据量暴增,很多互联网公司开始基于hadoop生态搭建大数据平台,来应对大数据量的处理。数据应用的场景也更加丰富,比如互联网广告、精准营销、供应链管理、abtest等
第三个阶段,大概从5年前,也就是15、16年前后,业界开始提出数据中台的概念,通过大中台、小前台的模式,驱动业务创新和提效。数据中台组件化、智能化的方式,将通用的数据开发场景和工具进行沉淀,来提升开发效率,再通过数据的资产化、服务化的方式提升业务数据使用效率,让业务更加聚焦在数据应用和业务创新上,而不是花费大量的精力进行数据能力的重复建设
从数仓的视角下,来看数据中台的技术架构,是伴随着数据的采集、存储、计算、管理、应用这些环节延展开的。
从这里可以看到,数据中台的技术生态是非常复杂的,这里涉及到非常多元的技术和产品,而且这些技术也在高速发展阶段,每年基本都会涌现大量的新产品和技术,这些特点就给企业实施数据中台带来了很高的技术门槛,如果技术路线不清晰,很可能会造成很大的风险和隐患
我们回顾京东零售大数据的发展历程,也经历了几个重要的阶段,从最开始的野蛮生长,到后来的精细化运营、以及现在的数据驱动业务,从过去的大数据平台阶段也升级到了现在的数据中台阶段。
第一阶段,在17年之前,是野蛮生长的阶段。当时的特点是烟囱式开发,业务发展很快,靠中心化的团队很难支撑所有业务需求,因此在大数据平台之上,每个业务线需求都是闭环的数据团队在支持。
但到后来这种烟囱式开发,导致了数据不互通、重复造轮子、研发效率低的问题,光数据集市就上百个,相似的数据产品也有非常多,占用了大量的存储和计算资源,数据口径也无法对齐,内部沟通和管理成本变得很高。于是就到了第二阶段,在17、18开始精细化运营,建设数据中台,打通各集市间的数据,更加注重数据资产的沉淀,也开始围绕业务场景,去搭建场景化服务的能力,去支撑业务的精细化运营场景。
第三阶段,是数据驱动业务的阶段,也是现在我们所处的阶段,精细化运营可以看作是专家经验的沉淀,中台也在考虑怎么进一步释放产能,降低研发门槛,以智能化的方式进行数据生产、管理和应用。比如低代码的开发平台,以及像智能选品和用户增长这些应用。
以上,我们简单回顾了一下京东大数据发展的几个阶段。
经过这些年,目前在数据中台已经沉淀了覆盖京东全链路业务场景的全域数据资产。我们基于对零售业务的深度理解,将业务场景抽象成数据模型体系,来描绘业务之间的关系,同时也会考虑到如何存储、计算、管理这些数据,这些都非常考验数据中台团队的业务能力、技术能力和数据治理能力。最终我们将沉淀的数据资产,应用到全链路的业务场景中,比如用户增长、营销策略制定、供应链管理、仓储布局规划、配送路径规划等等,在这些场景中得到验证和反馈,形成正向的循环,不断地将数据资产体系建设得更加完善。
在建设全域数据资产的过程中,数仓扮演了非常重要的角色,期间也面临了非常多的挑战。
像烟囱式开发,资源重复浪费,而且因为数据缺少打通和合理架构的规划,业务需求的迭代变得越来越慢。数据量在京东这几年也是呈几何级、爆发式的增长,单纯地依靠增加服务器,也已经很难解决存储和计算的难题!
随着数据资产建设的日益丰富,对于那些已经存在了几十万张的数据模型,如何有效地进行管理,便捷地找到数据?
另外,京东的业务复杂度也非常高,从最初的线上自营和第三方模式,全品类的商品,拓展到线下业务,以及全渠道、多个业态场景,组织变化也非常的快,带来数据资产的挑战。
在实时方面。业务越来越来越极致,过去从天、到小时、再到分钟,以及现在秒级的数据,而实时开发的门槛相比离线也比较高,周期也很长。
时效性方面。不管数据量和计算量怎么增长,业务对于时效性的追求确实越来越高。
我们是从四个维度,构建核心起来数仓的核心能力,来解决前面提到的这些问题。
包括统一的数仓架构、规范化的数据建模,数据质量的保障,以及数据资产的管理,来建设统一、标准、高质量的数据资产体系,提升数据服务化的水平,支撑业务价值实现。
我们是基于hive构建的数仓,架构上,我们从过去垂直烟囱式的开发,形成了现在统一的数仓分层架构。目前主要分为6层,每一层的定位、目标以及建设方法都不相同:
首先是BDM缓冲数据层,是用来缓存来自业务系统的数据库、消息、日志等临时数据,他的表结构与业务系统保持一致,并且只为FDM贴源数据层提供服务。
接着是FDM贴源数据层,这一层主要是存储全量业务系统的数据,并且能够支持还原业务系统的数据快照,按照业务系统数据变更的特性,一般会用拉链或者增量流水的方式存储,一般情况也不对外开放。
再往上的GDM、ADM和DIM是数仓的核心层,会开始按照业务特性,搭建各主题模型,主要是基于维度建模理论,去搭建公共的维度、实时数据、以及相应的宽表。
DIM维度层,主要是对通用的维度,进行统一标准化定义,进行维度复用。
接下来是GDM和ADM,都会去按照业务划分主题,也都会做数据的清洗和整合,只不过一个面向生产一个面向业务,GDM是面向生产,去做技术口径的封装,对生产系统的数据,进行清洗、整合,屏蔽生产系统的干扰,保障基础数据的高可用,ADM则面向业务,做业务口径的封装,去形成统一的维度和指标,消除口径的二义性。
ADM公共数据层,会划分两层,adm d 和s,adm-d主要负责统一的数据口径封装,提供最细颗粒度的维度和实时数据,同时封装各种口径的标识,adm-s会基于adm-d 进行各种维度场景的聚合和指标汇总。
最后是app 应用数据层,它主要是面向业务场景,提供具体场景的数据加工,直接提供给数据应用。
有了统一的数仓分层架构作为基础,我们也从过去开放式的数据开发,逐步形成了统一的数据建模方法论,来规范数据建模的过程,最后我们落地成了工具,来保证方法论和规范的落地。这张图就是我们内部数据建模工具,描绘了我们从业务板块的划分数据域、到一些规范的管理,再到规范化建模的过程。
在模型体系设计上,我们构建了数据总线矩阵,划分了业务域、主题和业务单元这三层,实现顶层设计的清洗完整。业务域是我们内部相对独立运营的的业务板块,比如线上零售、互联网医疗、B2B这些都是独立的业务域,在每一个业务域下,会根据业务特点,划分成多个主题。比如零售业务,会按用户的照购物旅程,拆分成流量、交易、客服等多个主题。每个主题下,会划分多个业务单元,每个业务单元会对应一个或者多个业务事件。比如在交易主题下,会拆分成下单、支付这些业务单元,业务单元就等同于概念模型,它最终会被映射成逻辑模型和物理模型。
在数据模型的构建上,我们主要是基于维度建模的思想去设计和开发模型。我们会定义统一的维度,并物化成维表,形成维度市场,供各个事实表去复用。业务单元会基于事实和维度数据,设计成大宽表,便于下游应用。
在指标管理和开发上,基于规范化的数据模型,我们可以进行指标的定义,我们将指标拆解成原子指标和派生指标,这样最大程度去复用原子指标的定义和逻辑,来消除指标口径的二义性。
最终保障了,数据模型体系以及数据指标体系的规范性,也减少了重复建设。
数据资产管理方面,我们的思路是,围绕数据的全生命周期,去构建丰富的元数据,基于元数据进行数据治理、并提供资产化的服务。整个过程链接了数据生产者和数据消费者两端,我们涵盖了从数据资产的规划、建设、采集、盘点、评估、应用、销毁等环节。
元数据分类上,我们切分了两个维度,一方面包括了元数据的范围,比如模型元数据、指标元数据、标签元数据等,尽可能的丰富,另一方面从类型上,也划分成技术元数据、业务元数据、管理元数据等,从更丰富的分析数据资产情况。
基于元数据的治理方面上,我们从数据生命周期管理、数据质量、数据安全共享、数据地图、数据百科、数据血缘这几个方面为数据治理提供更多的抓手,来保证数据资产的高质量,最后再将这些高质量的数据资产,通过服务化的方式提供给数据消费者,降低数据消费门槛。
质量保证方面,我们覆盖了从数据开发过程、到上线后的日常保障,不管是数据质量,还是数据时效,我们从事前、事中、事后,都提供了高标准的保障能力。
事前,在开发阶段,我们有标准的开发流程,并且做到了生产与开发隔离,部署了独立的开发环境,对任务和脚本也都进行版本管理,并且能够一键发布上线,发也支持一键回滚,能够快速恢复。
事中,在上线后,我们的目标是快速发现问题,通过时间基线去管理任务时效,通过一些配置化的校验规则,通过旁路数据质量,一旦发现时效和质量的异常情况,会电话到值班的同学去处理,而且对于不同等级的任务,有不通的预警策略,如果任务没有被处理,会一直上升到leader,知道任务在处理。所以不管是数据质量的问题,还是时效性问题,都可以快速发现。
事后,也就是发生后问题后,我们通过快跑通道,来达到快速恢复的目标。夜间任务出现问题产生延迟时,会预测撞线的概率,去触发队列的一件快跑,和一键推迟的功能,给核心任务让路,来保障时效。
接下来,我会介绍一下我们在离线、实时和批流一体上的场景实践和探索。
首先是离线上,关于超大数据量快速更新的一个实践,叫刷岗。什么叫做刷岗呢?简单来说,就是刷新sku、岗位、业务人员的关系,来控制权限。他是京东零售内部非常典型的业务场景,京东上有几百亿的sku,成千上万的品类,京东的采销业务人员,管理商品的颗粒度非常细,在行业内基本都是按照类目、或者按照店铺去管理,但是在京东特有的自营和pop模式的特点下,就需要按照sku的颗粒度去管理生意,并且控制权限,每个人只能看到自己管理的商品。这样就需要建立sku 和 岗位和人的关系,比如采销员可以看哪些sku,部门经理可以看哪些,总监可以看哪些都不一样。但是,采销业务经常会发生岗位调整,每次调整就需要去刷新sku 和岗位的关系。举个例子,一个采销员之前负责小米,今天负责华为,那么就需要按照华为对应的岗位,去更新历史数据,这样才能保障调整岗位之后,可以正常看到历史数据。而且每天都有大量的岗位调整,小到采销员,大到部门品类负责人,这就是刷刚的场景。
大概分成四个阶段,最开始数据量并不大,我们就简单粗暴的全量刷新。到后来,我们发现数据量增长的特别快,作业跑的越来越慢,而且经常跑不出来,所以后来我们想了一些办法,对数据进行预处理,比如对事实表做一些列的裁剪、轻度聚合,对商品维表,只保留那些变化的信息,这样可以大幅缩小数据量,我们把这个方案叫增量刷岗,刷完之后,进行各种维度的计算,存在hive里,再提供到业务。
第三个阶段,我们发现业务看数据的视角越来越丰富,维度组合非常的多,甚至上千种,而且遇到uv、用户数这种需要去重的指标,每种维度组合都需要计算出来结果,过去通过离线预计算的方式,不管是带来的资源消耗、存储消耗、以及人力投入都是巨大的,因此我们拆分出来一些细颗粒度的维度场景,把事实和维度都导入到olap中,我们使用的是ck,通过local join根据查询需求随时进行刷岗、聚合,大大降低了维护成本、以及资源成本。
到现在,我们已经形成了融合多种刷刚方案的服务,我们也在尝试利用iceberg的事务更新的特性,进行优化,只更新有变化的那些条记录,也能够大幅减少数据量。
在实时数仓上的实践,我们目前主要也是用业内主流的Flink+kafka的方案,来搭建数仓。原来的方式,我们会设计三层,每一层都物化成topic,发到kafka里,我们发现,这种方式建数仓,层级比较多,而且也很难像离线一样建设大宽表,因为这样会导致时延性增加,而且消耗的存储和计算资源也比较多。因此我们也是借鉴视图的思路,把实时数仓的建模过程全部逻辑化,将逻辑模型的定义、结构、处理逻辑片段等信息,存储在元数据中,通过这种方式把逻辑模型体系搭建起来。
最后会跟据应用层需要的计算的数据,将使用到的逻辑模型的代码片段,进行裁剪和优化,生成最优的执行计划,并生成任务。并且呢,当我们也会识别数仓中的热点路径和关键模型节点,再进行数仓模型的物化。这样我们在前期就可以参照离线模型体系,比较低成本的构建逻辑化的实时数仓模型。
从前面的分享也可以看到,我们现在还是非常典型的lambda架构,实时和离线分开去计算,使用的都是不同的存储和计算框架,最后再放到统一的存储引擎中,给上层应用提供给数据服务。
这种方案,目前看还是存在了一些痛点:1、需要同时维护了实时、离线两套计算框架,运维的成本比较高,2、实时和离线数据口径要对齐,因此在两套开发框架上,要实现两套业务逻辑相同的代码,开发成本也很高,而且随时时间的推移,链条链路上都在各自迭代,非常容易造成数据的不一致;3、另外,如果完全依赖实时数据,对消息队列的存储要求又很高,持久化存储带来的成本非常高,而且数据回溯的能力也不如离线。
因此,我们内部也在实践流批一体的数据湖解决方案,在一些场景上去落地。数据湖和数仓有什么区别呢,基于hive 的数仓的方案上其实也是有些痛点,比如不支持事物,并发往数仓读写入数据,可能会存在一些问题,不支持数据的更新,数据修正的成本就比较大,需要重写分区,schame变更的成本也比较大,变更了之后需要重写数据,整体的数据时效也是比较长的。数据湖的特性,在一定程度上是可以解决这些问题,支持ACID的事物读写,这样读和写就可以并发的进行,没有提交的数据就不会被读取到,支持upsertt,很方便的进行数据行级别的更新,table revolution,可以很低成本的变更schame,并且不需要重写数据,同时批流的读写接口,可以增量读取数据,来提升时效性。
我们最终是选取iceberg的方案,delta lake是深度绑定spark的,不支持其他计算引擎。hudi一开始也是深度绑定spark,底层直接使用spark的rdd,后来才重构的。iceberg一开始架构就比较独立,有自己的数据类型和schema,不依赖其他计算引擎。
利用Iceberg 表的增量读取更新,以及对批流都有友好的接口支持,来构建批流一体的实时数据湖。上游实时数据,经过Flink或者spark streaming的加工,存储到Iceberg中,Iceberg又作为实时源,供下一层使用,最终通过hbase、ck这些引擎,给上层应用提供服务,整体的数据延迟,基本上是分钟级的,而且每一层Iceberg表,也都是持久化的存储,上面这些spark、flink等等计算引擎,也都是可以读写iceberg表。这种架构方案,在我们内部在逐步实践,像一些流量日志数据的计算场景,以及库房抽取数据的场景,以及刷岗的场景,在应用。
从未来的趋势来看,流批一体、湖仓一体、云原生数仓这些技术,将会是未来的趋势,现在这些方案也在业界被实践和验证。整体来说,还是希望能够进一步提升资源利用率,以更加便捷、智能、安全的方式支撑业务。
流批一体:通过一套引擎(Flink),解决流、批割裂的问题,业务可针对不同场景需求智能化选择流、批计算的能力,低成本、高效率的新开发模式,让业务专注自身能力发展,加速迭代;
湖仓一体:基于开放标准的湖仓一体存储架构,实现对异构数据统一、高效管理,兼具数据湖的扩展能力和高性价比、以及数据仓库的易用性和高性能,支持对EB级数据近实时的存储、更新和探查分析,业务可使用更全面的数据做深度洞察、实时分析和经营决策;
云原生数仓:基于云原生架构,实现OLAP系统的存储计算分离,达成高效弹性扩缩容能力,实现云原生数仓;更加高效支撑核心业务的实时多维数据分析需求,成为业务实时经营分析、决策的发动机。
以上是关于京东零售数据仓库演进之路的主要内容,如果未能解决你的问题,请参考以下文章