文章目录
前言
本文为Flink-StarRocks详解后续章节:主要详解StarRocks分区分桶
由于篇幅过长,后续接着下面进行详解:
StarRocks查询数据湖
实现即席查询案例
2.3 数据分布
建表时,可以通过设置合理的分区和分桶,实现数据均匀分布和查询性能提升。数据均匀分布是指数据按照一定规则划分为子集,并且均衡地分布在不同节点上。查询时能够有效裁剪数据扫描量,最大限度地利用集群的并发性能,从而提升查询性能。
说明
自 2.5.7 版本起,在建表和新增分区时可以不设置分桶数量 (BUCKETS)。StarRocks 默认自动设置分桶数量,如果自动设置分桶数量后性能未能达到预期,并且比较熟悉分桶机制,则也可以手动设置分桶数量。
自 3.1 版本起,在建表和新增分区时可以不设置分桶键(即 DISTRIBUTED BY 子句)。StarRocks 默认使用随机分桶,将数据随机地分布在分区的所有分桶中。
2.3.1 数据分布概览
2.3.1.1 常见的数据分布方式
现代分布式数据库中,常见的数据分布方式有如下几种:Round-Robin、Range、List 和 Hash。如下图所示:
Round-Robin:以轮询的方式把数据逐个放置在相邻节点上。
Range:按区间进行数据分布。如上图所示,区间 [1-3]、[4-6] 分别对应不同的范围 (Range)。
List:直接基于离散的各个取值做数据分布,性别、省份等数据就满足这种离散的特性。每个离散值会映射到一个节点上,多个不同的取值可能也会映射到相同节点上。
Hash:通过哈希函数把数据映射到不同节点上。
为了更灵活地划分数据,除了单独采用上述数据分布方式之一以外,还可以根据具体的业务场景需求组合使用这些数据分布方式。常见的组合方式有 Range+Hash、List+Hash。
2.3.1.2 StarRocks的数据分布方式
StarRocks 支持单独和组合使用数据分布方式。
说明:除了常见的分布方式外, StarRocks 还支持了 Random 分布,可以简化分桶设置。
并且 StarRocks 通过设置分区 + 分桶的方式来实现数据分布。
第一层为分区:在一张表中,可以进行分区,支持的分区方式有表达式分区、Range 分区和 List 分区,或者不分区(即全表只有一个分区)。
第二层为分桶:在一个分区中,必须进行分桶。支持的分桶方式有哈希分桶和随机分桶。
2.3.1.3 分区
分区用于将数据划分成不同的区间。分区的主要作用是将一张表按照分区键拆分成不同的管理单元,针对每一个管理单元选择相应的存储策略,比如分桶数、冷热策略、存储介质、副本数等。StarRocks 支持在一个集群内使用多种存储介质,可以将新数据所在分区放在 SSD 盘上,利用 SSD 优秀的随机读写性能来提高查询性能,将旧数据存放在 SATA 盘上,以节省数据存储的成本。
选择分区列和分区粒度
选择合理的分区列可以有效的裁剪查询数据时扫描的数据量。业务系统中⼀般会选择根据时间进行分区,以优化大量删除过期数据带来的性能问题,同时也方便冷热数据分级存储,此时可以使用时间列作为分区列进行表达式分区或者 Range 分区。此外,如果经常按照枚举值查询数据和管理数据,则可以选择枚举值的列作为分区列进行表达式分区或者 List 分区。
选择分区单位时需要综合考虑数据量、查询特点、数据管理粒度等因素。
示例 1:表单月数据量很小,可以按月分区,相比于按天分区,可以减少元数据数量,从而减少元数据管理和调度的资源消耗。
示例 2:表单月数据量很大,而大部分查询条件精确到天,如果按天分区,可以做有效的分区裁剪,减少查询扫描的数据量。
示例 3:数据要求按天过期,可以按天分区。
2.3.1.4 分桶
一个分区按分桶方式被分成了多个桶 bucket,每个桶的数据称之为一个 tablet。
分桶方式:StarRocks 支持随机分桶(自 v3.1)和哈希分桶。
随机分桶,建表和新增分区时无需设置分桶键。在同一分区内,数据随机分布到不同的分桶中。
哈希分桶,建表和新增分区时需要指定分桶键。在同一分区内,数据按照分桶键划分分桶后,所有分桶键的值相同的行会唯一分配到对应的一个分桶。
分桶数量:默认由 StarRocks 自动设置分桶数量(自 v2.5.7)。同时也支持手动设置分桶数量。
2.3.2 创建分区
按照分区类型可以分为表达式分区、Range分区和List分区。
按照分区创建方式可以分为手动创建分区、批量创建分区和动态分区。
2.3.2.1 表达式分区
自 v3.0 起,StarRocks 支持表达式分区(原称自动创建分区),更加灵活易用,适用于大多数场景,比如按照连续日期范围或者枚举值来查询和管理数据。
仅需要在建表时使用分区表达式(时间函数表达式或列表达式),即可实现导入数据时自动创建分区,不需要预先创建出分区或者配置动态分区属性。
2.3.2.1.1 时间函数表达式分区(自v3.1)
如果经常按照连续日期范围来查询和管理数据,则只需要在时间函数分区表达式中,指定一个日期类型(DATE 或者 DATETIME )的分区列,以及指定分区粒度(年、月、日或小时)。StarRocks 会根据导入的数据和分区表达式,自动创建分区并且设置分区的起止时间。
不过在一些特殊场景下,比如历史数据按月划分分区、最近数据按天划分分区,则需要采用 Range 分区创建分区。
(一)语法
PARTITION BY expression
...
[ PROPERTIES( 'partition_live_number' = 'xxx' ) ]
expression ::=
{ date_trunc ( <time_unit> , <partition_column> ) |
time_slice ( <partition_column> , INTERVAL <N> <time_unit> [ , boundary ] ) }