作业帮-Doris在数仓中的实践

伴随着业务的快速发展,由于确实统一的查询系统,作业帮整个数据中台交付项目的成本非常高,达到数人周甚至月,为了解决如上问题,引入Apache Doris,并基于Doris做了统一元数据、统一读写服务、规范化运维等的工作,数据中台交付效率提高数十倍,目前以小时级交付;并对与特定场景下的查询性能提高了数十到数百倍;查询服务保持高稳定性,线上运行近1年,0事故(>=p2)。本次分享将分享这其中的实践和踩过的坑。

展开查看详情

1.Doris 在作业帮实时数仓中的应用&实践 糜利敏 1

2.目录 • 业务与背景介绍 • 基于Doris的实时查询系统 • 未来规划 2

3. 业务与背景介绍-数仓逻辑分层 ADS 业务侧应用数据。如某个课程、部门下的学生答题情况;流量分析等 业务线团队 明细查询 聚合查询 DWS 聚合事实数据。如每个学生在所有题目的做题情况 大数据团队 实时聚合 离线聚合 DWD 明细事实数据。如每个学生在每个题目的做题情况 数据摄入 ODS 业务侧日志。如Mysql-Binlog、前端打点日志等 数据流动方向 3

4. 业务与背景介绍-过去的业务支持模式 业务线团队 ES 业务线团队 Spark ES 大数据团队 Spark Kafka 大数据团队 数据清洗 业务线裸查ES 业务线构建成本高 学习成本高、性能差 重复建设、且无法复用 稳定性差、Sql不完备 业务线团队 业务线团队 API API 大数据团队 大数据团队 ES Druid 非标接口 case by case 建设 需独立维护 数据清洗 效率低,维护成本高 不支持明细 4

5.业务与背景介绍-总体架构图 OpenAPI 实时查询 工作台…… 流量类分析…… Druid/ES/ Doris On ES Doris Kafka/API/… Kafka 数据清洗 Flink-Sql Spark Kafka 数据摄入 Flume Canal 5

6.业务与背景介绍-效果 过去 现在 收益 • 技术选型:Spark/API/ES/…… • 基础数据写入Doris/ES • 交付效率:数人周/月 -> 小时 • 开发、联调…… • 业务侧基于Sql进行查询 • 裸用ES,千万级数据查询 十小 • Doris/Doris on ES高性能查询 • ES:十小时 -> 分钟级 时+ • Doris:分钟级 -> 秒级 • 前端基于Mysql做报表 • Doris 易运维(无第三方组件、Mysql接口)、社区支持度好 • 目前半年时间,7+业务线。近1T数据 • 0事故(>=P2) 6

7.目录 • 业务与背景问题介绍 • 基于Doris的实时查询系统 • 系统选型&原理 • 应用实践 • 未来规划 7

8.基于Doris的实时查询系统-业务场景 • BI、报表…… • PV、UV…… • 日活…… • 特点:明细、聚合 • 聚合:作业帮 主APP在某一天的活跃用户 • 明细:作业帮 主App各个小时段各个版本下的活跃用户 Date App ActUV 2020-05-01 zuoyebang 100 … … … Date Hour App version ActUV 2020-05-01 13 zuoyebang 12.11 50 … … …

9. 基于Doris的实时查询系统-业务场景 • 教研工作台 Lesson(课程ID) student_id(学生ID) …… tearcher_id(教师ID) attend_time(出勤时长) …… 1000 12345 1111 1800 某节课内,各个老师的学生出勤数: select teacher_id, count(student_id) from attend_table where lessonId=xxx and attend_time > 300 group by teacher_id

10.基于Doris的实时查询系统-查询引擎调研 查询引擎 特点 性能 备注 Presto on ES • Sql接口 查询延迟99分位 ~25s 无法支持聚合 • 不支持DDL • 部分语句如limit无下推 • 列名必须小写 Duird • 只支持聚合,明细数据丢失 查询延迟:~秒级 无法支持明细 • 非Sql ES-Sql(6.3版本) • Sql语法不完备(如不支持 查询延迟:~秒级 无法支持聚合 join、多列groupby等) • 使用复杂,使用调试size参 数避免数据遗漏 Doris • Sql语法完备 查询延迟:~秒级 聚合、明细(流 • 易运维 量类) • 支持Rollup • Schema在线变更 Doris on ES • Sql语法完备 查询延迟: ~秒级 明细(工作台) • 任意列检索 • 高性能 Doris/Doris on ES 统一的满足了各个场景下数据查询的需求 10

11.基于Doris的实时查询系统-Doris简介 • MPP架构的OLAP引擎 • FE:解析、元数据;BE:执行、存储 • 同时支持高并发点查询和高吞吐的Ad-hoc查询 • 同时支持离线批量导入和实时数据导入 • 兼容MySQL协议和标准SQL • 支持Rollup Table和Base Table的智能路由 • 支持Schema在线变更 • 丰富的数据模型(Aggre、Dup…) • ……

12. 基于Doris的实时查询系统-Doris数据模型 • Aggregate模型 • RollUP预聚合,提高查询性能 dt app uv(bitmap) pv(sum) RollUP表 2020-08-15 zuoyebang 23 350 dt hour app version uv(bitmap) pv(sum) Base表 2020-08-15 13 zuoyebang 11.27.13 10 100 2020-08-15 13 zuoyebang 11.12.14 12 200 2020-08-15 14 zuoyebang 11.27.13 11 150

