导读:本文是货拉拉大数据引擎负责人杨秋吉在 DataFunSummit 2022 多维剖析架构峰会上的演讲共享,共享的主题是《货拉拉依据 Apache Doris 的 OLAP 系统演进及建设方法》,详细解说了货拉拉从 OLAP1.0 到 3.0 的演进进程,其中不乏有值得学习的方法论以及深刻的技能考虑,期望能对大家有所协助。
共享人|货拉拉大数据引擎负责人杨秋吉
事务背景
货拉拉成立于 2013 年,成长于粤港澳大湾区,是一家从事同城、跨城货运、企业版物流服务、搬迁、轿车出售及车后市场服务的互联网物流公司。到 2022 年 4 月,货拉拉的事务范围现已覆盖了国内 352 座城市,月活司机到达 58 万,月活用户到达 760 万,包括 8 条以上的事务线。
货拉拉大数据系统为支撑公司事务,现在现已成立三个 IDC 集群、具有上千台规模的机器数量,存储量到达了 20PB、日均使命数到达了 20k 以上,而且还处在快速增长的进程中。
大数据系统
货拉拉大数据系统从下往上分为 5 层,最下面的是 根底层和接入层 ,这两层首要会供给根底数据的存储、核算以及集群的管理功用。在根底层和接入层之上是渠道层和数仓。在渠道层之中包括了数据研制渠道和数据治理渠道,依据渠道层的才干和数据仓库的数据系统,在这之上面包括了含有事务属性的服务层和应用层。整个系统自下而上相互支撑,完成支撑事务和赋能事务的才干。
图1.1 货拉拉大数据系统
数据处理流
货拉拉典型的数据处理流,可以分红数据集成、数据收集、数据存储核算和数据服务四部分,一同也包括了实时、离线以及在线三大事务场景。
图1.2 货拉拉大数据数据流
在数据收集阶段存在实时收集和离线收集两条路线。
- 实时收集比较典型的场景为用户端上埋点直接同步到大数据渠道做存储,供后续的在线和离线核算运用。
- 离线的数据首要是来自于事务方的数据库,会以天或小时为周期,定期收集到大数据存储中,以供后续运用。
中心是数据的存储和核算阶段。在离线场景中会经过对数据 ETL 之后转换为结构数仓的分层系统。实时比较典型的场景为数据在经过 Flink 的处理后会直接落在线存储系统,相似于 HBase 和 OLAP 等等,为后续的事务系统供给数据服务。
OLAP 演进概览
货拉拉从 2021 年开始进行 OLAP 的技能研究,到目前现现已历 3 个阶段:
- 2021 年上半年为货拉拉的OLAP1.0 阶段,这个阶段首要是支撑公司的罗盘事务,引入的是可以供给较好的单表聚合和查询才干的 Apache Druid 引擎。
- 2021 年下半年为货拉拉的OLAP2.0 阶段,这个阶段首要是支撑智能定位东西,引入了够供给单标明细查询,而且还有较高压缩率的 ClickHouse。
- 今年为货拉拉的OLAP3.0 阶段,伴跟着公司事务需求的不断增多,需求用到多数据源的相关剖析。依据此,由于 Apache Doris 具备大表相关剖析的才干,终究引入了 Apache Doris 引擎。
图2.1货拉拉OLAP系统演进进程
OLAP1.0 孕育期
事务需求剖析
先看下没有引入 OLAP 之前的事务数据流:
图3.1 OLAP1.0事务场景
依据该图可以看到事务的数据经过实时和离线处理之后会落在 MySQL,MySQL中储存了维度聚合之后的成果数据,这也意味着会在 Flink 之中做许多的聚合剖析,依据事务需求的相应维度所做的一系列组合都是在Flink之中做实时聚合,终究将成果储存到MySQL。
存在的问题
- 存在存储瓶颈,相似于 Kylin 之中的维度爆破的问题。
- 开发本钱高、功率低。当事务侧需求新增维度的时分需求对 Flink 中的所有作业都做必定的修改,然后再重新上线。
- 无法支撑部分聚合需求。
关于存在的这些问题,经过剖析之后,总结出了 3 个背面存在的需求点:
- 可以横向扩容,处理存储瓶颈。
- 可以自由组合维度做剖析,提高开发功率。
- 可以支撑任意时刻窗口的剖析。
处理计划
依据事务需求,并经过调研,决定运用 OLAP 引擎来支撑事务需求。那如何挑选一款 OLAP 引擎,并把它安稳的应用到出产之中呢?
咱们总结了如下的 4 个步骤作为处理思路:
图3.2 OLAP 1.0 处理思路
技能调研
技能调研阶段,对比了 Druid、ClickHouse、Kylin、Presto 和 Doris 等等引擎。结合上述的 3 个事务需求,终究挑选了 Druid 引擎 。
原因是Druid除了可以满足事务需求之外,还有一个比较重要的影响因素是 Druid 引擎是纯 Java 开发,与部门的技能栈比较符合,可控性更高。
图3.3 OLAP1.0技能调研
POC 阶段
POC 进程中,从以下 3 个步骤着手:
- 功用验证。 在功用验证中,咱们收集了事务侧的 SQL,之后提取 SQL Pattern,再依据 Druid 引擎的 Rollup 语义做 SQL 的改写,触及到许多 UDF 的改写、Rollup 语义兼容以及 Count Distinct 语义兼容等等。
- 功能验证。 直接选用事务实在的数据和事务实在的 SQL 来执行。验证进程中将 Cache 关闭,别离核算 P75、P90、P99 的查询耗时。在这进程中,有部分查询的功能没有到达要求,之后做功能剖析发现Druid 引擎本身没有比较完善的功能剖析东西,不可以很好的打印出执行计划以及各个算子的耗时,所以选用了第三方的 Arthas 火焰图进行剖析。定位到相应的耗时算子后,经过优化建表导数和索引构建的逻辑(首要经过调整 Segment 巨细和一些参数的调整,一同参加物化视图),优化功能。
- 准确性验证。 将事务实在数据一同写 Hive 和 Druid,之后跑 Hive SQL和 Druid SQL,来进行数据质量的校正。在这个进程中发现例如 Druid StringLast 等一些函数会在特定的场景下呈现核算值不安稳的问题,终究经过代码优化使之到达安稳。
图3.4 OLAP1.0 POC 验证
安稳性保证
当 POC 验证完成之后,接下来是安稳性保证系统的建设。咱们将安稳性保证分为事前、事中、事后 3 个阶段:
图3.5 OLAP1.0 安稳性保证
上线阶段
当安稳性保证系统建立完成之后就进入了上线阶段。上线相同分红了 3 个阶段:
- OLAP测验阶段。 在这个阶段中,事务的数据会接入到 Druid 之中,可是事务的实在查询仍是经过本来的MySQL库。这个阶段首要会验证 Druid 引擎的数据质量和 Druid 集群的安稳性。
- 上线调查阶段。 在这个阶段,事务的查询会切到 Druid。一同旧的MySQL链路还没有下线,事务侧可以随时切回MySQL链路。
- OLAP运转安稳阶段。 下线MySQL链路,做资源的回收。
图3.6 OLAP1.0 上出产
问题总结
下面总结了 1.0 阶段时遇到的问题:
- 数据导入部分中,实时数据乱序为典型问题。
- 在数据准确性验证阶段发现 StringLast 的函数值不安稳。
- Druid 没有一个高效的精准去重的函数。
图3.7 OLAP1.0 问题总结
OLAP2.0 完善期
事务需求剖析
在 OLAP2.0 阶段首要有以下 4 个事务需求:
图4.1 OLAP2.0 事务需求剖析
下图是简略的事务东西的截图,从图中可以看到,OLAP2.0 需求可以支撑汇总与明细,一同依据这些才干可以做一个快速的问题定位。
图4.2 OLAP2.0 事务需求剖析骤去完成。
处理计划
图4.3 OLAP2.0 技能调研
OLAP2.0 引入了 ClickHouse。ClickHouse 可以比较好地支撑杂乱的数据类型,一同由于事务侧是埋点数据,关于实时导入语义要求并不高。没有选用 Druid 首要是有 2 个原因:
- Druid 关于杂乱的数据结构支撑度并不是很好。
- Druid 尽管可以支撑明细查询,可是 Druid 的明细查询和聚合查询得分红不同的表,这样就会额外的引入一系列的存储本钱。
剩下的部分便是 POC 、上出产的步骤,这两个步骤和 OLAP1.0 阶段比较相似,在这儿就不过多打开介绍。
OLAP3.0 成熟期
事务需求剖析
2022 年跟着公司事务的开展,更多的产品线关于多数据源相关场景下的在线剖析需求也变得越来越火急。比方 AB 试验场景与实时数仓场景,这两个场景关于多表相关需求,尤其是大表的多表相关需求也变得越来越火急。
图5.1 OLAP3.0 需求剖析
举一个 AB 试验的比方。从下图可以看到,比方中是需求把 AB 试验的一个数据和后边相应的司机与用户的埋点数据相关到一同并做剖析。在这种状况下,就发现之前的两种东西都会存在一系列的坏处。
图5.2 OLAP3.0 需求剖析
处理计划
技能调研
在技能调研阶段咱们调查了 Druid 和 ClickHouse。Druid 引擎可以支撑一些维表的简略 Join,ClickHouse 则可以支撑 Broadcast 这种依据内存的 Join,但关于大数据量千万级乃至亿级的表Join 而言,ClickHouse 的功能体现不是很好。
图5.3 OLAP3.0 技能调研
接下来对 Doris 进行了调研,发现 Doris 是不仅可以支撑小表的 Join,对大表的话也相同可以支撑依据 Shuffle 的 Join,关于杂乱数据类型(Array、JSon)的支撑,经过跟 Apache Doris 社区交流,估计将在 2022 年 7 月份的新版本中发布。经过在多个维度和需求满足度上进行对比,终究挑选了 Apache Doris,也是由于 Apache Doris 的 SQL 支撑度十分完善。
图5.4OLAP3.0 技能调研
POC 阶段
本次POC阶段除了引证事务实在的数据和场景做验证以外,还引入了 TPC-DS 的数据集做了验证。在多表相关的场景下对单天数据进行查询,对 5 亿左右的数据量进行 Join,TP75 大概是 9 秒左右。在数据质量阶段咱们也是把 TPC- DS 的数据集以及事务实在数据集,别离在 Hive 和 Doris 里边做了双跑验证,发现两者都是可以彻底对得上的。
图5.5 OLAP3.0 POC
安稳性保证
与之前相同依然是从事前的容量评估和压测、事中的监控和定位来进行。
图5.6 OLAP3.0 安稳性测验
下面是Doris的监控图,首要是关于 Compaction 相关的一些监控,感兴趣的同学可以看看。(文末 QA 环节有部分解说)
图5.7 OLAP3.0 安稳性监控
问题总结
问题1: Doris查询功能的优化。
事务侧的需求是7 天的查询 RT 需求在 5 秒内完成,在优化前,咱们发现 7 天的查询 RT 是在 30 秒左右。关于这个问题,优化策略是把小表 Join 大表改成了大表 Join 小表,首要原理是由于 Doris 默许会运用右表的数据去构建一个 Hashtable。还有相似下图中的状况:union all 是在子查询中,然后再和外层的别的一张大表做Join的查询方法。这种查询方法没有用到 Runtime Filter 的特性,因而咱们将 union all 说到子查询外,这样就可以用到 Runtime Filter,这应该是由于这儿的条件下没有推下去所导致的。一同运转时选用的 Bloom Filter 是可以将 HashKey 条件下推到大表 Scan 阶段做过滤。在经过对这两者优化之后便可以满足事务的查询功能需求了。
图5.8 OLAP3.0 问题1
问题2:UnhealthyTablet 不下降,而且在查询阶段会呈现 -230 的报错。
这个问题的场景是在没有停 FIink 写使命的时分,对 BE 机器交替重启,重启完会呈现许多 UnhealthyTablet。经过剖析发现,原因一是Coordinator BE 的二阶段提交 Commit 后,大部分的副本是现已 Commit 后且在Publish前,在这短短的时刻范围内 BE 机器被重启,这也就导致会呈现 Tablet 状态不一致的状况。原因二是由于参数(max_segment_num_per_rowset)调整的过大,导致了 Compaction 压力过大。
终究的处理办法: 与 Aapache Doris 社区的同学经过互助排查,引入了社区 1.1.0的 Patch,一同对相应的数据做了恢复。
图5.9 OLAP3.0 问题2
参数优化
- 打开 Profile。Doris 关于查询的功能剖析具有十分好的 Profile 文件,这一点是十分赞的!咱们可以看到各个算子在每一个阶段的查询耗时以及数据处理量,这方面比较于 Druid 来说是十分快捷的!
- 调大单个查询的内存约束,一同把 BE 上的执行个数由 1 个调整成为 8 个,而且增加了 Compaction 在单个磁盘下的数据量。关于 Stream Load,把 Json 格局的最大的内存由 100兆调整成为 150 兆,增大了 Rowset 内 Segment 的数量,而且敞开了 SQL 级和 Partition 级的缓存。
图5.10 OLAP3.0 参数优化
数据流
下图是运用 Doris 之后的数据流图:
图5.11 OLAP3.0 数据流
数据流中,在 Flink 中做的事情现已很少了,经过数据简略的 ETL 后就可以把数据直接灌入到 Doris。经过 Doris 一系列的聚合核算、union 核算以及多表相关核算之后,事务侧就可以直接查询 Doris 来获取相关数据。
总结与考虑
总结: 咱们 OLAP 的引入首要仍是从事务需求的视点出发来匹配适宜的引擎,为事务精细化运维供给技能支撑。在这之后,咱们也考虑了一套较为完善的上线流程及安稳性保证计划,为事务的平稳运转供给才干保证。
考虑: 咱们认为很难有单个引擎可以富含各种场景。因而在技能选型时,需求针关于需求特点和引擎特点进行合理挑选。
后续规划
咱们期望可以向 OLAP 渠道化开展,经过完成自助化建模的一同在这方面做一些多引擎的路由,使其可以支撑各类聚合、明细以及相关等场景。
图6.1 后续规划 OLAP 渠道化
除 OLAP 渠道化之外,后续咱们的引擎演进计划从高效、安稳和内核演进三部分来进行。
图6.2 后续规划引擎演进
安稳性方面: 对 Doris 继续深化内核了解,进行必定的二次开发。别的 Doris 社区的相关原理以及代码级别的教程数量十分丰厚,这也间接性降低了咱们深化 Doris 原理的难度。
内核演进方面:咱们发现 Doris 基本可以覆盖 Druid 所有场景,因而后续计划以 Doris 引擎为主,Clickhous 引擎为辅,逐渐将 Druid 的相关事务向 Doris 搬迁。
Q&A 环节
Q:方才讲到了后续要从 Druid 引擎搬迁到 Doris,要完成搬迁的本钱有多大呢?
A:搬迁本钱方面和咱们之前的本钱是相同的。咱们上线的时分也会选用以下方法:先把事务的数据一同往 Druid 和 Doris 之中写,写完之后的事务搬迁会触及一些 SQL 改造。由于 Doris 更加接近MySQL的协议,比起 Druid SQL 会更加快捷,所以这部分的搬迁本钱不是很大。
Q:方才介绍的第二个场景之中的监控图都看了哪些指标呢?
A: 关于监控图,咱们会比较关注 Doris 的数据导入。而在数据导入部分,咱们最关注的便是 Compaction 的功率,是否有 Compaction 的堆积。咱们现在仍是选用的默许参数,也便是 Compaction 的分数就代表它的版本号,所以咱们监控的更多的是它的版本。关于这方面的监控,社区也现已有了比较完善的相应技能计划,咱们也是参考了社区的技能计划来进行了监控的指标搭建。
Q:从指标上看,Doris 的实时服务在线查询功能怎么样?在数据导入状况下功能损耗可以从这些指标上看出来吗?
A:实时导入方面首要是从 Compaction 的功率来看。结合到咱们这边的事务场景,最多的一张埋点表,单表一天也有 6 亿到 10亿的数据量的导入。别的关于峰值,它的 QPS 也是能到达千到万的,所以导入这一块压力不是很大。
Q:SQL 缓存和分区缓存实际作用怎么样?
A:SQL 缓存方面作用还好,关于许多离线场景,尤其是首页这种查询的数据量而言。比方以昨日或者是曩昔一个小时之前的这种状况来说,SQL 缓存射中率会十分高。分区级缓存方面,咱们分区的时刻仍是设的是小时级,这意味着假如这个查询里边触及到的一些分区在一个小时内没有数据更新的话,那么就会走 SQL 缓存;假如有更新的话就会走分区级缓存。整体来看作用还好,可是咱们这边射中比较多的仍是 SQL 级的缓存。
Q:Doris 的查询导入兼并和缓存的 BE 节点的内存一般怎么分配?
A:缓存方面咱们分配的不大,仍是选用的偏默许的 1G 以内。导入方面咱们设计的是 parallel_fragment_exec_instance_num这个参数,大概在 8G 左右。
Q:可以解释一下 OLAP3.0的处理思路吗?
A:关于 OLAP3.0方面来说,事务的首要诉求便是大表Join。除此之外,还有一些相似于导入的进展一致等等。在大表Join方面,咱们也对比了许多的引擎。Druid 这方面便是偏维表;Clickhouse这方面仍是偏依据内存方面的 Broadcast。正因如此,首要是依据大表Join的起点,咱们挑选引入了在Join这方面才干更强的 Doris。
Q:Druid、ClickHouse 和 Doris 应该都是近实时的,便是 Near Real-time,他们的写入不是立刻可见的,是这样吗?
A:是这样的。像 Doris 和 ClickHouse 之前的写入都是 Flink 直接去写,咱们也没有彻底做到来一条数据就写一条,都是一个微批次。一个批次最大可以到达 150 兆的数据堆积,写入一次的时刻距离也是到 10秒左右,没有做到彻底的实时写入。
Q:方便透露一下货拉拉目前 Doris 的集群的运用状况,比方机器的数量和数据量吗?
A:咱们的集群数量还不算许多,10多台。
Q:关于 Doris 的运维方面,它的快捷性和 Druid、ClickHouse、Kylin、Presto 这些比较,有很好的扩展性吗?
A:咱们觉得是有的。第一个是在咱们 Druid 方面碰到了一个比较大的痛点,便是它的人物特别多,有 6 种人物,所以需求布置的机器会十分多。别的一点是 Druid 的外部依靠也十分多,Druid 依靠于 HDFS、离线导入还需求Yarn 集群。
第二个是 ClickhHouse 方面,咱们当时运用的版本关于 Zookeeper 也是有比较大的依靠。别的,ClickHouse 也是偏伪分布式的,有点相似于数据库的一种分表。Doris 自身就只有 FE、BE,外部依靠会十分少,所以咱们从布置的视点一同考虑到 Doris 的横向扩展方面,Doris 的扩缩容也可以做到自平衡,所以比较而言 Doris 会更好一些。
Q:在实时特征场景下,分钟级的数据更新对服务功能要求比较高,可以用 Doris 吗?能到达 TP99 200毫秒以下吗?
A:TP99 可以否到达200毫秒以下首要和你查询 SQL 相关。例如咱们这边的许多触及到大表 Join 的查询,触及的分区数据量大概在 10亿量别,事务侧关于查询功能要求是 5 秒以内,经过 Doris 是可以满足咱们需求的。假如是实时特征这种事务,是否能到达 200毫秒可能需求经过一轮实际测验才干得到成果。