ArgoDB分区分桶选取建议

  1. 表定义
    1. 表定义流程

在ArgoDB的分布式数据管理架构(TDDMS)下,表的数据会以数据分片(tablet)的方式分布在ArgoDB集群的各个节点的数据盘上。数据的分布影响SQL执行过程中的执行效率,因此提前规划合理的表定义可实现:

  1. 表数据均匀分布在各个磁盘上,防止单个磁盘对应的存储设备空间不足造成的集群有效容量下降。选择合适分桶键,可以避免数据分布倾斜;
  2. 表数据扫描压力均匀分散在各个磁盘上,避免某个磁盘的IO消耗压力过大,形成Scan的单节点瓶颈。通过避免把基表上的等值filter中的列作为分布列可以实现;
  3. 减少扫描数据的数据量,通过分区的剪枝机制可以实现;
  4. 尽量减少数据shuffle,减小网络和磁盘IO压力,通过选择join-condition或者group by列为分桶键可以最大程度的实现。
    1. 分区表

分区表是把逻辑上的一张表,根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。分区表和普通表相比具有以下优点:

  1. 改善查询性能

对分区对象的查询可以仅搜索自己关心的分区,提高检索效率。

  1. 增强可用性

如果分区表的某个分区出现故障,表在其他分区的数据仍然可用。

  1. 方便维护

如果分区表的某个分区出现故障,需要修复数据,只修复该分区即可。

      1. 常用分区表

ArgoDB数据库常用的分区表为单值分区表、范围分区表。

单值分区表:将数据基于数值映射到每一个分区,这是由向数值分区表导入数据时生成的。

范围分区表:将数据基于范围映射到每一个分区,这个范围是由创建分区表时指定的分区键决定的。分区键经常采用日期,例如将销售数据按照月份进行分区。

分区

优势

单值分区

把拥有相同分区字段值的记录放在同一目录下,做查询的时候,系统可以直接找到与查询相关的指定目录,然后返回对应记录。同未实现分区的表相比,保证了查询过滤的效果并且提高了效率。

范围分区

扩展了单值分区的功能,使一个 Partition 能够包含某个字段值落在某一范围的所有记录,单值分区可能会因为某一分区字段值的记录数很多而导致数据严重倾斜到某一个分区,而 Range Partition 由于按照范围划分因此能够合并某些记录数少的单值分区,从而一定程度的避免了分区之间数据量差距过大的现象。

      1. 单值分区

单值分区导入数据支持两种:静态插入和动态插入。动态插入的时候必须要设置动态分区插入参数SET hive.exec.dynamic.partition = TRUE;

单值分区注意事项:

  • 单值分区不支持在建表的时候导入数据,创建分区表和导入数据必须分开执行;
  • 分区字段的取名一定要和数据源表的对应列名相同,否则在导入数据时会报错“ Partition spec {...} contains non-partition columns”;
  • 推荐使用STRING字段做分区字段,尽量不要使用其他字段,常见的可以选择时间字段;
  • 常规物理机配置时,一般单个分区的数据量控制在500GB左右;
  • 集群CPU数量比较多时,可以考虑单分区管理500GB~2TB左右的数据,更大的集群建议研发参与设计;
  • 一般不使用多级分区,但多级分区过滤效果非常出色可以考虑使用;
  • 动态分区插入性能较差,且由于入库排序,对磁盘性能要求较高,虚拟机可能出现Fetch Timeout。

单值分区DDL示例:

CREATE TABLE partitioned_table_name( column_name1 DATATYPE1, column_name2 DATATYPE2,

...

) PARTITIONED BY( partition_column_name1 DATATYPE1’, partition_column_name2 DATATYPE2’, ...

);

*其中 partition_column_name1, partition_column_name2, ...分别是分区依据的字段。

      1. 范围分区

范围分区DDL示例:

CREATE TABLE partitioned_table_name ( column_name1 DATATYPE1, column_name2 DATATYPE2,

...

)

PARTITIONED BY RANGE (

partition_column_name1 DATATYPE1’, partition_column_name2 DATATYPE2’, ...

)(

PARTITION [partition_name1] VALUES LESS THAN ( upper_bound_1_1, upper_bound_1_2, ... ), PARTITION [partition_name2] VALUES LESS THAN ( upper_bound_2_1, upper_bound_2_2, ... ),

...

PARTITION [partition_name3] VALUES LESS THAN ( MAXVALUE, MAXVALUE, ... )

);

