如何排查Trino常见报错问题

news2024/11/15 10:05:16

一、背景

必须前置知识:《Trino权威指南》第12章及周边涉及知识,基于392版本的使用层面入门书,引擎创始人亲自编写:

https://www.wisdominterface.com/wp-content/uploads/2021/07/Trino-Oreilly-Guide.pdfhttps://www.wisdominterface.com/wp-content/uploads/2021/07/Trino-Oreilly-Guide.pdf

或者中文翻译版《Presto实战》第12章及周边,基于330版本。

可选知识:

(1)编译原理基础(SQL语法解析token、生成AST抽象语法树、将AST生成执行计划并优化覆盖的过程,如《ANTLR4权威指南》)、《数据库系统内幕》等计算机专业通用底层课程;

(2)《Presto技术内幕》等深入底层原理的Trino源码级书籍或博客。

(3)《大数据技术体系详解:原理、架构与实践》等大数据平台全貌入门书。

二、查看SQL性能瓶颈的方法

执行如下SQL:

explain analyze 要分析的SQL;

完成之后会生成详细的执行计划,执行计划本身是从底部往上倒着看的,可以全部复制下来到sublime text等文本编辑器后,ctrl+f搜索百分号“%”,来查看具体是什么操作的cpu time、schedule time、block time等百分比占据了整个查询的大部分。例如如下的执行计划,可以看到大部分的开销百分比在于kudu表扫描的调度上,有可能会成为查询任务的瓶颈之一:

同时如果能找到当时问题查询的query id,则可以在Trino原生UI中搜索对应的查询历史记录,注意有的query id搜不到可能是过期或者coordinator重启过了,因为目前社区版的查询历史记录都存在coordinator内存中,过段时间会被刷掉: 

三、常见问题判断与解决方法

具体报错有成百上千种之多,但是其中有一部分是较常见、甚至google报错内容就能搜到解决方法的,下面阐述部分比较常见的问题迹象,和相应的解决方案,将随时间更新。

3.1、数据倾斜导致查询慢

在Trino Query的执行过程中,会遇到时间很长的情况,其中一个可能性就是数据倾斜,判定数据倾斜的标准之一是下图进入具体查询id链接的Overview界面中,展开每个stage的节点信息,可以看到stage26中,某个节点的处理数据量要比其他节点大好几倍,其他节点执行的快也要最终等它执行完才能结束:

数据倾斜往往出现于join或者group by操作distinct在开启mark distinct特性时会优化成group by那样的预聚合)的位置,正如上面结合Query OverviewLive Plan两个界面的提示(ScanFilterProject的算子之后进行预聚合operator),这样观察SQL之后就能发现数据倾斜语句的位置,并根据具体业务场景进行改写。

除了引擎自动进行优化的hash build join(类似Spark的broadcast join)等技术外,SQL层面可以尝试打散会被join on的字段值:

--打散数据(倾斜字段未知)
select id, value, concat(id, (rand() * 10000) % 3) as new_id from A
 
select id, value, concat(id, suffix) as new_id
from ( 
      select id, value, suffix
      from B CROSS JOIN UNNEST(array(0, 1, 2)) tmp as suffix(array(0, 1, 2))
)
 
--打散数据(倾斜字段已知)
select t1.id, t1.id_rand, t2.name
  from (
        select id ,
               case when id = null then concat(‘SkewData_’, cast(rand() as string))
                    else id end as id_rand
          from test1
          where statis_date = ‘20200703’) t1
  left join test2 t2
    on t1.id_rand = t2.id 

可以通过如下SQL判断某个join on或group by字段是否存在倾斜:

select id, count(id) as cnt from table1
where xxxx
group by id
having cnt > 3

3.2、混布架构抢不到CPU导致查询慢

Trino作为全内存计算引擎,对CPU与内存的需求量很大,如果和其他引擎混布在同一个节点上可能会互相影响。它在对多个候选执行计划进行CBO比较哪个更优时,也是对CPU开销的权重(比较开销时的重视程度)占到了75%,内存占10%(因为它量大相对CPU便宜),网络占15%。

如果是混布架构下出现如下迹象,则Trino可能有点抢不到CPU,即查询Overview界面里,某些stage的调度时间远高于CPU时间: 

如果频繁出现这种现象,则可以看具体情况是否切换到存算分离架构,将trino worker等独立出来,避免和其他高耗能组件竞争物理机资源。

3.3、Remote Page is too large

原因是各stage之间进行shuffle exchange时,传输的数据过大超过了默认16M的限制,可能是因为page数据中包含复杂嵌套列,通过Jackson序列化成JSON传输出去的时候容量很大,可以参考如下issue增大config.properties中的参数限制:

Remote page is too large exceptions · Issue #10292 · trinodb/trino · GitHubHi all, We’re running into issues with Remote page is too large exceptions. This is the stack trace in the admin UI: io.trino.operator.PageTooLargeException: Remote page is too large at io.trino.operator.HttpPageBufferClient.rewriteExcep...https://github.com/trinodb/trino/issues/10292

3.4、小文件过多导致查询慢

可以用hadoop fs -ls命令查看一下对应目录下的文件情况,一般HDFS处理32MB以内大小的文件会比较慢,因为它为了海量数据高吞吐性能而牺牲了小文件的读取性能。对于hive表来说默认HDFS路径往往是:/user/hive/warehouse/库名.db/表名/分区名1=值/分区名2=值

这种情况下可以参考部署英特尔开源的SSM服务进行小文件合并:

GitHub - Intel-bigdata/SSM: Smart Storage Management for Big Data, a comprehensive hot/cold data optimized solutionSmart Storage Management for Big Data, a comprehensive hot/cold data optimized solution - GitHub - Intel-bigdata/SSM: Smart Storage Management for Big Data, a comprehensive hot/cold data optimized solutionhttps://github.com/Intel-bigdata/SSM

3.5、某个stage的算子block住其他stage

由于trino的默认处理模式是流式的,某一环节的算子执行的慢,会block住所有其他各stage的算子,分为2种情况:

(1)表扫描太慢block住下游所有算子:在具体查询的Live Plan界面里,看到各底部scan数据的stage没有block,而下游stage被block:

这种时候就要去对应排查具体涉及的存储引擎是否有性能瓶颈,例如小文件等。

(2)下游算子计算慢,反压block回扫描stage:和上面的情况相反,是执行计划树底部TableScan或者ScanFilterProject所在的stage出现block,而下游stage(也就是Live Plan中上方的stage)的block时间远小于Scan Stage的block时间,则可以判断是下游的计算算子处理慢了,需根据具体SQL来改进书写方式。

3.6、Join时右侧表远大于左侧表导致查询慢

Trino自身会根据对应表存储的统计信息(行数、容量、列的最小最大值等)来自动进行一些执行计划优化,但是当统计信息缺失时,Trino并不确定用什么方式最优,只能用默认行为来执行。例如下图中的事件表与历史标签表进行join,本来Trino在提前得知标签表会更大的前提下,可以自动调换join的左右顺序,即reorder join自动优化。

但是由于事件表量级太大,没有提前进行过analyze命令,Trino并不提前知道事件表的statistics,只好采用了对join的左侧即事件表进行probe,右侧的标签表进行hash build(把它以为的“小表”每一行进行哈希值计算,全部加载到内存,广播到各probe侧的worker里,类似spark的broadcast join)的模式,导致标签表容量大、在广播时的开销很高的现象,本来它更大应该处于左边的probe侧。

这种情况下,可以手动改写SQL调换join的顺序,例如ta_event_3 left join history_tag_3改写为history_tag_3 right join ta_event_3,或者对join两边的表执行如下命令之后再join:

analyze 要统计信息的表名

3.7、Could not communicate with the remote task. The node may have crashed or be under too much load. This is probably a transient issue, so please retry your query in a few minutes.

很多时候这个报错主要由2方面的原因导致:

(1)集群CPU负载高或者出现Full GC,导致worker出现几十秒甚至分钟级的不对外进行HTTP响应的情况。

(2)集群网络带宽有瓶颈或质量抖动。

除了分析当时时刻是否有大查询、集群资源是否充足、网卡是否为千兆以外,缓解的方法是设置如下config.properties参数:

exchange.http-client.request-timeout=30s
node-manager.http-client.request-timeout=30s
# 仅限coordinator
memoryManager.http-client.request-timeout=15s

3.8、Column name not specified at position

一般是因为SQL中某些select的列没有写as别名,例如:

create table t1 as select c1, c2, '2023-07-03 17:55:00' from t2

解决的办法是找到没有取别名的列加上as语句,如下所示:

create table t1 as select c1, c2, '2023-07-03 17:55:00' as stamp1 from t2

四、不建议的SQL写法

不建议的写法并不代表完全不能写,只是如果具体业务场景可以避免这种写法就尽量减少,如果具体逻辑无法用其他写法替代,必须使用一些复杂且性能较差的写法时,也是可以的。

4.1、过多的连续join