13. 基于Doris的实时查询系统-Doris数据模型 • Doris on ES模型 • ES任意列检索 Lesson(课程ID) student_id(学生ID) …… tearcher_id(教师ID) attend_time(出勤时长) …… 1000 12345 1111 1800 Key Value 某节课内,各个老师的学生出勤数: select teacher_id, count(student_id) from attend_table where lessonId=xxx and attend_time > 300 group by teacher_id

14.基于Doris的实时查询系统-DoE高性能的设计 • Doris on ES总体架构 Doris FE Shard Meta BE BE BE Http Scroll ES DataNode DataNode DataNode MasterNode

15. 基于Doris的实时查询系统-DoE高性能的设计 • Doris on ES 比 裸访问ES快的原因 搜索两阶段模式 Query Then Fetch Query:排序获取Top ID Fetch:根据Top ID获取Doc 分析场景模式 Query And Fetch 直接获取过滤后文档

16. 基于Doris的实时查询系统-DoE高性能的设计 • Doris on ES 比 裸访问ES快的原因 • 扫描速度优化 • 顺序扫描 • 传输速度优化 • 行列自动选择 - 列存优先原则 • 就近原则 – 计算找数据 • 分片级并发 • source/path filter – 提高带宽利用率 • 谓词下推 • 提前终止加速(limit/first-time-scroll)

17.目录 • 业务与背景问题介绍 • 基于Doris的实时查询系统 • 系统选型&原理 • 应用实践 • 未来规划 17

18.基于Doris的实时查询系统-架构图

19.基于Doris的实时查询系统-实践案例 • 元数据/表管理 • 数据写 • 数据读 • 低延迟 • 高吞吐 19

20.基于Doris的实时查询系统-元数据 • 元数据存在的必要性 • 最优化性能保证 • Doris on ES 列存 尽力而为:需保证ES index 全部开启列存读取 • 查询稳定性 • ES 与 Doris 类型不一致,会导致查询出错: keyword vs bigint • 不一致字段Schema,会导致数据同步质量不可控 • 使用效率 • es建index、doris建表需要配套 • es新增字段,doris表重建 • doris建表、rollup…… • 其他 • Flink Sql 强依赖元数据构建DDL…… 20

21.基于Doris的实时查询系统-元数据 • 方案 • 统一数据模型 <env, db, table -> Fields & Index & Storage> • Json-Schema 约束列值域 类型域 元数据类型 物理存储类型(ES) 物理存储类型(Doris) Common VARCHAR Keyword VARCHAR BIGINT Long BIGINT INT Long INT DATE DATE DATE …… …… …… Doris DORIS::BITMAP - DORIS::BITMAP …… …… 21

22.基于Doris的实时查询系统-元数据 • 方案 • 统一数据模型 <env, db, table -> Fields & Index & Storage> • Json-Schema 约束列值域 系统Meta字段,数据行更新时间、ES IndexID 22

23.基于Doris的实时查询系统-元数据 • 效果 • 查询效率保障 • 100% 列存访问 • 查询稳定性 • 由于数据质量问题导致的异常:0 CASE • 运维效率 • 平台化表管理:CreatTable/AlterTable/RollUP/… • 提高系统自动化、稳定性的基础 • Openapi/Flink…… 23

24.基于Doris的实时查询系统-OpenAPI • 为什么做OpenAPI(query/upserts) • 稳定性保障的基础 • 避免业务端滥用、误用(如连接数过多……) • 屏蔽系统实现,提高易用性 • 可能后期会变更doris、es(版本升级、集群切换……) • 需要针对业务线设置query_time、exec_mem_limit……

25.基于Doris的实时查询系统-写 • Upserts • 表抽象为Env/DB/Table, 统一数据模型 { "env": "bzr_online", • JsonSchema 校验,保证数据质量 "database": "inclass", "table": "attend", • 自动写入Meta字段,提高Debug能力 "data": [{ "_id": "CU_98765_123456789", • UpdateTime/IndexID/… "_version": 1600188562, "subject": "82235", • _version做版本控制,避免乱序覆盖 "coursetype": "100", "grade": "7" • Monitor }] …. }

26.基于Doris的实时查询系统-写 • Upserts – 乱序流写入下的问题背景 问题 • 离线修数和实时流写入同一个Table(ES index)。导致乱序覆盖 • 修数数据规模大,避免乱序只能牺牲写入的时效性

27.基于Doris的实时查询系统-写 • Upserts – 乱序流写入下的解决 方案 • 修数流、实时流隔离,写入各自topic • 数据同步服务基于topic限速消费 • 基于_id & field => _version,对字段级做版本管理 效果:数据正确性&时效性 得到兼顾

28.基于Doris的实时查询系统-读 • Query • Sql语义。业务方最大效率使用数据 • Sql缓存 • 解决 F5刷新、系统Bug、重复Sql执行等场景的性能和稳定性问题 • 系统参数,如query_timeout…… • 某业务线上线后 • 访问doris规模下降90+%,TP99延迟下降40倍(16s->400ms), CPU IDLE 50% 提高到 95%

29. 基于Doris的实时查询系统-微批模式调度 • 业务场景 • 统计某个学部下(各个老师)的学生上课情况:上课人数… 课中数据 Kafka/… 教师信息 redis/… lesson student teacher attend_time begin_time … teacher dept(学部) … 1010 1000 12345 30 2020-07-01 12345 1 … 17:05:15 Flink/Spark 多流join • 修数成本高:强依赖主数据流来驱动 结果表 Doris dt hour lesson teacher dept … students 2020-07-01 17 1010 12345 1 10 … … … … … … 29