Apache Doris 在橙联的应用实践:数仓架构全面革新,千万数据计算时间从 2 小时变成 3 分钟
导读:为了适应快速的增长需求,橙联于 2022 年正式引入 Apache Doris,以 Apache Doris 为核心构建了新的数仓架构,构建过程中对服务稳定性、查询稳定性、数据同步等多方面进行了优化,同时建立了以 Apache Doris 为核心的数据中台,在这一过程中积累了诸多使用及优化经验,在此分享给大家。
随着公司业务的发展和数据的不断增长,早期基于 MySQL 的传统数仓架构已经无法应对公司数据的快速增长。业务的需求和运营的决策对于数据时效性的要求越来越高,对数仓准实时能力的需求越发强烈。为了适应快速的增长需求,橙联于 2022 年正式引入 Apache Doris,以 Apache Doris 为核心构建了新的数仓架构,构建过程中对服务稳定性、查询稳定性、数据同步等多方面进行了优化,同时建立了以 Apache Doris 为核心的数据中台,在这一过程中积累了诸多使用及优化经验,在此分享给大家。
# 数据架构演进
早期数仓架构
随着公司业务规模扩大、数据量激增以及对数据时效性要求不断提高,使⽤ MySQL 进⾏数据分析越来越不能满⾜业务⽅的要求。 没有对数仓进⾏分层划域,烟囱式的开发模式数据复⽤性很差,开发成本⾼,业务⽅提出的需求不能快速得到响应。 对数据的质量和元数据的管理缺乏管控。
新数仓架构
采⽤ MySQL 协议和语法,⽀持标准 SQL,可以通过各类客户端⼯具来访问 Doris,能够与 BI ⼯具⽆缝对接 ⽀持多表 Join,针对不同场景的 Join 提供了多种优化⽅案 ⽣态扩展完善,离线数据的⾼效批量导⼊、流式数据的低延迟实时导⼊都有很好的⽀持 相较于业界其他热⻔ OLAP 数据库,Apache Doris 的分布式架构⾮常简洁,只有 FE、BE 两个进程,运⾏不依赖任何第三⽅系统 ⽀持弹性伸缩,对于部署、运维⾮常友好。
数据的预聚合以及预聚合结果的⾃动更新 数据的实时更新 ⾼并发查询
架构介绍
如以上架构图所示,我们的数据源共有4种,业务数据 MySQL、文件系统 CSV、埋点数据和第三方系统 API;针对不同的需求,使用了不同的数据导入方式,文件数据导入使用 Doris Stream Load,离线数据使用 DataX doriswriter 进行数据初始化,实时增量数据使用 Flink CDC + Flink Doris Connector 的方式进行数据同步;数据存储和计算层使用了 Doris ,在分层设计上采用 ODS(Operation Data Store 数据准备区,也称为贴源层)、 明细层 DWD、中间层 DWM、服务层 DWS、应用层 ADS 的分层思想,ODS 之后的分层数据通过 DolphinScheduler 调度 Doris SQL 进行增量和全量的数据更新。最终上层数据应用使用自研的一站式数据服务平台,可以和 Apache Doris 无缝对接,提供自助报表、自助取数、数据大屏、用户行为分析的数据应用服务。
# Apache Doris 构建数仓优化方案
服务稳定性
优化前
FE 负责元数据的管理、用户请求接入、查询的解析规划,资源占用较低,因此将 FE 和其他大数据组件混合部署 FE*3。 BE 负责数据存储、计算、查询计划的执行,资源占用较大,因此 BE 进行独立部署且分配了较多的资源 BE(16C 128G 4T*1)*7。
基于以上方式部署,使用初期运行的稳定性还不错,然而在使用一段时间之后,这种部署方式暴露的问题就越来越明显。
首先,FE 混合部署存在资源竞争。其他组件与 FE 服务竞争资源,导致 FE 资源不足,服务运行稳定性不好。具体问题表现在:每当机器资源使用率打满,就会导致 FE 节点无法连接,长时间获取不到心跳而被 FE 集群判定为离线。 其次,BE 单磁盘存在 Compaction 效率低的问题。初期,我们在部署 BE 时,每个节点只分配了 1 块 4T 的磁盘,虽然磁盘的空间并不小,但是磁盘的数量比较少,Compaction 线程数只有 2,Compaction 效率很低,这是导致 BE Compaction Score 不健康的原因之⼀。 Compaction 配置参数:
compaction_task_num_per_disk
每个磁盘上的任务数,默认为 2 max_compaction_threads Compaction
线程的总数,默认为 10
total_permits_for_compaction_score Compaction
任务配额,默认 10000
Compaction 工作机制:Apache Doris 的数据写⼊模型使⽤了与 LSM-Tree 类似的数据结构。数据以追加(Append)的⽅式写⼊磁盘,在读逻辑中,需要通过 Merge-on-Read 合并处理写入的数据。Merge-on-Read 会影响读取的效率,为了降低数据读取时需要合并的数据量,使⽤ LSM-Tree 的系统会引⼊后台数据合并逻辑,以⼀定策略定期的对数据进⾏合并。
优化后
FE 进行独⽴部署,避免了 FE 混合部署资源竞争问题 BE 进行磁盘拆分,多磁盘部署,从原来一块 4T 磁盘变更为 5 块 1T 磁盘,使 BE Compaction 线程数提升 5 倍,Compaction 效率、磁盘 I/O 带宽也得到了提升。 增加客户端连接代理层 ProxySQL,对 FE 连接进⾏负载均衡,解决 FE 连接单点问题。 增加 Supervisor 对 FE、BE 服务进程状态监控,FE、BE 进程意外宕机可以快速恢复。
查询稳定性
优化前
随着使用时间和数据量的增加,集群开始频繁出现不可用的问题,主要体现在以下几个方面:
DDL 操作很难执行,查询速度变得比较缓慢。 FE 服务频繁出现 OOM 宕机,有时候甚至出现无法连接的情况。
下图是生产环境某张表的体积的大小和 Tablet 数量的情况。这张表的体积只有 275M,但是 Tablet 的数量却达到了 7410,这非常不合理。进一步排查确认整个集群 Tablet 数量非常庞大,集群只有 5T 的数据量,然而 Tablet 数量达到 150 万。
优化前的 FE
数据同步优化
优化前
全量同步使用 MySQL Dump -> CSV -> Doris Stream Load -> Doris 增量同步使用 Flink CDC -> Kafka -> Flink Doris Connector -> Doris
数据调度优化
我们在使用 DolphinScheduler 进行 Doris SQL 的任务调度时,同一 node 下配置多条 SQL 时会出现 node 执行状态异常的情况,导致工作流 DAG 的 node 依赖失效,前一个节点未执行完,后一个节点就开始执行,结果会有缺数据甚至没有数据的情况。这个问题是因为 DolphinScheduler 2.x 在同一个 node 下不支持按顺序执行 MySQL 的多段 SQL,而 Doris 在 DolphinScheduler 中使用 MySQL 数据源创建连接。
实现方案
我们将元数据分为物理元数据和业务元数据两大类:
物理元数据维护表的属性信息和调度信息 业务元数据维护数据在应用过程中约定的口径和规范信息
表级血缘支持粗粒度表关系和跨层引用分析 字段级血缘支持细粒度的影响分析
架构介绍
元数据管理和数据血缘实现方案技术栈
数据采集:使用 Apache Doris 提供的审计日志插件 Doris Audit Plugin 进行数据采集 数据存储:对审计日志插件做了定制化开发,使用 Kafka 存储 Doris 审计日志数据 血缘解析:使用 Druid 进行 Doris SQL 解析 血缘关系存储:使用 Nebula Graph 存储血缘关系数据 业务元数据:因为业务元数据经常发生 CRUD,因此使用 MySQL存储业务元数据信息 搜索数据:使用 ElasticSearch 存储血缘关系查询索引以及表和字段的搜索索引数据
接下来介绍一下个架构四个组成部分:审计日志的采集和清洗服务、血缘解析服务、元数据信息整合服务、应用接口服务。
Apache Doris 审计日志的采集/清洗服务
Connector Manager 负责创建 Apache Doris 和 DolphinScheduler 的元数据链接,同时也支持后续其他类型数据源接入的扩展。 Meta Service 负责元数据信息获取的具体实现。Apache Doris 元数据信息主要从 information Schema 库、Restful API、以及 SHOW SQL 的查询结果三种途径来获取。DolphinScheduler 的工作流元数据信息和调度记录信息从 DolphinScheduler 元数据库获取。
我们提供了 3 种类型的应用接口服务,分别是血缘应用接口服务、元数据应用接口服务和数据行为分析应用接口服务。
血缘应用接口服务提供表、字段、血缘关系、影响分析的查询服务。 元数据应用接口服务提供元数据的查询和字段搜索的服务。 数据行为分析应用接口服务提供表结构变更记录、数据读写记录、产出信息的查询服务。
以上就是元数据管理和数据血缘分析架构的整体方案的全部内容介绍。
# 总结及收益
最后,欢迎更多的开源技术爱好者加入 Apache Doris 社区,携手成长,共建社区生态。
▶ 打造自助对话式数据分析场景,Apache Doris 在思必驰的应用实践