GaussDB Hash表分布列选择原则及数据倾斜检测

开发 前端
aussDB如果采用分布式部署模式,则可以根据数据量以及用途定义两种不同分布方式的表,分别为复制表(Replication)和哈希(Hash)表。

 [[414220]]

本文转载自微信公众号「数据和云」,作者宋俊卓 。转载本文请联系数据和云公众号。

GaussDB如果采用分布式部署模式,则可以根据数据量以及用途定义两种不同分布方式的表,分别为复制表(Replication)和哈希(Hash)表。

复制表(Replication)是将表中的全量数据在集群的每一个DN实例上保留一份,主要适用于数据量较小的表。这种存储方式的优点是每个DN上都有此表的全量数据,在Join操作中可以避免数据重分布操作,从而减小网络开销。缺点是每个DN都保留了表的完整数据,造成数据的冗余。一般情况下只有较小的维度表才会定义为Replication表。

哈希(Hash)表是将表中某一个或几个字段进行hash运算后,生成对应的hash值,根据DN实例与哈希值的映射关系获得该元组的目标存储位置。对于Hash分布表,在读/写数据时可以利用各个节点的IO资源,大大提升表读/写速度。一般情况下大表定义为Hash表。

Hash分布表的分布列选取至关重要,需要满足以下原则:

(1)列值应比较离散,以便数据能够均匀分布到各个DN。例如,考虑选择表的主键为分布列,如在人员信息表中选择身份证号码为分布列。

(2)在满足第一条原则的情况下尽量不要选取存在常量filter的列。例如,表dwcjk相关的部分查询中出现dwcjk的列zqdh存在常量的约束(例如zqdh=’000001’),那么就应当尽量不用zqdh做分布列。

(3)在满足前两条原则的情况下,考虑选择查询中的连接条件为分布列,以便Join任务能够下推到DN中执行,且减少DN之间的通信数据量。

(4)一般不建议新增一列专门用作分布列,尤其不建议新增一列且用SEQUENCE的值来填充做为分布列,因为SEQUENCE可能会带来性能瓶颈和不必要的维护成本。

对于Hash分布表策略,如果分布列选择不当,可能导致数据倾斜,查询时出现部分DN的I/O短板,从而影响整体查询性能。因此在采用Hash分布表策略之后需对表的数据进行数据倾斜性检查,以确保数据在各个DN上是均匀分布的。

GaussDB中提供了1个视图pgxc_get_table_skewness,可以查询数据库中所有schema下的表在各个DN的分布情况以及倾斜率,虽然可以通过schemaname和tablename查询指定表的倾斜情况,但该视图查询时耗时较长,仅适用于数据量较小的表(10W以下),尤其不建议不增加条件查询所有表的数据倾斜情况。该视图各个字段说明如下:

除此之外,可以使用函数table_skewness()和table_distribution()查询指定表的数据倾斜情况。在使用table_skewness()时,如果不指定具体字段,默认查询当前分布列的数据倾斜程度,则该函数可以用来评估表的其他字段分布倾斜情况。同样,当表的数据量巨大时,这两个函数查询耗时都比较长。因此对于一张数据量较大的表,一般使用如下语句查询其数据倾斜情况:

  1. select xc_node_id, count(1) from tablename group by xc_node_id order by xc_node_id desc

如果需要查询数据库中倾斜的表,除了使用上面提到的视图pgxc_get_table_skewness,还可以通过排查各个DN实例数据存储目录的大小以及数据文件来找出倾斜的表,这也是实际应用中比较常用的方法。

具体方法及步骤如下:

(1)在所有节点上执行df –h查看各个DN数据目录使用率是否有接近,找到使用率明显较大的磁盘目录。

(2)通过 cm_ctl query –Cvd 确认该磁盘节点对应的DN实例(如上一步检查为slave磁盘占用率过大,则需要查看与该备实例对应的主实例磁盘使用情况),确认DN实例端口号。可通过以下方式查询DN实例端口号:

  1. select * from pgxc_node; 
  2. 或者 
  3. cat DN实例数据目录/postgresql.conf |grep Port 

(3)进入实例base目录,执行du -ak | sort -nr | more查找文件大小为1GB,且文件前缀数字ID相同的文件,查找相同文件数量最多的文件,记录其ID值及其所在文件目录ID值。

(4)通过gsql连接DN实例,并通过文件目录ID确认表所属数据库。

  1. select oid,* from pg_database where oid='1642599'

(5)切换至该数据库,通过文件的ID确认表名称,执行如下SQL:

  1. select relname from pg_class where relfilenode = 3308672; 

(6)根据表名称进一步确认该表所属schema,执行如下SQL:

  1. SELECT n.nspname as "Schema"
  2. c.relname as "Name" 
  3. FROM pg_catalog.pg_class c 
  4. LEFT JOIN pg_catalog.pg_namespace n  
  5. ON n.oid = c.relnamespace 
  6. WHERE relname = 'insured'

(7)通过gsql连接CN实例,最后再通过table_skewness()函数进行核实确认。

 

责任编辑:武晓燕 来源: 数据和云
相关推荐

2009-03-20 10:02:00

IP电话方案设计

2022-03-21 19:44:30

CitusPostgreSQ执行器

2021-08-04 07:21:31

Hive 数据排查

2019-07-29 15:08:34

RedisHashString

2010-08-18 11:17:29

DB2分区数据库DB2

2019-09-30 08:23:47

Hash表哈希表Java

2010-09-25 15:49:07

SQL修改

2020-11-03 10:16:24

Hive数据倾斜Hive SQL

2010-11-23 13:29:36

MySQL数据列类型

2012-05-04 10:41:38

数据库SQL Server

2012-11-12 11:23:26

路由器

2020-02-22 14:14:24

数据库维护必做

2010-11-11 09:51:46

SQL Server添

2009-10-23 11:21:03

宽带接入技术

2012-09-26 10:42:11

大数据

2011-05-31 17:59:48

C++

2011-04-11 09:23:27

设计目标原则C++

2011-03-21 17:09:38

数据表设计原则
点赞
收藏

51CTO技术栈公众号