分布与倾斜
分析型数据库 PostgreSQL 依赖于跨节点的均匀数据分布。
在 MPP 无共享环境中,查询的总体响应时间由所有节点的完成时间来度量,系统只能与最慢的节点一样快。如果数据偏斜,具有更多数据的节点将花费更多时间来完成,因此每个节点必须具有大致相等的行数并执行大致相同的处理量。如果一个节点具有比其他节点更多的处理数据,则可能导致性能不佳和内存不足。
大表做连接操作时,最佳分布至关重要。要执行连接,匹配的行必须位于同一节点上。如果数据未在同一连接列上分发,则其中一个表所需的行将动态重新分发到其他节点。有些情况下,执行广播动作,每个节点将其各个行发送到所有其他节点上,而不是每个节点重新哈希数据并根据哈希值将行发送到适当的节点的重新分配。
本地(Co-located)连接
使用在所有节点上均匀分布表并导致本地连接的哈希分布可以提供显着的性能提升。当连接的行位于同一节点时,可以在节点实例中完成大部分处理。这些连接被称为本地或 Co-located 连接,本地连接能最小化数据移动量,因为每个节点独立于其他节点运营,节点之间没有网络流量或通信。
要做到对经常进行连接的大型表采用本地连接,请在同一列上分布表。本地连接要求连接的两端分布在相同的列上(并且顺序相同),并且在连接表时使用分布子句中的所有列。分发列也必须是相同的数据类型——尽管不同数据类型的某些值可能看起来具有相同的表示,但它们以不同方式存储并且哈希值不同,因此它们存储在不同的节点上。
数据倾斜
数据倾斜可能是由于错误选择分布键或单个元组表插入或复制操作导致的数据分布不均匀。出现在表级别的数据倾斜通常是查询性能不佳和内存不足情况的根本原因。倾斜的数据会影响扫描(读取)性能,它也会影响所有其他查询执行操作,例如:连接和按操作分组。
验证分布以确保数据在初始加载后均匀分布非常重要;在增量加载后继续验证分布同样重要。
以下查询显示每个节点的行数以及最小和最大行数的方差:
SELECT 'Example Table' AS "Table Name",
max(c) AS "Max Seg Rows", min(c) AS "Min Seg Rows",
(max(c)-min(c))*100.0/max(c) AS "Percentage Difference Between Max & Min"
FROM (SELECT count(*) c, gp_segment_id FROM facts GROUP BY 2) AS a;
gp_toolkit schema 里有两个 view 可以供你检查倾斜。
- gp_toolkit.gp_skew_coefficients view 通过计算存储在每个节点上的数据的变异系数(CV)来显示数据分布倾斜。skccoeff 列显示变异系数(CV),计算为标准差除以平均值。它考虑了数据系列平均值附近的平均值和可变性。值越低越好。值越高表示数据倾斜越大。
- gp_toolkit.gp_skew_idle_fractions view 通过计算表扫描期间空闲的系统百分比来显示数据分布倾斜,这是计算倾斜的指示。siffraction 列显示在表扫描期间空闲的系统百分比。这是数据分布不均匀或查询处理倾斜的指标。例如,值 0.1 表示 10%偏斜,值 0.5 表示 50%偏斜,依此类推。倾斜超过 10%的表应评估其分配策略。
注意- 随机分布表
当创建一个随机分布表(DISTRIBUTED RANDOMLY),分析型数据库 PostgreSQL 以轮询方式将您插入或复制的数据分发到表中。分析型数据库 PostgreSQL 为每个插入或复制操作启动轮询周期的新实例。因此,将随机分布的表中的单个元组插入分配给第一个节点,将导致数据偏斜。分析型数据库 PostgreSQL 更均匀地分布来自批量插入的数据。
- 复制表
当您创建复制表(CREATE TABLE 子句 DISTRIBUTED REPLICATED)时,分析型数据库 PostgreSQL 会将每个表行分发到每个节点实例。复制表的数据均匀分布,因为每个节点具有相同的行。使用复制表上的 gp_segment_id 系统列来验证均匀分布的数据的查询将失败,因为分析型数据库 PostgreSQL 不允许查询引用复制表的系统列。
处理倾斜
当不成比例的数据流向一个或几个节点并由其处理时,则要处理倾斜结果。它往往是分析型数据库 PostgreSQL 性能和稳定性问题的罪魁祸首。它可能发生在诸如连接,排序,聚合和各种 OLAP 操作之类的操作中。处理倾斜在执行查询中发生,并且不容易检测数据倾斜。
如果单个节点失败,即不是主机上的所有节点,则可能要处理倾斜问题。识别处理倾斜目前是一个手动过程。如果确定存在倾斜,则找到导致倾斜的查询。以下是要使用的步骤和命令:
-
查看查询分布情况: 使用
gp_toolkit.gp_dist_random
视图查看表数据在分布键上的分布情况。这将显示每个分片(Segment)上数据的分布统计信息,帮助你发现数据倾斜的情况。SELECT * FROM gp_toolkit.gp_dist_random('your_schema.your_table');
-
查找执行计划中的数据倾斜: 使用
EXPLAIN
命令来查看导致倾斜的查询的执行计划。执行计划将显示查询是如何在各个分片上执行的,从而帮助你找到可能导致倾斜的原因。EXPLAIN your_query;
在查询计划中,你可能会注意到有些分片上的任务比其他分片上的任务执行得更慢。这可能表明数据倾斜,即某些分片上的数据量较大,导致查询在这些分片上执行较慢。
-
查看资源分配情况: 使用
pg_stat_activity
视图来查看当前正在执行的查询和它们的资源分配情况,包括 CPU 和内存的使用情况。SELECT * FROM pg_stat_activity;
-
查找高消耗查询: 使用
pg_stat_statements
扩展来查找执行时间较长或资源消耗较高的查询。这可以帮助你找到可能导致数据倾斜的查询。
首先,确保已经加载了pg_stat_statements
扩展:CREATE EXTENSION pg_stat_statements;`
然后,查询
pg_stat_statements
视图:SELECT query, total_time, rows, calls FROM pg_stat_statements ORDER BY total_time DESC;
这将显示查询、总执行时间、返回的行数和调用次数。如果某个查询的执行时间远远超过其他查询,那么它可能是导致数据倾斜的候选者之一。
几乎在所有情况下处理倾斜的解决方法是重写查询。创建临时表可以消除倾斜。临时表可以随机分配以强制进行两阶段聚合。