暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

AUTO模式分区的Hash类型

酷数据库 2023-09-14
187


PolarDB-X的Hash类型分区可细分为Hash分区与Key分区两种类型。Hash分区与Key分区是原生MySQL的标准分区语法之一,PolarDB-X为提供灵活强大的分区管理能力(例如分裂、合并与迁移等)以及考虑支持向量分区键下热点散裂,PolarDB-X不仅在语法上尽量兼容了MySQL的Hash分区与Key分区的建表语法(PolarDB-X仅兼容了语法,分区路由的实现与MySQL并非一致),但是对于Key分区与Hash分区的路由行为重新进行了定义。Key分区与Hash分区使用区别如下表所示:

表 1. Key分区策略与Hash分区策略对比
分区策略分区键支持是否支持分区函数语法示例特点与限制路由描述(点查)
Key(默认的分区策略)单列分区键PARTITION BY KEY(c1)
  • 不支持热点分裂;
  • 最多有1个分区列参与路由计算;
  1. 按c1列的值,使用一致性哈希算法计算其哈希c1_hash;
  2. 按哈希值 c1_hash进行分区路由。
向量分区键PARTITION BY KEY(c1,c2,...,cn)
  • 支持热点分裂;
  • 建表后默认仅第1个分区列c1实际参与路由计算,热点分裂时可以使用c2,...,cn等更多的分区列;
  • 最多允许n个分区列同时参与路由计算;
  • 分区列数目n默认不能超过5个。
  1. (c1,c2,...,cn)这N个列的值组成一组分区键向量,并使用一致性哈希算法为向量的各个列的值计算其哈希值,从而将一个分区键向量映射成一个哈希值向量(c1_hash,c2_hash,...,cn_hash)
  2. 将哈希值向量(c1_hash,c2_hash,...,cn_hash)按range路由并找到目标分区。
Hash单列分区键PARTITION BY HASH(c1)
  • 不支持热点分裂;
  • 一个分区列参与路由。
  • 目前支持11个分区函数:
    • YEAR
    • MONTH
    • DAYOFMONTH
    • DAYOFWEEK
    • DAYOFYEAR
    • TO_DAYS
    • TO_MONTHS
    • TO_WEEKS
    • TO_SECONDS
    • UNIX_TIMESTAMP
    • SUBSTR/SUBSTRING
PARTITION BY HASH(c1)与PARTITION BY KEY(c1)完全等同 ,其路由算法与PARTITION BY KEY(c1)完全一致。
PARTITION BY HASH(YEAR(c1))
  1. 按c1列的值,使用YEAR分区函数计算其对应的年份year;
  2. 将年份year使用一致性哈希算法计算其哈希值year_hash;
  3. 按哈希值year_hash进行分区路由。
向量分区键PARTITIONBY HASH(c1,c2,...,cn)
  • 不支持热点分裂;
  • 建表后,n个分区列将同时与路由;
  • 分区列数目n默认不能超过5个。
  1. (c1,c2,...,cn)这N个分区列的值组成一组向量,并使用一致性哈希算法,计算该向量对应哈希值hashVal;
  2. 按哈希hashVal进行分区路由。

示例1-1:Key分区

Key分区也是PolarDB-X的默认分区方式。 Key分区支持向量分区键。例如,用户想按用户名字name列与用户ID两个列作为分区键进行分区,预建分区数目可以指定为8,可以使用以下的语法建表:


CREATE TABLE key_tbl(
 id bigint not null auto_increment,
 bid int,
 name varchar(30),
 birthday datetime not null,
 primary key(id)
)
PARTITION BY KEY(name, id)
PARTITIONS 8;

根据KEY分区的特点,如上所示向量分区键的分区表,当它进行路由计算时,默认只使用向量分区键的第1个分区列(name)进行路由。因此,业务查询SQL的WHERE条件表达式中,只需要含有第1个分区列的等值条件,即可命中分区裁剪的优化,如下所示:


##(命中分区裁剪,只需扫描一个分区)
SELECT id from key_tbl where name='Jack';

若第1个分区列name存在分布不均衡或者出现数据热点,您也可以通过分区分裂操作(详细请参考表组级分区变更语法(AUTO模式)),并使用下一个分区列(如id)进行分区分裂,从而解决数据不均衡的问题。

如果一个由N个分区列组成的向量分区键,若它实际路由使用到的分区列数目是前K个(1<=K<=N),则查询SQL的WHERE条件表达式只需要包含由这前K个分区列组成的前缀分区裂即可命中分区裁剪。

