优化慢sql碰到的问题,如何控制一个Fragment的Instance数量

【sr版本】2.3.0正式版
【背景】3fe+20be;
查询的表test_src为聚合模型表,副本数为3,分桶数为20,无分区,数据量39亿左右;
写入的表test_dest为聚合模型表,副本数为3,分区数1300多个,每个分区分桶数20个,数据量39亿左右;
test_src和test_dest分桶键为同一字段forder_id;
经确认,表test_src 60个tablet均匀分布在20个be节点(每个be节点3个tablet),以下是执行show tablet from test_src order by BackendId desc的结果:
show_tablet.txt (27 KB)

【生产场景】
enable_pipeline_engine=true
pipeline_dop=0
parallel_fragment_exec_instance_num=1
执行的sql:
测试sql.sql (18.9 KB)

遇到的问题:
sql耗时30min,查看profile发现集群20个be节点,fragment0只有18个be节点执行,其中有2个be节点处理了两倍于其他节点的数据,耗时30min,而其他节点耗时16min以下,如下图:
image


profile文件如下:
profile1.txt (81.5 KB)
前面背景介绍里已经提到表test_src 60个tablet均匀分布在20个be节点,所以排除了节点数据分布不均的情况。
后面我试着调整session级别的enable_pipeline_engine、pipeline_dop、parallel_fragment_exec_instance_num这三个参数,但不管我如何设置如何组合,fragment0都只有18个be节点执行,耗时都是30min

【测试场景1】
session和global参数:
enable_pipeline_engine=true
pipeline_dop=0
parallel_fragment_exec_instance_num=1
查询的test_src表数据量为10000000,其他和生产场景一致。
执行后的profile中,fragment数量为1,fragment0的BackendNum数量为17
image

【测试场景2】
global参数:
enable_pipeline_engine=true
pipeline_dop=0
parallel_fragment_exec_instance_num=1

session参数:
enable_pipeline_engine=true
pipeline_dop=20
parallel_fragment_exec_instance_num=20
查询的test_src表数据量为10000000,其他和生产场景一致。
执行后的profile中,fragment数量为1,fragment0的BackendNum数量为18
image

【测试场景3】
global参数:
enable_pipeline_engine=true
pipeline_dop=0
parallel_fragment_exec_instance_num=1

session参数:
enable_pipeline_engine=false
pipeline_dop=20
parallel_fragment_exec_instance_num=10
查询的test_src表数据量为10000000,其他和生产场景一致。
执行后的profile中,fragment数量为1,fragment0的BackendNum数量为19
image

【测试场景4】
global参数:
enable_pipeline_engine=true
pipeline_dop=0
parallel_fragment_exec_instance_num=1

session参数:
enable_pipeline_engine=false
pipeline_dop=20
parallel_fragment_exec_instance_num=20
查询的test_src表数据量为10000000,其他和生产场景一致。
执行后的profile中,fragment数量为1,fragment0的BackendNum数量为17
image

【测试场景5】
global参数:
enable_pipeline_engine=true
pipeline_dop=0
parallel_fragment_exec_instance_num=1

session参数:
enable_pipeline_engine=false
pipeline_dop=20
parallel_fragment_exec_instance_num=5
查询的test_src表数据量为10000000,其他和生产场景一致。
执行后的profile中,fragment数量为1,fragment0的BackendNum数量为19
image

【问题】enable_pipeline_engine、pipeline_dop、parallel_fragment_exec_instance_num这三个参数的设置会影响到执行时fragment0的BackendNum数量,但似乎其中没有规律。
请问需要设置什么参数才可以让前面生产环境里的BackendNum数量变为20,从而让各instance处理的数据量均匀,解决节点耗时短板的问题。

image
还有个问题,enable_pipeline_engine、pipeline_dop、parallel_fragment_exec_instance_num这三个参数是不是实际影响的是ScanConcurrency(一个fragment下每个Instance的scanner线程数?)

【生产场景a】
global:
enable_pipeline_engine=true
pipeline_dop=0
parallel_fragment_exec_instance_num=1
session:
enable_pipeline_engine=false
pipeline_dop=0
parallel_fragment_exec_instance_num=40
sql耗时31min,fragment 0 - backendnum:17
image
【生产场景b】
global和session:
enable_pipeline_engine=false
pipeline_dop=0
parallel_fragment_exec_instance_num=40
sql耗时17min,profile中backendnum无显示,fragment 0 - instance数:20


我设置session参数关闭pipeline,并把parallel_fragment_exec_instance_num设为40,sql执行耗时还是30多分钟,backendnum还是不为20。
但我把global参数也改为关闭pipiline,parallel_fragment_exec_instance_num也设为40,sql执行耗时降到了17分钟,backendnum变为20了,难道enable_pipeline_engine修改session参数没用?只能修改全局参数才能生效?

【生产场景c】
global和session参数:


sql耗时16 min 52.03 sec,profile中BackendNum未显示,fragment 0的instance有20个

【生产环境d】
global和session参数:

sql耗时17 min 8.27 sec,profile中BackendNum为17,fragment 0的instance有20个,其中有三个be节点上有2个instance

您好方便发下对应的profile看下么?

从目前测试结果推测,enable_pipeline_engine修改session参数不起效,要修改global参数才生效,global enable_pipeline_engine为true时,无论session enable_pipeline_engine为false还是true,sql执行都是走pipeline自适应调节并行度。global enable_pipeline_engine为true时,pipeline_dop控制并行度,global enable_pipeline_engine为false时,parallel_fragment_exec_instance_num控制并行度。

现在并行度计算的规则是这样的:两级并行,当pipeline_dop=0时就会自适应调节并行度。当pipeline_dop不等于0的时候,并行度=pipeline_dop*parallel_fragment_exec_instance_num

【生产场景a】profile生产场景a.yml (78.4 KB)
【生产场景b】profile生产场景b.yml (88.4 KB)
【生产场景c】profile生产场景c.yml (88.8 KB)
【生产场景d】profile生产场景d.yml (88.5 KB)

请问我这样理解是否正确:enable_pipeline_engine为true时,当pipeline_dop=0时就会自适应调节并行度;当pipeline_dop不等于0的时候,并行度=pipeline_dop*parallel_fragment_exec_instance_num。
enable_pipeline_engine为false时,pipeline_dop不起作用,并行度=parallel_fragment_exec_instance_num。

您好,您的表中数据倾斜很严重,建议重新改下建表语句。

  1. 尽量将表坐下分区
  2. 使用高基数列队表进行分桶。

我查询的表的分桶键用的order_id,是高基数列,前面有贴这张表的tablet分布,建表时分桶数为20,副本数为3,总共60个tablet,20个be节点,每个节点3个tablet,每个tablet 1.9亿多的数据量,没有数据倾斜

image :joy:您的数据倾斜相当严重呢。

这个截图是分析的哪个profile呢,maxTime和minTime profile里没有这两个关键词,这是用的starrocks manager解析profile出来的吗

上面的几个测试中,耗时30min左右的都是数据倾斜导致的,但表本身的数据分布没有倾斜,我建的是聚合模型表,建表时是用的主键order_id作为分桶键的。是并行度导致的倾斜问题,fragment0下有些instance处理的数据量是其他instance的两倍

不过表的分桶数为20,确实小了,如果分桶数调大些,或者按日期分区,sql执行时的并行度造成的倾斜问题应该就没那么大了

请问下咱们是千兆网么?

是万兆网卡(要满8个字才能发帖)

您好,是的(满8字才能发帖~)