StarRocks分区分桶注意事项

  1. 如何分区

  • 分区的主要作用是允许用户将整个分区作为管理单位,从而选择存储策略,比如副本数,冷热策略和存储介质等等。大多数情况下,新数据被查询的可能性更大,因此将新数据存储在同一个分区后,用户可以通过StarRocks的分区裁剪功能,最大限度地减少扫描数据量,从而提高查询性能。同时,StarRocks支持在一个集群内使用多种存储介质(SATA/SSD)。用户可以将新数据所在的分区放在SSD上,利用SSD的优秀的随机读写性能来提高查询性能。而通过将旧数据存放在SATA盘上,用户可以节省数据存储的成本。

  • 所以,在实际应用中,用户一般选取时间列作为分区键,具体划分的粒度视数据量而定,单个分区原始数据量建议维持在100GB以内。

  1. 分区列选择
  • 通过合理的分区可以有效的裁剪scan的数据量。我们一般从数据的管理角度来选择分区键,选用 时间 或者区域作为分区键。

  • 使用动态分区可以定期自动创建分区,比如每天创建出新的分区等。

  1. 如何分桶

StarRocks采用Hash算法作为分桶算法,同一分区内, 分桶键的哈希值相同的数据形成(Tablet)子表, 子表多副本冗余存储, 子表副本在物理上由一个单独的本地存储引擎管理, 数据导入和查询最终都下沉到所涉及的子表副本上, 同时子表也是数据均衡和恢复的基本单位。

2.1 分桶列选择

  • 选择高基数的列(例如唯一ID)来作为分桶键,可以保证数据在各个bucket中尽可能均衡。如果数据倾斜情况严重,用户可以使用多个列作为数据的分桶键,但是不建议使用过多列。

  • 分桶的数量影响查询的并行度,最佳实践是计算一下数据存储量,将每个tablet设置成 1GB 左右。

  • 在机器资源不足的情况下,用户如果想充分利用机器资源,可以通过 BE数量 * cpu core / 2的计算方式来设置bucket数量。例如,在将 100GB 未压缩的 CSV 文件导入 StarRocks 时,用户使用 4 台 BE,每台包含 64 核心,仅建立一个分区,通过以上计算方式可得出 bucket 数量为 4 * 64 /2 = 128。此时每个 tablet 的数据为 781MB,能够充分利用CPU资源。

2.2 分桶数如何确定

在StarRocks系统中,分桶是实际物理文件组织的单元。数据在写入磁盘后,就会涉及磁盘文件的管理。

分桶的数据的压缩方式使用的是Lz4。建议压缩后磁盘上每个分桶数据文件大小在 1GB 左右。这种模式在多数情况下足以满足业务需求。

建议用户根据集群规模的变化,建表时调整分桶的数量。集群规模变化,主要指节点数目的变化。假设现有20G原始数据,依照上述标准,可以建10个分桶(压缩前每个 tablet 大小2GB,压缩后可能在 200MB-500MB)。但是如果用户有20台机器,那么可以适当再缩小每个分桶的数据量,加大分桶数。比如分成40个分桶,大概每个 tablet 500MB(保持压缩后一般不小于 100MB)。

2.3 分桶数选择举例

在 ‘采用Range-Hash组合分布的建表语句’ 示例中,site_access 采用 site_id 作为分桶键,其原因在于,针对site_access表的查询请求,基本上都以站点作为查询过滤条件。采用site_id作为分桶键,可以在查询时裁剪掉大量无关分桶。如下案例中的查询,10个bucket中的9个被裁减,因而系统只需要扫描site_access表的1/10的数据。

案例SQL

select
city_code, sum(pv)
from site_access
where site_id = 54321;

但假如site_id分布十分不均匀,大量的访问数据是关于少数网站的(幂律分布, 二八规则),如果用户依然采用上述分桶方式,数据分布会出现严重的倾斜,进而导致系统局部的性能瓶颈。这个时候,用户需要适当调整分桶的字段,以将数据打散,避免性能问题。如下案例中,可以采用site_id、city_code组合作为分桶键,将数据划分得更加均匀。

采用site_id、city_code作为组合分桶键:

CREATE TABLE site_access

(

site_id INT DEFAULT '10',

city_code SMALLINT,

user_name VARCHAR(32) DEFAULT '',

pv BIGINT SUM DEFAULT '0'

)

AGGREGATE KEY(site_id, city_code, user_name )

DISTRIBUTED BY HASH(site_id,city_code) BUCKETS 10;

上面两种模式的选取是建表过程中经常需要面对的问题,采用site_id的分桶方式对于短查询十分有利,能够减少节点之间的数据交换,提供集群整体性能;采用site_id、city_code组合做分桶键的模式对于长查询有利,能够利用分布式集群的整体并发性能,提高吞吐。用户在实际使用中,可以依据自身的业务特点进行相应模式的选择。

  1. 最佳实践

对于StarRocks而言,分区和分桶的选择是非常关键的。在建表时选择好的分区分桶列,可以有效提高集群整体性能。当然,在使用过程中,也需考虑业务情况,根据业务情况进行调整。

以下是针对特殊应用场景下,对分区和分桶选择的一些建议:

  • 数据倾斜 :业务方如果确定数据有很大程度的倾斜,那么建议采用多列组合的方式进行数据分桶,而不是只单独采用倾斜度大的列做分桶。

  • 高并发 :分区和分桶应该尽量覆盖查询语句所带的条件,这样可以有效减少扫描数据,提高并发。

  • 高吞吐 :尽量把数据打散,让集群以更高的并发扫描数据,完成相应计算。

3赞

请问在2.5版本后,分桶的数量还会限制查询性能吗,比如一个tablet 10G和一个tablet 1G,对查询性能会有很大影响吗

建表和插入新分区数据时的自动分桶规则:


根据数据量决定分桶数的建议:
https://doris.apache.org/zh-CN/docs/table-design/data-partition/#bucket-的数量和数据量的建议