Doris性能调优《一》

随着 Apache Doris 在越来越多的企业中得到落地和应用,越来越多用户开始关注如何在海量数据下对Doris的查询性能进行优化。有哪些性能优化的小技巧?如何降低查询耗时?数据模型和分区分桶策略该如何设计?针对慢查询该如何进行分析及优化?

  • 慢查询定位、Profile 解读及SQL优化;
  • 数据模型、索引及分区分桶策略设计;
  • 物化视图及Rollup使用技巧;
  • Doris查询优化器解读;

sql调优

两个基本原则

  • 空间换时间

技术:索引/物化视图/缓存/...

适用场景:固定查询。可提前准备

  • 数据裁剪

技术:谓词下推/Join-Reorder/

适用场景:所有查询,包括Ad-hoc 查询


如何分桶


Doris中有两层的数据划分,第一层是分区(Partition),第二层是分桶(Bucket)。

分区是粗粒度的划分,桶是细粒度的划分,为了让查询发生在更小范围的数据上来提高效率。分桶将整个数据内容安装某列属性值得hash值进行区分,如要安装name属性分为3个桶,就是对name属性值的hash值对3取摸,按照取模结果对数据分桶。如取模结果为0的数据记录存放到一个文件,取模为1的数据存放到一个文件,取模为2的数据存放到一个文件。

  1. 为什么分桶

(1)获得更高的查询处理效率。桶为表加上了额外的结构,Hive在处理有些查询时能利用这个结构。具体而言,连接两个在(包含连接列的)相同列上划分了桶的表,可以使用 Map 端连接 (Map-side join)高效的实现。比如JOIN操作。对于JOIN操作两个表有一个相同的列,如果对这两个表都进行了桶操作。那么将保存相同列值的桶进行JOIN操作就可以,可以大大较少JOIN的数据量。

(2)使取样(sampling)更高效。在处理大规模数据集时,在开发和修改查询的阶段,如果能在数据集的一小部分数据上试运行查询,会带来很多方便。

与分区不同的是,分区依据的不是真实数据表文件中的列,而是我们指定的伪列,但是分桶是依据数据表中真实的列而不是伪列。所以在指定分区依据的列的时候要指定列的类型,因为在数据表文件中不存在这个列,相当于新建一个列。而分桶依据的是表中已经存在的列,这个列的数据类型显然是已知的,所以不需要指定列的类型。


分桶实例



Runtime Filter

Runtime Filter 是在 Doris 0.15 版本中正式加入的新功能。旨在为某些 Join 查询在运行时动态生成过滤条件,来减少扫描的数据量,避免不必要的I/O和网络传输,从而加速查询。

文档地址:Runtime Filter - Apache Doris 中文帮助文档 - 开发文档 - 文江博客

需要理解下为什么要先做一次发布。

Scan节点应该等待多长时间?

--A 收集局部RF的时间

--A合并局部RF的时间

-A将RF发送给多个Scan节点的时间

性能优化问答

Doris 集群 不定期的出现某个 BE 节点直接挂掉的情况,每次挂掉的 BE 节点并不一样。查看监控看机器 Load 比较高(主要是磁盘IO write高)怎么排查这个问题,怎么知道这台机器上在做什么,有什么命令可以知道。

答:BE 挂掉最常见的两种情况:

1. oom 被系统 Kill,通过 dmesg 方式排查,并且结合使用方式确定 导入还是查询导致的内存使用量过大,需要优化使用方式。

2. be core 了,通过 core dump 方式找到 core 栈,core 栈就可以看到是哪部分行为导致的 BE 挂掉。并且在 Issue 里面搜索,看是否是 Doris 旧版本已知问题。每次不一样节点,那就要逐个分析,可能虽然节点不一样但原因都一样。

问: core dump 这个文件存放在哪里的?

答:core dump文件存放地址可以参考链接 https://www.jianshu.com/p/60a5df15093c

问:

1:在做 100-200 个相同 sql 并发测试时,总是越往后面的查询,尤其是做group by的时候,看 profile越慢,好像哪里卡住了似的,这个应该怎么定位是哪里的问题?

2: 通过 Broker Load 导入数据时,总偶然碰到查询超时,而且这个问题是必现,我怎么定位问题,还请给点指点。

答:

1. 这种 qps 性能分析问题,主要工具是 pprof ,看看 CPU 集中耗时在哪里。

2. 导入过程中的查询超时,建议先看监控,grafana 上的数据。比如是否导入占用了过多的 IO或者 cpu 等,导致了相互影响,再逐步根据 pprof + 代码分析。

问: 请教下 Doris 集群规模为 6个 BE节点,在聚合模型下用天 Date做时间分区、每天数据近2亿行,发现 select max(date) 性能不佳(接近10秒),看了下执行计划发现全表扫描了,这样设计的主要考虑是什么呢?

答:确实,如果对 Range 分区字段求 Max 或者 Min 等,逻辑上可以只读最大分区数据。Doris 没对这种特殊场景做优化,所以是全表扫描。需要增加 Where 条件从而匹配到分区分桶裁剪,才能减少数据量。比如这样写 select max(date) from table where date >xxx。分区字段和索引字段需要出现在 Where 条件中效果最好。

问: 请问高吞吐量的即席查询实时性如何,比如1张1亿条数据的表,查出200万条数据,大约需要多少毫秒?

答:这个差异可能会非常大,需要结合建表语句、查询 SQL 、机器配置、集群规模等多方面因素综合来看。在 Doris 官网上基于 Star-Schema-Benchmark 标准测试数据集做过性能测试,可以参考一下 https://doris.apache.org/zh-CN/benchmark/star-schema-benchmark.html#

问: 我们最近在做响应治理:不同维度的查询会对性能有不同的影响,比如 1 亿数据的场景下,数据权限的条件每个人都不一样,很多数据无法提前预聚合,此时 IO 会成为高性能的最大瓶颈,请问 Doris 在这方面有什么比较好的实践?

答:建议使用明细模型 + 物化视图的方式,保留明细的同时,也能有预聚合的数据,而且目前 Doris 的物化视图是可以保证基础表与物化视图表数据的强一致性。

问: 请教一下分桶的优化技巧

答:数据分桶主要是为了分桶裁剪,并且避免数据倾斜。所以首先,最好选用像 id,uuid 这种不容易产生数据倾斜,且分散广的列作为分桶列。同时可以选择查询的 Where 条件列作为分桶列,来更好的减少读取的数据量,提升查询性能。

问: 接口性能优化都有哪些好的方案

答:首先要看你的情况是提升 QPS 还是提升单个慢查询。

先说慢查询:

1. 打开 Profile 观察慢查询主要的性能瓶

2. 梳理 Doris 的常见优化,比如 Join Reorder 、Runtime Filter、谓词下推等等需要手动开启的优化策略,并观察作用。

3. 从数据模型入手,比如是否存在数据版本过多、数据模型和列类型设计不合理等等问题。

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章