*其中 partition_column_name1, partition_column_name2, ...分别是分区依据的 字段。

    1. 分桶键

建桶操作实际是将一张表进一步细分为不同个数的Bucket,从0至n-1将这些Bucket编号。分桶后,如果Bucket体积小于Block的最大容量,那么每个Block对应一个桶;否则,一个桶的数据会保存在若干Block中。系统将记录根据指定字段的列值分配至不同Bucket,分配规则如下:对字段值求哈希,这里使用的哈希方法是对n取模,取模的结果表示该记录插入的Bucket的编号。假设有从1到10十个值,分配给三个Bucket,根据各值对10取模的结果,如图所示,为0的给第一个桶,为1的给第二个桶,为3的给第三个桶。

bucket

      1. 什么时候分桶
  1. 分桶查询:直接使用分桶键作为查询条件,可以加速查询
  2. 数据取样:分桶采用hash切片,数据分布均匀;海量数据查询时,可以先查询一个分桶的数据进行数据取样查询

例如在报表展示场景中,往往需要构建主题宽表,查询每月每个消费者(customer_name)的消费总金额。因此可以通过hash bucket可以将customer_name相同的数据放在一个“桶”中。在使用customer_name进行查询时,能够减少扫描范围。

此外,根据经验,我们建议 30GB 以下的小表可以选择不分桶,ORC格式一般就是100~200MB一个桶(压缩后);Holodesk格式的话,对桶文件会进一步细粒度切分管理,因此单个桶可以到1G左右都是没问题的

      1. 选择分桶字段

ArgoDB的表数据分桶键选取至关重要,需要满足以下原则:

  1. 列值应比较离散,以便数据能够均匀分布到各个磁盘。例如,考虑选择表的主键为分桶键,如在人员信息表中选择身份证号码为分桶键;
  2. 在满足第一条原则的情况下尽量不要选取存在常量filter的列。例如,表table_a相关的部分查询中出现table_a的列col_1 存在常量的约束(例如col_1= '000001'),那么就应当尽量不用col_1做分桶键;
  3. 在满足前两条原则的情况,考虑选择查询中的连接条件为分桶键,以便Join任务能够下推到桶上执行,促使执行计划使用bucket join,且减少join过程中shuffle的数据量。

ArgoDB的数据分桶使用 Hash 分布策略,用A、B字段分桶50个,分桶时候是按A拼接B进行哈希计算分桶,推荐就按离散字段来分桶。如果分布列选择不当,可能导致数据倾斜,查询的时候会因此出现部分磁盘的I/O短板,从而影响整体查询性能。

注意事项:

  • 避免使用太长的字段作为分桶字段,会影响分桶判断的性能;
  • 禁止对分桶表使用automerge,因为会削弱或者干涉分桶的优化作用;
  • 分桶字段不建议使用decimal ,分桶个数不建议使用31个。

同时,ArgoDB目前已经支持多列做分桶键,可以更好地满足数据分布的均匀性要求。

      1. 选择分桶个数
        1. 默认分桶

ArgoDB 3.2.2版本及后续版本已支持自动分桶(不指定分桶数的条件下自动分桶),默同认分桶数:大于(集群配置给ArgoDB的磁盘数×5)的最近的一个质数,但这个分桶数一般严重偏大不符合最佳实践,尤其是开发、测试环境较差的CPU内存资源的情况下

备注:5是由参数argodb.default.bucket.ratio的默认值,具体可由用户自行调整。

        1. 手动分桶

手动分桶时,分桶的数量在建表时确定以后就不可更改,以避免因数量更改造成的对数据重新分配的开销。实际上,并没有硬性的标准要求Bucket的数量,用户应该根据实际情况选择,选择原则是选取的分桶数不能产生过多小文件,并且每个分桶建议不小于200M。

        1. 分桶数量

分桶数量建议取质数,小于总的CPU核数的质数:

  • 单表查询的场景,分桶数为小于vCore总数的一个数字(不能是31的倍数);
  • 复杂分析/多表关联场景,分桶数为小于vCore总数÷2的一个数字,相关联的表使用相同的分桶数。

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值