淘菜菜主业务为社区团购,消费者通过在淘宝、微信等端上的淘菜菜小程序购买商品后,采用次日达的配送到团长手中,然后再到团长那里取货。
具有以下几个特点:
1、生鲜电商,能满足消费者一日三餐的需求
2、提供高性价比商品,即便宜又好品质
3、面向三线城市及以下的下沉市场
4、建立三级仓配方式,共享仓、中间仓和网格仓,降低履约成本
5、通过团长实现履约的最后一环,为消费者提供服务
淘菜菜实时数据场景多样,有实时播报(保证快速交付、高保障)、仓库实时作业(高性能,持续服务)以及指标中心和自助中心(多维OLAP、灵活)。
实时任务数最高可达400+;Flink 资源和Hologres资源分别1w+,重要任务70%以上;实时吞吐日均超2000万/s,日均输出超50万/s。
淘菜菜实时架构的演进分为四个阶段:
阶段1:16年之前原始架构- jstorm阶段
该阶段为实时数仓的初期建设,主要用于零售通团队的实时作战大屏,以及核心数据产品的报表看板等。技术方案采用的jstrom,有专门的实时团队同学支持,实时任务数10个以内,实时计算的资源在3000+CU。
阶段2:16-20年传统架构-FlinkSQL阶段
16年之后,零售通业务开始规模化增长,因此业务场景变得更加丰富,包括实时大屏、实时营销活动分析、渠道实时分析等。这个阶段主要基于Flink SQL发展,同时离线开发同学慢慢开始加入,和实时团队同学配合进行实时需求支持。直到到19年B系研发同学开始独立支持实时数据体系的建设,这个时期实时任务数快速增长到500+。资源使用也比第一个阶段上升30%。
阶段3:20年实时数仓 - Flink+Hologres阶段
随着业务的快速发展,实时数仓的建设越来越臃肿,也开始出现一些开发和运维问题。而当时Hologres也开始在集团内大面积推广,于是我们开始考虑用一套新的方案解决老架构存在的问题。因此这个阶段开始基于Flink+Hologres进行实时架构升级。
在这个阶段,零售通和盒马优选合并成淘菜菜团队。面对日益增长的数据,技术上主要要解决的问题就是实时开发提效,追求高效率、高灵活,以此来满足淘菜菜所有小二实时&离线数据的查询需求,核心应用场景包括交易实时多维分析,物流供应链实时服务、指标中心自助分析和离线报表加速等。
我们用了一年的时间(从20年9月到21年9月)完成了架构升级,通过新架构缩短了实时处理链路,提高数据处理效率,让实时数仓变得更加高效快捷。
阶段4:21年高可用实时数仓-Flink+Hologres读写分离部署
21年架构升级完成后,在新的阶段,我们的核心目标就是提升新架构的稳定性。同时业务发展也逐渐趋于稳定,除了常规场景的支持,也开始参与双11、双12等大促节日,因此成本的治理也开始提上日程,我们期望能够用最简单的架构,最少的资源支撑所有的场景。
在高可用稳定性方面,我们使用写链路的主备链路,应用层使用Hologres多子实例共享存储的部署方式,主实例用于写,不同子实例用于不同场景的查询,这样做能够非常好的做到读写分离、资源隔离以及开发生产隔离。
在成本治理侧,我们主要采取了将闲置实时任务及时治理、Hologres表存储优化等手段,21年共计节约200w+资源。
目前新的架构在淘菜菜业务稳定运行中,在本文中我们将会介绍为什么要进行架构升级,以及架构升级后我们遇见的挑战和对应的解决方案,以帮助大家更简单高效的建设实时数仓。
从研发视角来看,实时数仓应该具备以下几个特性:
- 高效率:传统架构选型太多,导致门槛较高。而且运维时查问题或定位问题比较耗时间。
- 高可用:需要能够提供持续化服务,出现问题时可快速恢复。
- 低成本:以最低的计算和最低的存储提升稳定性。
2020年之前,传统数仓面临的问题主要可以归纳为以下三个。
第一,开发效率低。
输入端、输出端、服务均由多种选型,另外不同维度指标开发时存在重复开发。代码调试需要完整地运行,导致调试难度大。数据测试运行在存储里,无法查看中间结果,链路越长则测试成本越高。
第二,运维成本高。
· 任务排查耗时长:实时任务链路长,部分应用层ADS的设计达到5层,加上ODS和DWD总共达到7+以上的层次,再加上有些任务本身逻辑复杂,导致整个计算链路非常长。另外由于实时本身的State不可见,在问题排查的时候非常困难,平均一个问题定位到解决就需要半天以上,严重影响线上查询效率。
· 长周期回滚难:由于上游采用的TT中间件(Datahub),只能回滚3日数据,对于长周期去重指标回滚就会有问题,同时为了保证数据一致性,需要另外将离线数据加入才能进行回滚。在压测的时候,上游的数据量不够,无法达到压测预期,还需要额外造离线数据。
第三,资源浪费。
有些实时数据并不是高频使用场景,比如大促预热期的多维实时蓄水效果监控跟踪,日常基本没查询,仅在大促前两天需要使用,日常的实时计算就会导致浪费计算资源。
基于以上痛点,我们对Hologres进行了调研,发现一些优秀能力:
1、高性能 OLAP 意味着逻辑可以写在后端,
2、共享盘古,很多数据可以直接进行加速并使用,不需要再导入 MySQL 或 HBase。
3、实现离线和实时模型统一,避免代码放在不同地方运行。
4、拥有行存长周期 Binlog 的能力,可以像普通中间件一样提供订阅消费能力,可以解决长周期指标计算的问题。
因此,我们在双 11 进行了Hologres试点,实际效率得到很大提升。最终,淘菜菜决定使用Hologres支持所有内部应用。后续,我们也计划用Hologres对商家或合作方、消费者侧的应用进行全面覆盖。
2020年,淘菜菜使用Hologres替换传统数仓,主要目标为存储统一、计算升级、应用服务统一。
存储统一:将中间公共层全部替换为Hologres,得益于binlog能力,替换之后可以解决长周期指标计算的问题。且出现问题后可以直接排查,无需将数据存到另外的存储里再进行查询。另外,公共应用层也进行了全面升级,能够支持不同的应用场景,比如分析场景、产品点查能力。
计算升级:实时数据扫完可直接回写到离线数仓,保证实时离线逻辑统一。另外也做了列式更新,不同实时任务更新同列的不同字段,各个字段之间的逻辑相互独立,任何延迟或问题都不会影响其他字段。提供服务时效率会更高,无需再写多个任务的不同表。
应用服务统一:用Hologres提供数据存储之后,可支持不同的OLAP 查询,点查服务也全部通过Hologres实现了支持。
此阶段的核心目标是提效,但是过程中也出现了一些问题。
1、出现了性能瓶颈,后续我们通过Table Group 重构、表结构优化和资源隔离解决了问题。
2、实时任务逻辑后置到应用,出现了指标不一致性问题。后续我们通过数据监控,实现分钟级别的核心指标巡检以及指标中心管理指标口径、核心指标逻辑下沉解决了问题。
经历第一次升级之后的一些价值:
1、实现BU 级别的实时架构实现了统一,技术选型和开发提效;
2、无需维护实时任务,逻辑置于后端直接写 SQL 即可输出数据,开发效率得到很大提升;
3、技术选型也有了比较明确的选择,层次变少,排查问题更高效。
2021年双十一前后,该架构出现一些严重问题,一个月内出现多次故障,稳定性风险变得越来越大。主要原因在于很多开发人员建表或使用数据库时过于随意,没有约束。很多重要场景没有对业务提供持续化服务,业务不可接受。且存在资源浪费,虽然出现问题之后可以加资源,但持续加资源并不是长久之计。
另外一个问题是:当时的架构为行存和列存两个实例,数据需要开发两次,开发效率低,存储浪费,研发成本高。另外,要对数据的生命周期进行控制,很多无效数据不应该长期占据存储空间。
基于此,我们针对稳定性从事前、事中、事后进行了架构升级。
1、事前阶段:
1)公共层不只有Hologres,也新增了中间件,两者互备,出现问题时可以互相切换。
2)应用层升级为1写3读,将实时数据和离线数据全部写到主实例,通过不同读实例来提供不同服务。另外,上线了同城灾备,因为读写分离全部在集群里,如果集群集体故障依然会存在问题,因此需要同城灾备来保证服务不出现问题。
3)同建立规章和制度,对开发人员的使用进行约束。
4)实现了评估治理,评估holo表是否存在风险,对慢SQL进行监控,提前识别异常情况并进行治理。
2、事中阶段:监控集群的异常指标,出现问题时能够及时预警,且建立了快恢机制。
3、事后阶段:通过定期复盘发现问题并进行改善。
成本治理方面主要采取策略:
1、无效表的识别,主要通过执行记录扫描确认其否依然在被查询,针对查询结果进行治理和下线,
2、生命周期方面会通过 SQL 访问跨度为其提供建议。
3、对于异常binlog开启 治理。
经过以上改进,故障次数从月均6次降为0次,存储从400T缩小至40T,效果显著。
接下来我通过几个案例来简单介绍下我们几个典型应用场景是如何实现的:
第一个案例就是指标中心&自助分析平台的场景:
前面有提到看数维度比较多,从总部到区域的各个层级、角色都需要各种交叉看数,单一支持效率低,而且经常会有数据不一致的问题。
因此我们建立了指标中心,并配置出自助分析的页面,支持业务自助选择维度和指标进行多维数据分析:
1、首先我们会将实时、离线明细数据写入到holo主实例中,实时放当日分区,离线放历史分区
2、然后在指标中心配置指标口径和支持的维度
3、配置自助分析的场景,然后发布上线,业务就可以进行自助的勾选和分析了。
自助分析平台读取的是其中一个只读实例,当通过监控识别到该实例出现异常的时候,我们会切换数据源到另外一个只读实例,以支持数据的持续可用。
第二个案例是物流实时作业跟进的场景:
物流场景的几个特点:
1、作业流水状态变化非常快,包括入库、出库、调拨等,且有大量累积指标。
2、同一份数据既要在报表上看,还需要提供数据服务嵌入到小二工作流中
3、非常重要,不看中断。仓库小二会根据实时数据进行作业,如果数据有问题直接影响物流的作业进度,需要保障服务的99%以上可用。
方案是:用现有架构的行存公共层会提供长周期 Binlog 消费,订阅时间更长。应用层有行列共存应用实例,可以提供服务报表一体化服务,报表和应用都可读。服务数据做了容灾实例,考虑到成本,由服务直接读取容灾实例,出现问题时再切回主实例,提高容灾实例的使用率。
升级后的架构为淘菜菜带来了极大的效果和价值。
第一,统一技术框架。通过 Flink+Hologres支持了所有计算、存储和服务。
第二,高效支持业务看数。因为开发实时任务数变少,很多逻辑置于后端,可以直接写 SQL 查询数据,交付周期缩短 30%以上。另外,存储选型变得简单,不用学习复杂的新技术,而且能够支持各种量级的数据和场景。数据测试也变得简单,因为测试层次变少。成本缩减 50% 以上,出现问题可以马上定位,长周期指标回滚更高效便捷。
第三,持续化服务能力。此前抓取较大问题时,时常因为排查不及时导致问题放大,而如今可以彻底避免该类事件的发生。实时数仓较大影响问题的发生频次从原先的月均3次降低为0-1次。
未来,我们希望从三个方面继续加强:
① 更加稳定。继续完善规范,与Hologres进行合作,提前识别风险并提前治理。出现问题时能快速定位并启动应急预案,能够支持高SLA场景 99% 可用。
② 高效。探索Hologres物化视图,将逻辑后置,无需开发实时任务、直接写SQL即可运行数据得出结果。实现行列共存和流批一体,最终快速支持100%数据应用。
③ 更加低成本。要以最小的成本实现最好的稳定性和效率,提升无效表识别精度,大 SQL 优化,实现动态扩缩容,最终实现成本最优。
Q&A
Q:ODPS 的数据更新频率和 Hologres的数据更新频率如何分配?
A:这是两个技术方案。 ODPS 偏离线,用离线来进行每日更新,或准时比如 15 分钟更新一次。而小二要求看实时数据,但可以容忍偶尔的服务故障,可以通过实时写明细到 Hologres里,再写一个SQL、指标中心或物化视图,来支持小二查看实时数据。
Q:从数据周期上看, ODPS 里是全量数据,而Hologres里是一天或两天频率的数据吗?
A:主要是看场景,离线和实时数据都可以全量。比如将实时数据初始化一次,每天更新它,则为全量。也可以同步增量,每个分区里都是增量,加起来则为全量。
Q:Hologres 同城容灾的实时同步如何实现?
A:实例之间 Binlog 实时同步。Hologres实例分为几种容灾方式,一种是同机房共享存储的多实例,数据不同步,但计算有多个,相当于内存中有两个实例,状态实时同步。本文介绍的示例为两份存储,不管是同城还是异城,技术都一样,都是多份存储,存储之间通过 Binlog 同步。主实例故障之后,上面不会再有新数据,由从实例来同步数据。