美团餐饮 SaaS 基于 StarRocks 构建商家数据中台的探索

本文简介

  • 作者:何启航,美团餐饮 SaaS数据专家(文章整理自StarRocks Summit Asia 2022)

StarRocks 极速查询、 简单部署、高效运维等特点,很好满足了美团商家数据中台的需求,查询性能提升了 28 倍以上。

 

咨询案例

本文发表于: &{ new Date(1667491200000).toLocaleDateString() }

随着社会经济的发展,餐饮连锁商家越来越大,“万店时代”来临。对于美团餐饮 SaaS来说,传统的 OLTP 引擎已经无法满足当前数据生产和查询场景,亟需一款 OLAP 数据引擎解决数据查询复杂度大幅提高、数据价值挖掘能力不足等痛点。经过多方测试比对,美团餐饮 SaaS 选择了 StarRocks 来构建商家数据中台。本文将从业务介绍、技术选型、数据中台、建设成果等四个方面,介绍美团餐饮 SaaS 如何基于 StarRocks 为商家构建数据中台。

01 业务介绍

首先,概要介绍一下美团餐饮系统,及其使用的数据产品和基本的系统架构,以及业务所面临的痛点。

1.  美团餐饮系统

上图左侧展示了美图餐饮系统的功能全景图。可以看到其功能非常丰富, toC 的部分包括扫码点餐、外卖、团购等;toB 的部分,比如老板看到的一些经营分析、财务管理、进销存等。根据场景,系统分为线下和线上两个部分:线下,为餐饮商户提供餐厅数字化解决方案,帮餐厅实现从前厅管理、后厨生产管理、会员管理、线上运营管理,到供应链管理的整套数字化经营;线上,实现餐厅和平台的打通,帮助餐厅链接顾客,帮助餐饮商户了解顾客、商圈,辅助商业决策,并为顾客带来更好的消费体验。 

2. 数据产品

上图展示了美团餐饮两大类数据产品的截图,左侧是核心报表产品,右侧是智能应用。可以看到报表种类很多,有汇总表、明细表、业务预警表、财务统计表等。智能应用的截图是一个商家选址的应用。商家可以通过地图去选择一块区域,然后根据一些标签,比如业态、流量等去选择合适的经营地址。

我们的数据产品的使用者包括厨师长、收银员、老板、店长、财务,业务场景包括:

经营分析:如分析营业额、收入等。

智能决策:利用分析结果进行智能决策,比如为老板推荐什么菜卖的好,该如何配置套餐等等。

业务预警:老板可以配置一些阈值,比如收营员一天返结多少钱、退账多少钱,一旦达到阈值就要通知老板及财务对账。

财务对账:一些比较大的商家每个月或者每个季度都有专门的财务进行对账。

以上场景决定了我们的业务具有以下特点:

  • 数据质量高
  • 迭代效率高
  • 查询体验好
  • 数据体量大

其中数据质量高是非常重要的一个特点。美团餐饮数据产品不同于一般的大数据产品,一般的大数据产品主要是作分析决策使用,而我们的场景中除了分析决策还要作财务对账。财务对账是和钱挂钩的,算错一分一厘都有可能引起客诉,严重情况还会引起资损,所以我们这里对数据质量要求非常高。这也影响了我们后续的技术架构选型,以及整体的系统设计。

3. 系统架构
 

我们整体中台的架构和市面中台的架构是基本一致的,最下面是业务数据,从下往上,根据数据处理流程分为以下几层:

第一层是数据同步层,使用公司的同步组件将数据入仓,到数据生产层。

第二层是数据生产层,分为离线数仓和实时数仓两块,从上图可以看到,离线数仓和实时数仓都采用了相同的分层模型,这样的目的就是为了提高迭代效率。其他数据团队,实时和离线通常是两组人员来开发,离线可能使用 Hive 等批计算引擎,实时可能选择 Flink、Spark 等流式系统进行烟囱式的实时指标开发。我们为了加快迭代效率,统一了离线和实时数仓,采用了基于 SQL 的开发模式,让一些离线分层模型可以得到复用,从而提高了迭代效率。

第三层是数据存储层,选择了稳定性比较高的 MySQL 作为存储引擎,但是随着数据的持续增长,MySQL 会有性能和存储的瓶颈,因此也逐渐引入了一些 HTAP 的存储引擎,如 TiDB。

第四层是数据服务层,提供一些原子的基础服务,支撑百花齐放的数据应用。

第五层就是数据应用层,包括报表和数据应用等。

为了保证数据质量,在这套架构上还横向增加了监控系统和稳定性保障系统。监控系统主要是为了发现数据质量问题,并将其报给稳定性系统;稳定性保障系统会识别这些问题,然后选择合适的方式去自动修复异常数据,进一步提高数据质量。

