AnalyticDB PostgreSQL属于MPP数据库,其中的数据是分布在多个节点上,因此会出现数据倾斜的问题,本文介绍如何发现并解决数据倾斜。

数据倾斜一般会带来查询任务运行慢的问题,同时还会导致OOM或者磁盘满等问题。数据倾斜分为三种:

  • 数据存储倾斜:数据在多个节点上分布不均匀。
  • 数据重分布倾斜:在查询过程中,数据Shuffle后出现的分布不均匀。
  • 窗口函数查询导致分布不均:指内核提供的一些窗口函数的分组字段中所有数据重分布后,出现严重倾斜,造成重分布后的某些节点数据量过大。

如何发现数据倾斜

只有数据存储倾斜是比较容易发现的,可以通过查看数据在各个节点上的分布来查看分布情况。数据重分布倾斜和窗口函数导致的分布不均,都属于运行时倾斜,需要单独的监控收到来发现。下面主要说明数据存储倾斜中的数据库级别的倾斜和数据表级别倾斜如何检查。

  • 数据库级别数据存储倾斜检查方法:
    select gp_execution_dbid(), datname, pg_size_pretty(pg_database_size(datname)) 
    from gp_dist_random('pg_database') order by 2, 1, pg_database_size(datname) desc;
  • 数据表级别数据存储倾斜检查方法:
    select gp_execution_dbid(),datname, pg_size_pretty(pg_total_relation_size('表名'))
    from gp_dist_random('gp_id');

消除数据倾斜

  • 数据存储倾斜

    数据存储倾斜出现的原因一般都是分布键选择不正确导致的。比如,一个表的某个字段的某些值特别多的时候,我们如果选择了这个字段按哈希分布,就会导致这个字段的这些值所在的segment上的数据比其他segment多很多。

    为了解决这个问题,我们一般应该重新选择分布方式。可以将分布键选择为比较均匀的分布键,或者是多列同时作为分布键,也可以采用随机分布策略。

  • 数据重分布倾斜

    数据重分布倾斜主要由两种情况,一种是做group by操作的时候,group by的字段不是分布键,会导致运算时,数据重分布不均匀;另一种是不同表做join操作的时候,join操作导致数据shuffle,出现了数据重分布不均。

    对于group by非分布键导致的数据倾斜问题,内核已经做了相关的优化,会采用多阶段聚合策略来解决问题。具体如下:

    1. 在Segment本地聚合。
    2. 将聚合的结果按照分组字段在Segment上重分布。
    3. 在Segment上聚合重分布后的数据。
    4. 最后将结果返回给Master。

    对于join不同表操作导致的数据倾斜问题,这个可以采用数据存储倾斜的解决方法来解决。尽量将发生join操作的表的关联字段设置为分布键,使其尽量做local join。

  • 窗口函数查询导致分布不均

    目前内核暂未对该倾斜进行优化。