性能改进的关键重点领域 - Amazon EMR
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)

性能改进的关键重点领域

Trino 最大程度地提高了查询并行度和内存优化。此架构具有很高灵活性,能够查询多个不同的数据来源,同时还能高效扩展。Trino 的关键性能改进领域包括下面列出的方面。

内存优化

Trino 中的内存管理对于实现高性能和稳定性至关重要,尤其是在运行大型复杂查询时。Trino 使用分布式内存模型。在此模型中,内存是在 Worker 节点之间分配的,用于处理任务、聚合、联接和其他操作。以下列表介绍了这些设置的集合:

  • query.max-memory – 设置整个集群中单个查询可用的最大内存。这是一个硬性限制;如果查询超出此内存,则会失败。

  • query.max-memory-per-node – 定义查询在每个 Worker 节点上可以消耗的最大内存。设置此项可确保任何单个查询都不会独占任何工作线程上的资源。

  • JVM 堆大小 – 这在 JVM 级别进行配置,它设置每个节点上 Trino 服务器进程的最大堆大小。此值通常应大于 Trino 中与内存相关的配置(这是 query.max-memory-per-nodememory.heap-headroom-per-node 的总和),以避免系统在 JVM 级别耗尽内存。

  • memory.heap-headroom-per-node – 指定 JVM 堆大小中为非查询操作留出的缓冲区内存量。这对于确保内部操作和垃圾回收有足够的开销至关重要。

动态筛选

Trino 中的动态筛选是一种优化技术,它通过减少处理的数据量(尤其是在联接期间)来提高查询性能。它根据联接一侧看到的数据,动态应用筛选条件来限制联接另一侧扫描的数据,这在联接一侧具有高度选择性(这意味着它包含一小部分数据)的查询中特别有用。Amazon EMR 默认启用该功能。以下是查询示例:

SELECT orders.order_id, orders.total_amount FROM orders JOIN customers ON orders.customer_id = customers.customer_id WHERE customers.country = 'France';

如果没有动态筛选,Trino 会扫描联接中的整个订单表,即使只有一小部分客户(来自法国的客户)相关也是如此。这种方法会读取订单表中的所有行,导致 I/O 和处理成本较高。借助动态筛选,Trino 首先扫描较小的客户表,仅检索法国客户的 customer_id 值,然后将此子集作为筛选条件应用于订单。这意味着只会扫描订单中的相关行(customer_id 与筛选后的子集匹配的行),从而大大减少处理的记录数。

溢出到磁盘

在 Trino 中,磁盘溢出允许将中间查询结果卸载到磁盘,从而使内存密集型查询能够完成,即使它们超过了 query_max_memoryquery_max_memory_per_node 设置的内存限制也是如此。默认情况下,Trino 会强制执行这些限制,以确保内存分配保持公平并防止集群死锁。但是,当大型查询超过这些限制时,就会面临终止的风险。磁盘溢出使用 revocable memory 来解决此问题,允许查询借用额外的内存,如果其他地方需要资源,则可以撤销这些内存。当内存被撤销时,中间数据会溢出到磁盘,从而使查询能够继续处理而不会超出内存限制。请注意,强制溢出到磁盘的查询的执行时间可能会更长,因此此功能默认禁用。要在 Amazon EMR 上启用溢出,请使用下面的配置:

  • spill-enabled=true – 当内存使用量超过可用阈值时,启用磁盘溢出。

  • spill-paths – 定义存储溢出数据的目录 spill-paths=/mnt/spill