以上就是我们的数据中台的整体系统架构。

4. 业务痛点

随着业务发展,连锁商家越来越大,我们迈入了“万店时代”,大一点的连锁管理的连锁店可能有上万家,这样就带来两个痛点:

(1)第一个痛点,这些商家查询的数据量和复杂度大幅提高,具体有三个方向的挑战:

数据存储量大(单表 10T 级别,数百亿数据)

单次查询上千万数据量

查询复杂度高,最多涉及 5 张表 Join,数十字段 Group 聚合

(2)第二大痛点是,这种级别的商家一般会有自己的研发和 IT 人员,所以他们也要求独立的数据价值挖掘能力,自己去分析数据集,这也带来了三个方向的挑战

  • 异构数据源的融合,商家可能使用不同的系统,比如收银使用美团,而供应链、财务、人力用的是其它系统,在做数据分析时需要将不同的数据融合在一起统一进行分析,所以需要我们的数据中台具备异构数据源融合的能力。
  • 这种规模的商家一般会自己采办 IDC 独立进行部署,因此需要我们整体的数据中台的部署,并且要低成本、高效的进行部署。
  • 现在我们数据中台提供的一些业务模型和功能都是普适性的,是给一般商家使用的,但这种规模的商家一般都有自己独特的需求,希望我们能够提供一些大的底表,然后他们根据这些底表去做分析。

面对这些痛点,传统的 OLTP 引擎无法满足当前数据生产和查询的场景。

02 技术选型

接下来介绍我们的技术选型的过程,以及 StarRocks 的特性。

1. 存储选型

前文提到 TP 引擎已无法满足我们的使用场景,所以需要一款 AP 的引擎来解决以上痛点。但是由于我们是从 TP 引入到 AP ,因此查询性能好只是最基础的一个要求。我们要根据自身业务特点,还要适配现有架构来进行选型,所以除了性能,我们还要考虑使用成本、易用性和运维成本。

  • 使用成本:我们要求 AP 引擎要具有很好的 Join 能力,因为现在数仓沿用分层模型,主题表会涉及到很多表的关联操作,如果 Join 能力不够就会需要模型的调整,改动就会比较大。
  • 易用性:查询端接口都是使用标准的 SQL 协议进行查询,因此我们希望新的 AP 引擎也具备标准的 SQL 协议,这样查询端就无需做太多更改。
  • 运维成本:由于商家可能希望进行独立部署,需要运维成本比较低,这样就不需要投入过多的研发和 IT 资源。

基于以上几点我们对比了市面上常见的 AP 引擎,Druid、Clickhouse、Kylin、StarRocks,最终选择了 StarRocks。

2. 选择 StarRocks

再来具体看一下 StarRocks 是如何满足我们商家数据中台需求的。

上图左侧列出了 StarRocks 的一些特点,包括极速查询,简单部署,以及高效开发三大方面。

这些特点可以帮助我们应对右侧所列的技术挑战,自下而上来看:

  • 独立部署:因为 StarRocks 是不依赖其他任何外部系统的,同时可以在线进行节点的扩缩容、自动故障恢复,所以它可以满足我们独立部署的要求。
  • 多数据源接入:StarRocks 支持市面上大部分数据源,所以这一点也是满足的。
  • 高效迭代:StarRocks 支持多种建模方式,支持多种 Join 方式,在引入的过程中整个数仓不需要做很多更改,我们的迭代效率会很高。
  • 大规模存储:StarRocks 是分布式的数据库,所以天然满足大规模存储。
  • 极速查询:StarRocks 作为全新的 MPP 执行框架,相对于其它 AP 系统还做了很多独特的优化,比如向量化执行引擎,以及 CBO 的一些专项优化等等,因此其查询速度非常快。
  • 低代码 BI:依托极速查询,可以做一些底表,商家能够通过拖拉拽的简单方式实现一些即席分析。

03 数据中台

这一章节将介绍我们引入 StarRocks 之后新的数据中台架构,以及一些关键设计,会分为5 个部分:

基于 StarRocks 的数据中台架构、数据同步、虚拟视图、智能分级查询、多活热备

1. 基于 StarRocks 的数据中台架构

新的数据中台在架构上并没有太多改变,只是在各环节增强了能力。原始数据层,新增了异构数据源,这样可以支持商家其它产品数据的接入;数据同步层基于 StarRocks 的导数功能,扩展了数据同步的能力,让其更加高效;数据仓库层,还是沿用了当前数仓分层的模型设计,新增了 StarRocks 的数据源,整体业务采取了混合存储的模式;再往上,实现了零代码的 BI,基于 StarRocks 极速查询的能力,支持大的 KA 进行自助分析。