Trino源码中默认只能对9个以内的连续join进行自动调整join顺序以降低计算开销的优化,且过于庞大的SQL往往会消耗更多的plan时间,所以一般建议SQL中连续的join语句最多不超过9个,最好可以不超过4到5个,尽量每几个连续join拆分成一个临时表或者view后再接着join。

4.2、过多的arbitrary()函数

如下issue提到了arbitrary()函数在内存效率上的问题:

Optimize arbitrary() aggregation · Issue #11187 · prestodb/presto · GitHubI have a use case of removing duplicate rows from a large table by a unique key: SELECT unique_key, ARBITRARY(huge_column) AS huge_column FROM my_table GROUP BY unique_key Presto puts huge_column in memory, while the only thing that need...https://github.com/prestodb/presto/issues/11187

4.3、over()等窗口函数不用partitioned by语句等限定窗口范围

这种情况下,如果还不带上where等过滤条件,就会相当于每一行数据都匹配全表范围的窗口,内存等开销会很大。

4.4、全表cross join/笛卡尔积

如果不加过滤条件,左表的每一行数据都交错匹配右表的每一行数据,执行时间和资源消耗将大大增加。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/714149.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Linux】基础IO——文件描述符/缓冲区/重定向/文件系统

文章目录 一、文件描述符二、缓冲区三、重定向的原理四、文件系统 (Linux Ext2)1 认识磁盘的结构CHSLBABlock 2 认识文件系统2.1 分区2.2 文件系统的结构2.3 剖析inode2.4 文件的操作 3 软硬链接3.1 软链接3.2 硬链接 📝 个人主页 :超人不会飞)&#x1f…

低代码平台的价格范围及购买成本分析

Zoho Creator是一款强大而灵活的低代码应用程序开发平台,可帮助企业快速、高效地创建各种应用程序。但是,很多人可能会担心它的价格问题。在这篇文章中,我们将深入探讨Zoho Creator的定价策略和计划,以帮助您更好地理解其价格结构…

如何保证消息队列的高可用?

RabbitMQ的高可用性 RabbitMQ 是比较有代表性的,因为是基于主从(非分布式)做高可用性的,我们就以 RabbitMQ 为例子讲解第一种 MQ 的高可用性怎么实现。 RabbitMQ 有三种模式:单机模式、普通集群模式、镜像集群模式。…

【裸机开发】I2C 通信接口(一)—— I2C 通信时序协议及通信流程