示例1-2:Hash分区

如果您想使用用户ID作为分区键进行水平分区,可以使用Hash分区进行建表,分区数目可以指定为8,建表语法示例如下:


CREATE TABLE hash_tbl(
 id bigint not null auto_increment,
 bid int,
 name varchar(30),
 birthday datetime not null,
 primary key(id)
)
partition by hash(id)
partitions 8;

Hash分区支持使用分区函数表达式(例如YEAR/TO_DAYS/...等)来将时间类型转换成整数类型。因此,如果您想按用户出生日期birthday列进行分区, 并且预建的Hash分区数目是8, 也可以使用如下语句建表:


CREATE TABLE hash_tbl_todays(
 id bigint not null auto_increment,
 bid int,
 name varchar(30),
 birthday datetime not null,
 primary key(id)
)
PARTITION BY HASH(TO_DAYS(birthday))
PARTITIONS 8;

目前PolarDB-X的分区函数仅支持以下的函数列表:

  • YEAR
  • MONTH
  • DAYOFMONTH
  • DAYOFWEEK
  • DAYOFYEAR
  • TO_DAYS
  • TO_MONTHS
  • TO_WEEKS
  • TO_SECONDS
  • UNIX_TIMESTAMP
  • SUBSTR/SUBSTRING

因此,除SUBSTR/SUBSTRING的分区键类型必须为字符串类型以外,其余分区函数的分区键的类型必须是时间类型(DATE/DATETIME/TIMESTAMP),其它类型不支持使用分区函数。

示例1-3:Hash分区扩展

PolarDB-X对Hash分区的语法进行扩展,让Hash分区支持使用向量分区键 (原生MySQL的标准分区语法,可使用如下语句:


CREATE TABLE hash_tbl2(
 id bigint not null auto_increment,
 bid int,
 name varchar(30),
 birthday datetime not null,
 primary key(id)
)
PARTITION BY HASH(name, birthday)
PARTITIONS 8;

与Key分区不同, Hash分区使用向量分区键,这样的分区表在分区路由计算时,是所有分区列同时参与哈希值计算与路由计算,所以,它会要求查询SQL的WHERE条件表达式必须要含包所有的分区列的等值条件才能命中分区裁剪,如下示例的SQL1可以命中hash_tbl2的分区裁剪,而SQL2则不能命中hash_tbl2的分区裁剪:


##SQL1(命中分区裁剪,只扫描一个分区):
SELECT id from hash_tbl2 where name='Jack' and birthday='1990-11-11';

##SQL2(没命中分区裁剪,全分区扫描):
SELECT id from hash_tbl2 where name='Jack';

Hash分区由于一开始就直接使用所有的分区键进行哈希值计算,所以理论上,它比使用向量分区键的Key分区会打散得更均衡,但它不再支持使用下一个列(因为已经没有列可用)进行热点散列。

相关限制

  • 数据类型限制
    • 整数类型: BIGINT/BIGINT UNSINGED/INT UNSINGED/INT/MEDIUMINT/MEDIUMINT UNSINGED/SMALLINT/SMALLINT UNSINGED/TINYINT/TINYINT UNSINGED;
    • 时间类型:DATETIME/DATE/TIMESTAMP;
    • 字符串类型:CHAR/VARCHAR。
  • 语法限制
    • Hash分区的单列分区键支持使用分区函数,且分区键类型必须为时间类型;
    • Hash分区的向量分区键不允许使用分区函数,不支持热点分列;
    • 默认最大分区数目不允许超过8192个;
    • 默认最大分区列数目不允许超过5个。

数据均匀性

  • Key分区与Hash分区内置的一致性Hash散列算法是经过业界广泛测试的、冲突概率低且性能良好的散列算法 MurmurHash3
  • 基于MurmurHash3的特性,一般情况下,当分区键不同取值的数目N大于3000时,Key分区与Hash分区的数据分布才会相对均衡,且N的值越大,数据分布也将越均衡。
「喜欢这篇文章,您的关注和赞赏是给作者最好的鼓励」
关注作者
【版权声明】本文为墨天轮用户原创内容,转载时必须标注文章的来源(墨天轮),文章链接,文章作者等基本信息,否则作者和墨天轮有权追究责任。如果您发现墨天轮中有涉嫌抄袭或者侵权的内容,欢迎发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论