【本文经做者受权转载,原则做者 糜利敏,联系方式见文章末尾】html
关于 Apache Doris(Incubating)
Apache Doris(Incubating) 一款基于大规模并行处理技术的交互式SQL分析数据库,由百度于2018年贡献给 Apache 基金会,目前在 Apache 基金会孵化器中。前端
Github: https://github.com/apache/incubator-doris,欢迎你们 Star、提 Issue、Pull Request。mysql
官方网站:http://doris.incubator.apache.org/ 能够查看更多安装、部署、使用文档,也欢迎对文档内容进行校对或建议。git
开发者邮件列表:dev@doris.apache.org,(如何订阅请戳这里)github
背景
做业帮大数据团队主要负责建设公司级数仓,向各个产品线提供面向业务的数据信息,如到课时长、答题状况等,服务于拉新、教学、BI等多个重要业务线。在过去数月内,咱们经过对Doris的应用实践,构建了数仓实时查询系统。本文总结并分享下期间的工做内容,也欢迎你们一块儿讨论。sql
典型的数仓从逻辑上划分为:数据库
大数据团队主要负责到ODS-DWS的建设,从DWS到ADS通常是数仓系统和业务线系统的边界。apache
在过去,因为缺失统一的查询系统,探索了不少模式来支持各个业务线发展。api
- 非流量类
- Kafka 。业务线从kafka接数据本身作数据的聚合计算。主要问题在于彻底没有数仓的概念,业务线在作大量重复的建设
- Spark + ES。每来一个业务需求,就构建一个Spark+ES集群(spark负责计算写入到ES,ES业务层直接使用)。效率低、构建成本高,且ES高效的使用自己自己就须要学习ES的接口以及内部原理,对于业务线很难有这样的精力去作
- ES + 自定义API。大数据将数据写入ES后,并case by case构建api。初步有了数仓的接口,可是接口不具备Sql的能力,只能基于需求case by case的构建,效率过低。
- ……
- 流量类(如pv、uv等)
- 因为数据量大,每每须要预聚合,引入druid
这些“烟囱”式的系统构建方式,致使系统愈来愈难以维护,且业务接入效率也逐步下降。缓存
所以,统一整个查询引擎,对于数仓建设在提升业务支持效率、下降维护成本上都具备很是重大的意义。
整体方案
通过过去数月的探索与实践,咱们确立了以Doris为基础的数仓实时查询系统。同时也对整个数仓的数据计算系统作了一次大的重构,最终总体的架构图以下:
如图所示(从下到上),原始业务层日志经数据摄入系统进入数仓,在数据清洗计算层,咱们将原来的Spark系统升级到了Flink,而且基于Flink-Sql提供了统一数据开发框架,从原有的代码开发升级到Sql开发来极大的提高数据的研发效率。
其后查询系统将Kafka的数据实时同步到查询引擎内,并经过OpenAPI的统一接口对外提供查询服务。
接下来,重点讲下查询系统的工做。
查询引擎选型
实时查询系统的核心在于肯定查询引擎。
社区的查询引擎较多,如Impala、Presto、Doris、ES(xpack),以及云上的ADB等。这块考虑到调研成本、团队技术生态、维护成本等多种因素,咱们最后选择了Doris 做为咱们的查询引擎。
在性能调研时,咱们也走了一些弯路:第一次使用Doris来作查询引擎,发现使用咱们的业务Sql,延迟数据比较大,且CPU使用率很高(IDLE < 10%),
缘由在于使用了AGGREGATE模型,如对于订单数据,通常会将用户支付金额等做为指标列(如一个用户从订单预订到支付,状态的改变会修改支付金额值),可是业务端的Sql中有大量的基于支付金额(指标列)的筛选查询,如统计支付金额 > 某个值的用户数。
Doris对于指标列的筛选成本较高,底层采用了类LSM-Tree的结构,所以为了肯定某一行的数据是否该被筛选,须要扫描全部底层文件内包含该行的数据,进而聚合计算后才能够决策是否结果集包含该行(UNIQ模型相似)。而DUPLICATE表没法更新列。
最终使用Doris on ES,主要考虑点
- 任意列检索。基于ES的倒排索引,我们能够对任意列进行检索(筛选)。这个模型大大下降了业务同窗的学习理解成本,能够和mysql一样方便的构建数据模型。
- ES的易用性以及整个技术生态在公司内相对成熟的多,维护成本较低。如数据修改能够直接覆盖最新值,很是简单。
- Doris on ES在数据Scan上作了大量的优化操做,如列存、local优先、响应内容过滤、顺序扫描、提早终止等,对于数据的扫描性能能够达到~30w/s
- Doris 提供了更强大的Sql语法(如join、多列group by……),且整个查询过程保障了数据的准确度。大大提升了数据使用的效率和数据查询质量。
- 因为ES缺乏分布式计算层,导致ES-Sql须要配置size,否则会导致返回的数据会少于预期的数据
固然,对于流量分析的场景,因为指标列通常是pv、uv等,业务上并无对指标的筛选过滤需求,且Doris自身支持RollUP,所以很是适合流量类的查询分析。
所以,经过Doris咱们统一了整个查询引擎端的实现,这样对于后续整个数仓的进一步建设就打下了很是重要的基础。
应用实践
基于业务场景,咱们对需求进行了分类:面向业务工做台的非流量类需求以及流量分析类需求。
非流量类
在实际的应用中,业务侧的需求主要分两类:
- 明细查询。教研工做台须要关注每一个老师的明细信息,如某课程的学生的到课状况、课前预习状况……
- 聚合查询。部门组织上会关注整个部门、小组内的统计信息,如到课率、拉新率等
这些需求在前端查询,均须要保障低延迟。
而明细查询对于数据的时效性要求更高,所以对于明细类查询,业务侧会直接访问Doris on ES中的数据进行查询,这样基于Doris on ES的任意列检索能力能够保障业务查询模式的灵活性以及数据的时鲜性。
而对于聚合查询,因为不一样指标的Sql计算的数据范围不一样,且业务侧对于聚合的计算没有明细查询的时效性,所以,咱们经过微批(如1min、5mins、10mins……)的调度能力按期计算聚合指标,并存放到ADS层的业务数据库中供前端平台查询。
为了提升数据使用效率,方便业务侧得到特定时间窗口的数据,在数据模型上,咱们统一设置了Meta字段如数据更新时间,这样业务能够用来划分每次更新的数据窗口,作增量计算。
这个模式的主要好处
- 业务端延迟可控、稳定性好。聚合查询的延迟随着具体的Sql不一样而不一样,按期执行后的数据存放到业务层Mysql中,能够最大化能够保证查询延迟
- 数据修复成本低、维护方便。一旦数据有异常,能够自动触发对应的数据窗口进行从新计算
- 原来基于流式计算的修数,须要从源头修复,且必须驱动主流事件触发,成本很是高,而基于doris on es,不一样的事件能够更新不一样的列或者表,只要在数据查询时join便可
- 高性能。通常业务每次读取部分列,这个模式反而能够发挥ES适合大宽表的场景以及Doris on ES列存读取模式的实现,更保障了这快的高性能
流量类
对于流量,在数据清洗后,直接基于kafka入Doris便可,这块主要是利用Doris RollUp的能力,提供低延迟的数据查询能力
OneService
虽然上述能够初步知足业务的需求,可是从站在最终系统可持续运维的目标态来看,还有不少潜在的问题须要提供解决的空间
- 如何保障查询稳定性
- 多个用户Sql查询,某个查询致使集群被打垮,如何快速止损
- 多个场景都在查询某一张表,如何作到可控的降级
- 如何保障入库的数据质量
- 避免数据乱序覆盖……
- 保障数据在多个库之间的无损、低成本迁移……如从Hive迁移到Doris、ES迁移到Mysql……
- 如何提升易用性
- 数仓内支持Sql的系统不少,如Hive的Hql、Flink-Sql……在部分函数语法上会因为差别,如何透明的打平这些差别。而不是让用户不断的学习异构语法
- 数据若是跨云同步,提供多集群数据同步、查询切换,如何对业务透明的完成
- 部分表须要自动Rotate的能力,自动删除过期的数据
- ……
上述的这些问题虽然短时间内没法一一解决,可是须要提供一个能力:未来解决时控制成本,尽可能作到对业务无感知。
这些都须要进一步定义出系统的接口边界,不然耦合各个系统,后续使用的用户越多,问题持续时间越久、迁移成本也越高。
所以咱们设计了OneModel来统一数据模型,而且构建了OpenAPI来统一服务接口。
目前完成的功能包括
- OpenAPI上
- Sql缓存
- 基于业务线的查询条件控制,如query_timeout
- OneModel
- 随着Flink系统的引入,结合原离线数仓的表,数据表在不一样存储上分布愈来愈多如Kafka、Redis、Doris、Hive……,所以构建<数据表,Schema,存储>的元数据,支持数据表在不一样存储上的映射关系,统一表逻辑视图,提高使用效率
- 引入了Json-schema,保证入库质量符合数据模型定义
- 其余
- Rotate Table
- 规范化数据协议,基于数据版本解决数据写入时乱序问题
- ……
基于上述的设计,一方面支持业务功能的同时,更重要的是切分了整个系统的接口,来下降各个系统的耦合。有几点具体的好处:
- 数据清洗系统和查询系统基于Kafka解耦,这样当查询系统临时异常时,不会阻塞计算系统。且多个Topic能够自然支持正常数据流&修数数据流的同步入库。
- 业务层经过统一的接口来进行数据访问,在访问入口处能够统一方便的进行流量调度,统一的解决稳定性问题
- 因为整个系统闭包,且接口基于数据协议耦合,稳定性和易用性获得了兼顾
应用表现
基于Doris on ES的查询系统上线数月,一直到经历了运营大促的活动,均表现出了很是好的稳定性。天天百万级次调用,99分位延迟~秒级
咱们的人效也获得了了数十倍的提高:从过去一个需求“进入查询系统到对外交付数据”须要数人周,提高到当前模式的小时级甚至分钟级。
总结与规划
经过引入doris,解决了咱们明细&聚合数据查询不统一的问题,奠基了整个数据中台在查询侧的基石,对于后续数仓向数据中台发展的路径起到了很是关键的做用。
规划
- 跨集群实时同步。在异地多活等场景下,目前缺乏类似mysql-binlog的实时同步能力,须要构建低成本的数据实时同步能力,支持在线业务的稳定性。
- Doris on ES多表Join性能。在长尾的需求下,Join须要扫描两张表的所有数据进行内存计算,尤为是大表Join大表,延迟就会升高。
- Doris on ES表分区能力。如对于ES的Rotate表,目前Doris没法识别新表或者自动删除老的表映射,须要频繁创建Doris表来对应ES.Index。
- Doris on ES表自动同步能力。如ES表Schema修改后,能够自动同步到Doris。
- Doris平台化运维,如建表、修改表、数据导出……
更多Doris on ES的2020规划,请参见:https://github.com/apache/incubator-doris/issues/3306
致谢
在此很是感谢百度Doris团队特别是@wuyunfeng、@imay 等同窗热情、给力、靠谱的技术支持!!!咱们也但愿后续一块儿参与到Doris的开发建设中来!
欢迎来撩!
在线教育属于当前还在持续高速增加的业务赛道,做业帮做为一家专一于K12的在线教育公司,当前已经累计激活用户8亿+,月活1.7亿+。
做业帮大数据团队致力于面向公司构建数据中台,这里能够接触到大数据下的分布式计算、存储等多种前沿的工程架构技术,欢迎各位感兴趣的小伙伴来撩~
联系邮箱:milimin@zuoyebang.com