下面具体介绍一些技术要点

2. 数据同步

整个数据生产系统采用的是 Lambda 架构,离线数据通过 Hive 计算;实时数据通过我们自研的实时计算系统,将数据生产到 Kafka。基于此我们的数据同步也分离线和实时两个部分来设计。

首先,上图中蓝色的部分是专为离线数据设计的同步功能,分为三块:全量导数、增量导数和变更导数。全量导数,顾名思义,就是将全量的数据导入到 StarRocks。由于我们的数据量非常大,有数十 TB,全量导数是十分耗费资源的,并且时间也比较长,因此我们仅会在表的初始化,或者表出现问题需要重新导入时才会使用全量导数。对于历史数据的变更我们是结合增量导数和变更导数来实现的。增量导数是指只导最近一段时间的数据,数据量会比较少,比如只导最近一个月的数据,通过分区替换的方式来更新 StarRocks 的数据。但是变更还可能是在一个月之外的数据,所以在上游还会有另外一个离线任务去计算一个月之外产生变更的数据,计算完之后就会自动触发变更导数。变更导数会拿到历史变更数据并对 StarRocks 的数据进行覆盖。通过增量导数加上变更导数的方式,我们实现了历史数据的更新,同时这种方式也大大减少了日常的导数量。我们进行了一个估计,10T 的数据可以控制在 100G 左右,这样可以很大程度提高我们数据同步的效率。

下面绿色部分是实时数据的同步,实时数据的同步没有做过多的设计,直接采用的是 StarRocks 的 Flink-Load。通过这种方式可以将数据同步到 StarRocks 中,但是我们采用的是混合存储的方式,也就是数据会在多个数据源中存储,那么就存在数据一致性的问题。为了解决这个问题,我们专门设计了同步保障系统。上图中最右侧同步保障系统,有两个模块,第一个模块是监控系统,提供了多种监控方式,比如流式监控,实时监控 StarRocks 的变更数据,与其它数据源变更数据进行实时校验,并将异常进行记录。还提供批量监控的功能,对 StarRocks 中的数据计算一个汇总值,比如算一张表的总金额、总订单数,然后和另外一个数据源的总金额和总订单数进行比对,如果发现有问题就说明数据在处理过程中存在问题,也会将这些数据异常记录下来。所有记录下来的异常会交给异步纠错模块,这个模块会去识别 StarRocks 整体的负载能力,当它低峰期的时候就会异步进行修复。通过这种方式可以保证数据的最终一致性。从而提高了整体的数据质量。

3. 虚拟视图

另一个关键设计是虚拟视图。上图左侧是我们现有的数仓开发模式,可以看到我们的数仓 RD 采用实时和离线计算平台,使用分层的数仓模型进行开发,同时离线和实时采用相同的分层模型,分层模型是基于血缘关系进行预计算的,每一层的数据都物化存储到了 MySQL 当中用于加速查询,最终数据应用的一个查询过来,只需要查询 ADS 层就可以将结果返回给客户,这样就可以加快整个查询。

然而这种方式在新的数据中台中无法满足低成本、高效的独立部署,原因主要有两点:

  • 沿用现有方式,需要额外部署一套离线计算系统和实时计算系统,增加了部署成本。
  • 抛弃分层模型,采用烟囱式开发,那么和内部系统是两套逻辑,会导致迭代慢。

针对以上问题,我们的解法是,基于 StarRocks 高效的查询能力和 Google 提出的 Shasta 理论,我们提出了虚拟化视图。整体的分层模型不变,开发方式也是一致的,但是 DWT  层和 ADS 层是虚拟化视图,也就是数据不做物化存储。当一次查询过来时,还是会查询  ADS 层,这时系统会判断如果 ADS 的数据是虚拟视图,就会将 SQL 进行下推,下推到 DWT 层,这时系统会发现 DWT 层同样是虚拟视图,然后 SQL 还会持续下推,一直推到 DWD 层,这一层是做了物化存储的,就会生成一个真实 SQL 去查询 StarRocks,最终将结果返回给用户。

以前无法实现虚拟化视图的原因是,下推的 SQL 会非常复杂,传统的 TP 引擎根本无法查询出来。

