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

从目前测试结果推测,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字才能发帖~)

我另外建了张tablet为400的聚合模型表,数据量、表结构和之前的test_src一样,sql耗时降到了7m28s。global和session参数如下:


以下是profile:
profile_tablet400.yml (1.4 MB)

我这边做了几个测试,有个点挺困惑的,pipeline_dop好像没用。。
【测试场景1】
参数:
global和session:
enable_pipeline_engine=false
pipeline_dop=2
parallel_fragment_exec_instance_num=5


sql耗时7m42s,Fragment 0下Instance数量100,每个be节点上跑5个Instance,ScanConcurrency为4
profile:
profile-test1.yml (368.7 KB)

【测试场景2】
参数:
global和session:
enable_pipeline_engine=true
pipeline_dop=2
parallel_fragment_exec_instance_num=5


sql耗时7m10s,Fragment 0下Instance数量100,每个be节点上跑5个Instance,ScanConcurrency为4
profile:
profile-test2.yml (368.8 KB)

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


sql耗时6 min 51.37 sec,Fragment 0下Instance数量100,每个be节点上跑5个Instance,ScanConcurrency为4
profile:
profile-test3.yml (368.9 KB)

【测试场景4】
参数:
global和session:
enable_pipeline_engine=true
pipeline_dop=10
parallel_fragment_exec_instance_num=5


sql耗时7 min 34.50 sec,Fragment 0下Instance数量100,每个be节点上跑5个Instance,ScanConcurrency为4
profile:
profile-test4.yml (368.8 KB)

如上所测,pipeline_dop参数值为2时,enable_pipeline_engine为true和false,都对sql执行并发度无影响。enable_pipeline_engine为true时,pipeline_dop参数值为1、2、10,sql的并发度也无变化。

似乎除了enable_pipeline_engine为true,pipeline_dop为0时sql执行会自适应调节并发度,其他情况sql并发度只和parallel_fragment_exec_instance_num参数有关,parallel_fragment_exec_instance_num设为多少,一个fragment下每个be节点就会跑几个instance(不超过表在当前be节点的分桶数),一个fragment下总的instance数就是be节点数*parallel_fragment_exec_instance_num(不超过该表的分桶数)

image
还是有不少的数据倾斜。可以执行下show tablet from table_name;来看下具体tablet的大小来做调整,另外可以使用高基数列来做分桶键。

image
目前来看网络花费的时间约为5min,还有一些优化的空间,但是可能不太大了。再调整下表结构看下吧。

这张表是建的聚合模型表,主键是order_id,分桶键也是用的order_id,算是这张表里最高基数的字段了。

我show tablet看了下,20个be节点,每个节点60(3副本数*20分桶数)个tablet,每个table的大小都是900M左右,在官方文档推荐的100M~1G之间。be节点CPU40核,建表时分桶数20,该表总分桶数为20(be节点数)*20(be节点CPU核数一半)=400,也是用官网分桶数公式计算出来的。以下是show tablet的结果:
show_tablet.txt (268.2 KB)

请问还有其他什么方式可以缓解数据倾斜呢?另外再请教个问题,你截图里的maxTime和minTime是取的OLAP_SCAN_NODE 的active time的最大最小值吗?但是我查了下那4个profile,所有的OLAP_SCAN_NODE的active time都比较平均,都在1~4s浮动,没有找到耗时30s的。

https://blog.csdn.net/ult_me/article/details/123707037?spm=1001.2014.3001.5502
可以参考下流木大佬的博客

那篇文章里的工具,我这边使用报错了:
image

另外,论坛里( StarRocks-Profile分析及优化指南 - StarRocks技术分享 / 经验教程 - StarRocks数据库论坛)这篇文章里的tablet分析工具我这边跑了后没任何输出:
image
image

不知道是不是版本不兼容,我用的starrocks版本是2.3.0