目录 一、I2C 简介 二、I2C 的整体通信流程 三、主要通信时序和协议 3.1 开始 / 停止条件 3.2 地址传送 3.3 数据传输 3.4 应答条件 3.5 重复开始条件 四、总线仲裁机制(SDA) 1、什么是总线仲裁 2、总线仲裁的过程 五、时钟同步(…

QT学习笔记:TCP客户端的实现

QT一般用来做客户端&#xff0c;我这里就简单讲一下怎么开发基于QT的TCP客户端。 1、用QtCreator创建项目 2、界面 3、.pro文件添加network QT core gui network 4、mainwindow.h #ifndef MAINWINDOW_H #define MAINWINDOW_H#include <QMainWindow> #include &l…

关于Unity动画卡在第一帧的处理方法

今天在制作人物的死亡动画时出现了题目所说的问题&#xff0c;以下是动画的状态机 因为任何状态都可能死亡&#xff0c;所以是从anyState进入的死亡动画 进入条件为isDead是true&#xff0c;当角色死亡时这个条件就会设置成true 结果出现了卡在这个动画的问题 经过检查发现&a…

Java连接数据库——JDBC使用步骤

步骤: 1.注册驱动 ——导入相应平台厂商的驱动jar包(zip为源码) 驱动版本 8&#xff1a;com.mysql.cj.jdbc.Driver 驱动版本 5&#xff1a;com.mysql.jdbc.Driver DriverManger.registerDriver( new Driver() ); 2.创建链接 —— connection Java程序连接数据库要调用方法,方…

网络推广技术和算法不断更新

网络推广技术和算法不断更新&#xff0c;以下是一些关于网络推广技术和算法的讨论。 1. 定向广告投放&#xff1a;定向广告投放是一种网络推广技术&#xff0c;它利用用户数据和行为分析&#xff0c;将广告投放给特定的受众群体。通过分析用户的兴趣、行为、地理位置等信息&am…

Go环境搭建[win10]

下载 https://golang.google.cn/dl/https://golang.google.cn/dl/go1.20.5.windows-amd64.msiGo环境变量配置 系统变量 GOROOT D:\Dev\Env\Go [Go语言安装目录] GOPROXY https://goproxy.io,direct [配置代理] GOPATH D:\Dev\PROJECTS_GO [Go语言工作目录] PATH …

Java Web JavaScript (1)23.7.1

JavaScript 1&#xff0c;JavaScript简介 JavaScript 是一门跨平台、面向对象的脚本语言&#xff0c;而Java语言也是跨平台的、面向对象的语言&#xff0c;只不过Java是编译语言&#xff0c;是需要编译成字节码文件才能运行的&#xff1b;JavaScript是脚本语言&#xff0c;不…

如何自己开发软件测试工具?一篇文章教会你

目录 序言&#xff1a; 一、自动化测试工具浅析 二、如何快速开发一个自动化测试工具 总结&#xff1a; 序言&#xff1a; 一说到自动化测试工具&#xff0c;大家很多人都会想到的是QTP、LR或者selenium之类的工具&#xff0c;要大家一开始设计一个这样的工具&#xff0c;其…

DevOps实现自动化发布实操

DevOps实现自动化发布流程 本篇文章来自 B站视频&#xff08;部分步骤与视频存在差异&#xff09; 流程图及原理 本地编写代码提交至远程仓库Jenkins&#xff08;基于Docker&#xff09;通过内置Git获取提交的代码&#xff0c;通过Maven进行打包&#xff0c;形成可执行文件&a…

数字信号处理实验:IIR数字滤波器设计及软件实现

目录 一、实验目的 二、实验原理 三、实验设备 四、实验内容及步骤 五、实验结果及分析 六、实验主程序框图及程序清单 七、实验总结 一、实验目的 熟悉用双线性变换法设计IIR数字滤波器的原理与方法&#xff1b;学会调用MATLAB信号处理工具箱中滤波器设计函数&#xff…

还在手动下载github项目?想要自动化下载github项目?基于python开发项目自动下载模块帮你实现自动下载存储

GitHub是一个基于Web的代码托管平台和开发者社区。它允许开发者存储、管理和分享他们的代码&#xff0c;并进行版本控制。开发者可以在GitHub上创建仓库来存储项目代码&#xff0c;并使用Git来跟踪和管理代码的变更历史。GitHub提供了一系列协作工具&#xff0c;如问题追踪、Pu…

一波三折|药学博士终获CSC资助赴瑞典隆德大学从事2年博士后研究

我们先为W博士获得美国哈佛大学布列根和妇女医院的邀请函&#xff0c;助其成功获得CSC公派资助&#xff0c;但后被哈佛大学国际中心以可能拒签为由&#xff0c;不予办理DS-2019表格。幸亏我们未雨绸缪先期又申请到瑞典隆德大学的2年博士后邀请函&#xff0c;最终顺利得到CSC改派…

CAS + 自旋 锁底层

多线程安全问题 为什么会出现多线程安全问题? 在多线程并发下, 假设有 A,B 两个线程同时操作 count 0 这个公共变量, 在A线程中count, 在B线程中count, 正常来说结果应该是 count 2, 可是同时在A, B两个线程中拿到 count 0 , 并且都执行count赋值, 结果就变成了 count 1…

【Java可执行命令】(十一)Java 密钥库和证书管理工具keytool:玩转密钥库和证书管理,深入解析keytool工具的应用与技巧~

Java可执行命令之keytool 1️⃣ 概念2️⃣ 优势和缺点3️⃣ 使用3.1 语法格式3.2 生成证书请求&#xff1a;keytool -certreq3.3 导出证书&#xff1a;keytool -exportcert3.4 生成密钥对&#xff1a;keytool -genkeypair3.5 导入证书或证书链&#xff1a;keytool -importcert3…

基于STM32的直流电机调速系统

目录 基于STM32的直流电机调速系统一、原理图二、部分代码三、视频演示 基于STM32的直流电机调速系统 功能&#xff1a; 1.通过LCD屏幕显示实时两个电机的占空比 2.通过按键调整电机1和2的加减速 3.通过L298N驱动两个直流电机完成调速 一、原理图 二、部分代码 #include &qu…

基于Spring Boot + Vue社区管理系统的设计与实现

1、项目介绍 Spring Boot 是一个用于构建 Java 应用程序的开源框架&#xff0c;它使得开发者可以轻松地创建独立的、生产级别的 Spring 应用程序。Vue.js 是一个流行的 JavaScript 框架&#xff0c;用于构建现代化的、响应式的社区管理系统是一个用于管理社区活动、用户信息和…

Vue发布新版本,强制更新代码的方式

public下新建version.json文件定义版本 {"version":"1.1.0" } util下新建updateVersion.js import axios from axios; import { Loading } from element-ui; var t1; var t2; export async function isNewVersion() {var randomNumberMath.random() co…