虚拟视图的优势可以总结为以下三点:

  • 首先,沿用分层模型,对于数仓 RD 是没有感知的,仍然按照分层模型来开发,无论虚拟视图还是物化视图都是系统自动判断,因此对于他们来说还是可以做到逻辑复用,提高迭代效率。
  • 第二点是去预计算,DWT 和 ADS 这种重计算的层级被我们虚拟化了,所以不需要额外去部署离线计算系统和实时计算系统,由此可以达到低成本的部署。
  • 第三点是数据无状态,可以加快迭代。按照以前的开发模式,如果数仓 RD 的逻辑出现了 Bug,DWT 和 ADS 层的数据会出现问题,就要进行数据重刷,在非常大的数据规模下,在保证稳定性的同时去重刷 DWT 和 ADS 层的数据,这个动作是非常重的,有可能需要几周的时间,迭代就会非常慢。而采用虚拟化视图的形式,所见即所得,当逻辑出现问题时,只需要修改 DWT 和 ADS 层的 SQL 逻辑,查询时直接查询 DWD 层,就可以即时生效。DWD 层一般就是简单的数据清洗入仓,通常不会有很多逻辑,所以问题也比较少。通过这种方式去掉了数据状态,从而加快了迭代效率。

通过这三个优势,保证了我们数据中台低成本、高效的独立部署。

4. 智能分级查询

我们的查询有如下特点

  • OLAP 并发能力低于 OLTP 引擎,当前场景高峰期并发查询 QPS 很高(万级别),压力很大;
  • 99%+的查询数据量小(数十万以内),这部分查询 OLAP 和 OLTP 性能差距不大,但如果全部放在 OLAP,收益较低,同时也会增加 OLAP 引擎的稳定性风险。

所以我们的整体思路是减少 OLAP 的并发压力 ,提高每次查询的 ROI。我们设计了分级查询,智能预测查询数据量,合理路由(MySQL->TiDB->StarRocks),数据量大的去 StarRocks 查询,数据量小的就去 OLTP 查询。

上图下半部分展示了整体的系统设计。系统提供了一个智能查询 SDK,是嵌入到接口服务当中的,因此对上游业务是没有感知的,上游并不知道查询的是哪个数据源,但可以快速拿到数据。智能查询 SDK 分为两个模块,一个是数据源自动切换模块,会根据我们的分级策略自动选择不同的数据源,去查询返回数据。

核心模块是智能分级策略模块,其分级策略有两个部分,一个是实时的动态路由配置策略,这是 RD 根据经验进行配置的,比如通过经验发现商户在查询大于一个月的数据量时会很慢,这部分需要 OLAP 引擎去加速,就会配置一个到 OLAP 去查询的策略,这部分是人工配置的策略。第二部分是机器自动识别的策略,我们会有离线任务,每天批量地去分析现有商户查询的数据量,比如分析出某些商户在某些场景下的查询性能比较差,这一部分需要加速,就会记录下来,在后面查询时,如果命中这些记录就会放置到 OLAP 中去查询,提升查询体验。通过这种智能分级的策略,提高了每次查询的 ROI,同时也增强了 OLAP 的稳定性。

5. 多活热备

最后一个设计要点是多活热备,也是为了增强稳定性。

多活热备分为两层,第一层是 StarRocks 的主备集群的切换,第二层是 OLAP 集群和 OLTP 集群的切换。在此之上我们还增加了数据质量监控和自动降级恢复两层。

其运作方式为:

  • 首先,数据质量监控系统会实时监控数据质量,一旦发现数据质量降到了一个水位线之后,会自动触发 StarRocks 的主备切换。
  • 如果数据质量还没有恢复,则会再次触发降级,从 OLAP 降到 OLTP 系统,前面提到这种查询有可能在 OLTP 上是查不出来的,所以这种降级是有损降级,会牺牲查询体验,但是整体风险是可控的。
  • 当告警恢复后,会自动切回到 StarRocks 主集群上进行查询。

04 建设成果

我们的探索过程分为 4 个阶段:

第一个阶段是可行性验证,主要验证了虚拟视图可以秒级出数,满足实时分析的场景。

第二个阶段是性能压测,相比之前的 OLTP 引擎,查询性能提升了 28 倍以上(复杂场景从数十秒到亚秒级别),吞吐在餐饮 SaaS 场景下约为 0.16qps/c。

第三个阶段是试点运行,完成了一套试点集群的搭建和对应的系统建设,整个试运行期间未出现事故,整体查询体验得到了较大改善(tp90 提升 30%,tp99 提升 500%)。

最后一个阶段是正式部署,现在还没有实施,后续会根据商家的需求进行独立部署。

05 总结

经过一段时间的探索,StarRocks 已经有一套试点集群,其极速查询、 简单部署、高效运维等特点能够很好地满足美团商家数据中台的需求。目前对 StarRocks 的使用还处于初级阶段,后续会继续探索更多高级功能,覆盖更多业务场景,持续提升美团 SaaS 数据中台的能力。最后,也期望 StarRocks 越做越好。