【遇见Doris 2019.06.29】Apache Doris 在京东广告平台的应用

80e417affefbb4d7508f4f8e2b2a1d1 需求背景eaed89cb4934f1dba73c02aee204c71

                                     应用场景举例
  • 查询效率与实时性 :京东广告平台有上百张报表,每日百亿级别的聚合结果增量,需要保证查询效率与实时性的统一。
  • 低延迟 :区别于分析师的ad-hoc分析需求,报表场景对于延迟要满足毫秒级别。
  • 高QPS :每日有几千万的查询调用量,日常峰值QPS达到四千以上,SQL on Hadoop的方案难以满足。
  • 方案简单 :既能满足报表查询,又能满足OLAP分析型需求,作为数据的统一出口。

为了解决目前存在的问题,京东急需一套完整的、简单已运维且稳定的报表存储方案。

80e417affefbb4d7508f4f8e2b2a1d1 Why Doris ?eaed89cb4934f1dba73c02aee204c71

目前开源的解决方案主要是SQL on Hadoop 的生态。但是Hadoop方案整体上依赖模块过多,对于业务团队来说,运维成本高。

如果使用公司大数据平台提供的Hadoop环境,难免与其他团队共用,查询效率与稳定性难以保证,对于对查询延迟要控制在毫秒级的报表需求更是无法满足。如果自建Hadoop环境,自己维护,又会出现运维压力太大的问题。比如使用Kylin,就需要维护多个Hadoop生态模块,任何一个模块的不稳定都可能导致报表系统的异常。

所以我们选择了Apache Doris作为我们的报表存储与查询模块,主要考虑到其几个关键优点。

  • 谷歌Mesa理论支持百度工程实践 。并且已经进入Apache基金会孵化,未来可期,并且后续开发维护有保障。

  • 完善的功能支持标准MySQL协议 。因为Apache Doris支持MySQL协议,现存的很多外围MySQL功能模块都可以使用,整体使用都很方便。并且原有的MySQL数据库的用户迁移成本很低。

  • 高并发高QPS支持 。因为核心代码全部使用C++实现,性能方面要优于其他语言。另一方面良好设计也保证Apache Doris在应对高并发时性能要优于其他开源产品。

  • 方便运维架构清晰 。只有FE和BE两个模块,外部依赖少。可以专心维护Doris系统,其他ETL的工作可以交给业务部门处理,解放了人力。

80e417affefbb4d7508f4f8e2b2a1d1 618战绩eaed89cb4934f1dba73c02aee204c71

618大促期间,Doris提供了非常稳定的线上服务。在线进行了稳定的 schema change全程无事故

在导入方面,支撑 100亿行/日 的增量,导入峰值达到 2000w/分钟秒级 导入延迟。

在查询方面,支撑了 4000w+ 的每日查询,TP99仅为 150ms 。大促期间QPS峰值 3000+ ,压测阶段峰值达到 1w+

80e417affefbb4d7508f4f8e2b2a1d1 在京东广告平台的应用123

下图介绍了数据从产生到入库的过程所有的点击流。订单流消息会进入Kafka消息队列,然后经由Spark/Flink的计算,生成一个批次数据,这个批次数据产生的频率由业务端控制。产生数据文件后,向JMQ(京东内部消息队列)中录入一个。任务。后面的Loader模块会根据任务中的批次路径拉取数据,导入Doris中。

JMQ内存储的并不是原始的消息,而是经过Spark/Flink生成的批次文件的路径。同时会有一个自定义的Label标签值,来保证入库任务的不重不丢。因为同一个批次任务使用相同的Label值,而Doris中一个Label值只能被导入一次。而真正业务去重逻辑则放在Spark/Flink这一层,由业务方控制,这样就可以使业务与存储解耦开,同时又可以保证Doris中的增量频率不会太快,保证了查询的性能。

在内部我们使用了三种导入方式,下面分别介绍下使用的场景:

  • Stream Load :主要使用在导入实时数据方面,当前内部数十张表,每张表一分钟一更新。保证了业务数据的准实时。并且因为Stream Load 的同步任务,内存传输数据的特性,Stream Loader不需要拉取数据到本地磁盘,可以实现直接读取hdfs上的增量数据,内存解析,内存导入的功能。

  • Broker Load :主要用在单次更新数据量较大的多维分析型报表和T+1更新的离线表的业务上。目前最大单次更新在30G+,性能稳定良好,一般可在20分钟以内完成入库。

  • KafkaLoad :因为Kafka的原因,以及业务方有重复发送消息的情况。Apache Doris 直接对接Kafka 的 Kafka Load方式无法实现消息去重的功能,所以我们目前并没有将其使用在广告效果报表方面。而我们在一些日志分析的需求上使用Kafka Load。因为日志分析对数据准确性没有要求非常高,那么使用KafkaLoad就可以省去中间的ETL的工作,简化了整体架构。

80e417affefbb4d7508f4f8e2b2a1d1 查询心得eaed89cb4934f1dba73c02aee204c71

  • 设置合理的分区分桶列 :因为Doris会根据分区分桶实现过滤,所以建表时应该谨慎选择分区列和分桶列。能否命中分区分桶列,对查询的影响非常大。

  • 建立合理的Rollup表 :可以说物化rollup的功能是Doris查询效率高的关键因素,因此建立合理的rollup表非常重要。那么实际使用中如何选择rollup呢?一般是将Doris fe的日志导入Doris中,分析慢查询,Scan bytes等指标,找到消耗资源大的查询,针对这些实际的查询建立Rollup表。

  • 设置doris_max_scan_key_num :oris会将可枚举的类型拆分查询,比如id=5 and date>=‘2019-01-01’ and date<='2019-01-31’的查询,doris会将其拆分成31个小查询分别查询[5,2019-01-01]…[5,2019-01-31],但是会有一个阈值(doris_max_scan_key_num),超过这个阈值后不再拆分,可根据业务调整

80e417affefbb4d7508f4f8e2b2a1d1 建议eaed89cb4934f1dba73c02aee204c71

最后京东列举了在使用过程中遇到的几个问题, 在这里欢迎有更多的同学加入我们让Doris变得更好

1、SQL优化器能力偏弱:使用过程中发现Doris的SQL优化器的优化结果并不足够好,这对于大规模的分析型需求是难以接受的。当然,目前Doris已经在开始优化了,相信不久就可以解决这个问题。

2、多机房部署有困难:如果整个机房的服务不可用了,如何容灾。目前Doris是无法感知机房信息的,所以如果单集群的be分布在多机房,势必会对IO压力很大,对查询性能造成影响。如果多机房多集群双写,对业务压力又会非常大。

3、维度表更新困难:这个是所有olap类型数据库的通病,就是为了保证查询的效率,无法大规模的update数据。造成实际业务中一些维度表(比如 hive 的replace)更新困难。对于这种需求可以通过 drop+rename的方式解决,就是每次新建一张临时表,然后导入数据。再将原表删除,将临时表rename成正常的表名来实现replace的功能

4、大规模平台化的能力不足:在我们使用的过程中,出现过个别查询因为查询量大或者触发bug导致整个集群的大量资源被占用,无法回收。目前仅能设置exec_mem_limit参数控制,并且将一些报表型的查询和olap分析型的查询分离部署。

原文链接:https://mp.weixin.qq.com/s/RykptJrnPD0MzmJZe-QqHg