本文将介绍分区表的三种管理策略。
分区表(Partitioned Tables)
在 Fluss 中,分区表根据一个或多个分区键(partition keys)来组织数据,为大型数据集的查询性能提升和可管理性提供了一种有效方式。通过分区,系统可以将数据划分为不同的片段,每个片段对应特定的分区键值。
对于分区表,Fluss 支持以下三种分区管理策略:
手动管理分区:用户可以手动创建新分区或删除已有分区。如需了解如何创建或删除分区,请参见管理分区。
自动管理分区:分区会根据建表时配置的自动分区规则自动生成,过期的分区也会被自动清理,确保数据不会无限增长。详见自动分区。
动态创建分区:分区会根据写入表中的数据动态创建。详见动态分区。
这三种策略是正交的,可以在同一张表上共存。
多字段分区表(Multi-Field Partitioned Tables)
分区表(无论是主键表还是日志表),都支持基于多个字段配置分区键。这种方式允许用户通过字段值的组合来划分数据,从而实现更细粒度的数据组织、管理和查询优化。
例如,在一个订单(Order)主键表中,可以将分区键定义为 (date, region)。数据将会存储在与具体组合对应的分区中,如 date=2025-04-05, region=US。在流式查询中,用户可以通过对数据进行过滤(如 region=US)来利用分区裁剪(partition pruning),通过分区下推(partition pushdown)提升读取性能。
分区表的主要优势
提升查询性能:通过限制查询范围到特定分区,系统读取的数据量减少,从而降低了查询执行时间。
数据组织更清晰:分区帮助从逻辑上组织数据,使其更容易管理和查询。
更好的扩展性:将大数据集划分为更小、更易管理的块,提升了系统的可扩展性。
限制条件
分区键的类型必须为 STRING 类型。
对于自动分区表,分区键可以是一个或多个字段。如果表只有一个分区键,则支持自动创建分区和自动过期清理;如果有多个分区键,则仅支持自动过期清理。
如果该表为主键表,分区键必须是主键的一个子集。
自动分区规则只能在创建分区表时配置,不支持在建表后修改自动分区规则。
自动分区
示例
自动分区规则通过表选项进行配置。以下示例展示了如何使用 Flink SQL 创建一个名为 site_access
的表,该表支持自动分区。
CREATE TABLE site_access(
event_day STRING, --分区键
site_id INT, --网站ID
city_code STRING, --城市编号
user_name STRING, --用户名
pv BIGINT, --页面访问次数
PRIMARY KEY(event_day, site_id) NOT ENFORCED
) PARTITIONED BY (event_day) WITH (
'table.auto-partition.enabled' = 'true', --启用自动分区
'table.auto-partition.time-unit' = 'YEAR', --时间粒度为年
'table.auto-partition.num-precreate' = '5', --预创建5个分区
'table.auto-partition.num-retention' = '2', --保留两个历史分区
'table.auto-partition.time-zone' = 'Asia/Shanghai' --时区为上海
);
在此示例中,当自动分区发生时(Fluss 会在后台定期对所有表进行操作),将以 YEAR 为分区粒度预创建四个分区,并保留两个历史分区。时区设置为 Asia/Shanghai。
表参数
参数 | 类型 | 是否必填 | 默认值 | 备注说明 |
table.auto-partition.enabled | Boolean | 否 | false | 是否为表启用自动分区。默认禁用。当自动分区启用时,表的分区将自动创建。 |
table.auto-partition.key | String | 否 | 无 | 此配置定义了在表使用多个分区键时用于自动分区的时间分区键。自动分区利用基于时间的分区键来自动处理分区,包括创建新分区和删除过时分区,通过将分区的时间值与当前系统时间进行比较。如果表使用多个分区键(例如复合分区策略),此功能确定哪个键应作为自动分区决策的主要时间维度。如果表只有一个分区键,则无需配置此项。否则,必须指定。 |
table.auto-partition.time-unit | ENUM | 否 | DAY | 自动创建分区的时间粒度。默认值为 'DAY'。有效值为 'HOUR', 'DAY', 'MONTH', 'QUARTER', 'YEAR'。如果值为 'HOUR',自动创建的分区格式为 yyyyMMddHH。如果值为 'DAY',自动创建的分区格式为 yyyyMMdd。如果值为 'MONTH',自动创建的分区格式为 yyyyMM。如果值为 'QUARTER',自动创建的分区格式为 yyyyQ。如果值为 'YEAR',自动创建的分区格式为 yyyy。 |
table.auto-partition.num-precreate | Integer | 否 | 2 | 每次自动分区检查时预创建的分区数量。例如,如果当前检查时间为 2024-11-11 且配置值为 3,则将预创建分区 20241111, 20241112, 20241113。如果任何一个分区已存在,则跳过创建该分区。默认值为 2,表示将预创建 2 个分区。如果 'table.auto-partition.time-unit' 为 'DAY'(默认),则一个预创建分区为今天,另一个为明天。对于具有多个分区键的分区表,不支持预创建,如果未显式指定,则在创建表时会自动设置为 0。 |
table.auto-partition.num-retention | Integer | 否 | 7 | 每次自动分区检查时保留的历史分区数量。例如,如果当前检查时间为 2024-11-11,时间单位为 DAY,且配置值为 3,则将保留历史分区 20241108, 20241109, 20241110。早于 20241108 的分区将被删除。默认值为 7。 |
table.auto-partition.time-zone | String | 否 | 系统时区 | 自动分区的时区,默认与系统时区相同。 |
分区生成规则
自动分区表的时间单位 auto-partition.time-unit
可以取值为 HOUR, DAY, MONTH, QUARTER 或 YEAR。自动分区将使用以下格式创建分区。
时间单位 | 分区格式 | 示例 |
HOUR | yyyyMMddHH | 2024091922 |
DAY | yyyyMMdd | 20240919 |
MONTH | yyyyMM | 202409 |
QUARTER | yyyyQ | 20241 |
YEAR | yyyy | 2024 |
Fluss 集群配置
以下是 Fluss 集群与自动分区相关的配置项。
选项 | 类型 | 默认值 | 描述 |
auto-partition.check.interval | Duration | 10 分钟 | 自动分区检查的间隔时间。默认设置为 10 分钟,意味着每 10 分钟检查一次表分区状态,以查看是否符合自动分区条件。如果不符合条件,将自动创建或删除分区。 |
动态分区
动态分区是客户端默认启用的功能,允许客户端根据写入表的数据自动创建分区。当分区集事先未知时,此功能尤其有价值,无需手动创建分区。在处理多字段分区时,此功能也特别有用,因为自动分区目前仅支持单字段分区创建。
动态创建的分区数量也受 Fluss 集群上配置的 max.partition.num
和 max.bucket.num
限制。
max.partition.num
默认值 1000, 代表每张分区表最多能创建的分区数。max.bucket.num
默认值128000, 代表每张表最多能支持的总 bucket 数(即 分区数 x 分桶数)。
客户端选项
选项 | 类型 | 是否必填 | 默认值 | 描述 |
client.writer.dynamic-create-partition.enabled | Boolean | 否 | true | 是否启用客户端写入器的动态分区创建。启用后,如果分区在数据写入时不存在,将自动创建新分区。 |
动态分区创建示例
步骤一:创建示例表
在左侧导航栏,ds
列为分区键的分区表。
CREATE TABLE IF NOT EXISTS `fluss-demo`.fluss.table_enable_dynamic_partition
(
id BIGINT
,name STRING
,dt STRING
)
PARTITIONED BY (dt)
WITH (
'client.writer.dynamic-create-partition.enabled' = 'true'
)
;
验证表当前的分区
SHOW PARTITIONS `fluss-demo`.fluss.table_enable_dynamic_partition;
查询结果表明表的分区列表为空。
步骤二:动态插入数据
运行下列SQL,向不存在的分区插入数据。
INSERT INTO `fluss-demo`.fluss.table_enable_dynamic_partition values(1, 'hello', '20250701');
步骤三:验证分区被动态创建
再次执行SHOW PARTITIONS
命令验证分区已经被动态创建。