StarRocks高效导入与分区分桶策略解析
StarRocks 导入性能对比分析
StarRocks 提供多种导入方式,包括 Stream Load、Broker Load、Routine Load、Spark Load 和 INSERT,以满足不同业务场景下的数据导入需求。


您可以根据业务场景、数据量、数据源、数据格式和导入频次等选择合适的导入方式。在选择导入方式时,可以注意以下几点:
- 从 Kafka 导入数据:推荐使用 Routine Load 实现导入。如果导入过程中有复杂的多表关联和 ETL 预处理,建议先使用 Apache Flink® 从 Kafka 读取数据并进行处理,然后通过 StarRocks 提供的标准插件
flink-connector-starrocks将处理后的数据导入到 StarRocks 中。 - 从 Hive 导入数据:推荐创建 Hive catalog,然后使用 INSERT 实现导入,或者通过 Broker Load 实现导入。
- 从 MySQL 导入数据:推荐创建 MySQL 外部表,然后使用 INSERT 实现导入,或者通过 DataX 实现导入。如果要导入实时数据,建议参考 从 MySQL 实时同步 实现导入。
- 从 Oracle、PostgreSQL 等数据源导入数据:推荐创建 JDBC 外部表,然后使用 INSERT 实现导入,或者通过 DataX 实现导入。

导入效率
导入效率排序如下:
spark load > broker load > routine load > stream load
Broker Load 与 Stream Load 的比较
结论:
- Broker Load 导入速度比 Stream Load 快。
- BE 的节点数越多,Broker Load 的速度越快。
- 文件格式对 Broker Load 的速度影响不大(此处对比 CSV 与 Parquet)。
- Broker 服务推荐部署在 BE 节点,可以减少网络传输。
- 如果导入的文件较少,Broker 服务的数量对 Broker Load 的速度影响不大,但推荐所有 BE 均部署 Broker。
- FE 参数
load_parallel_instance_num等会影响 Broker Load 的速度,但不宜调整过大,否则会导致冲突严重。 - BE 参数
flush_thread_num_per_store与olap_table_sink_send_interval_ms会影响 Broker Load 的速度,但影响有限。 - BE 服务器 CPU 核数对导入速度有影响,核数越多越快。
- BE 服务器 CPU 主频对导入速度有影响,主频越高越快。
参数:
- FE 参数:
load_parallel_instance_num = 32max_broker_concurrency = 400
- BE 参数:
flush_thread_num_per_store = 8olap_table_sink_send_interval_ms = 0
- BE 数量:3 个
- 导入任务参数:
"load_mem_limit" = "12884901888"(12G)
总结:
为提高 Broker Load 的速度,HDFS 的文件格式均可,设置 FE、BE 相关参数,增加 BE 节点数,Broker 与 BE 混合部署,且 BE 均部署 Broker 服务,提高单个 BE 的配置:CPU 核数、主频。
Spark Load 与 Broker Load 的比较

Spark Load 将导入拆分为计算和存储两部分,将分片、排序、聚合、压缩等计算逻辑放到 Spark 集群,产出结果写到 HDFS,StarRocks 再从 HDFS 中拉取结果文件写到本地盘。
- Broker Load:BE 节点负责计算,算力取决于 BE 节点个数及配置。
- Spark Load:Spark 集群负责计算,算力取决于集群配置,且弹性强。
概括:将导入涉及的聚合排序等计算卸载到 Spark 集群,充分利用 Spark 强大的计算能力。
- StarRocks 导入是一个 CPU 密集型操作。
- Broker Load 在大量数据聚合导入场景下存在性能问题,瓶颈在计算。
- Spark Load 可以很好地将导入涉及的计算任务卸载到 Spark 中,充分发挥各自优势。
- Spark Load 配置较为复杂,门槛高,Spark/Hadoop 环境不同公司差异大,容易踩坑,非大规模数据导入下谨慎使用。
- Spark Load 支持 Hive 和 HDFS 两种数据源,HDFS 作为数据源直接导入问题较多,不建议使用,Hive 作为数据源测试比较充分,可以使用。
分区分桶数量的设计

总结一下:分区是针对表的,是对表的数据取段。分桶是针对每个分区的,会将分区后的每段数据打散为逻辑分片 Tablet。副本数是针对 Tablet 的,是指 Tablet 保存的份数。那么我们不难发现,对某一个数据表,若每个分区的分桶数一致,其总 Tablet 数:
总 Tablet 数 = 分区数 * 分桶数 * 副本数
分桶数 = BE 数量 * BE 节点 CPU 核数 或者 BE 数量 * BE 节点 CPU 核数 / 2
以 table01 为例,我们为其设置了 3 个分区,为每个分区设置了 20 个分桶,又对分桶后的 Tablet 设置了 1 副本,则 table01 的总 Tablet 数 = 3 * 20 * 1 = 60 个。查看 table01 的 Tablet 信息,发现确实共有 60 个 Tablet:
sql
mysql> SHOW TABLET FROM table01;
...
60 rows in set (0.01 sec)
如何分区?
分区的主要作用是允许用户将整个分区作为管理单位,从而选择存储策略,比如副本数、冷热策略和存储介质等。大多数情况下,新数据被查询的可能性更大,因此将新数据存储在同一个分区后,用户可以通过 StarRocks 的分区裁剪功能,最大限度地减少扫描数据量,从而提高查询性能。同时,StarRocks 支持在一个集群内使用多种存储介质(SATA/SSD)。用户可以将新数据所在的分区放在 SSD 上,利用 SSD 的优秀的随机读写性能来提高查询性能。而通过将旧数据存放在 SATA 盘上,用户可以节省数据存储的成本。
在实际应用中,用户一般选取时间列作为分区键,具体划分的粒度视数据量而定,单个分区原始数据量建议维持在 100GB 以内。
- 分区键选择:当前分区键仅支持日期类型和整数类型,为了让分区能够更有效的裁剪数据,我们一般也是选取时间或者区域作为分区键。使用动态分区可以定期自动创建分区,比如每天创建出新的分区等。
- 分区粒度选择:StarRocks 的分区粒度视数据量而定,单个分区原始数据量建议维持在 100GB 以内。
如何分桶?
StarRocks 采用 Hash 算法作为分桶算法,同一分区内,分桶键的哈希值相同的数据形成(Tablet)子表,子表多副本冗余存储,子表副本在物理上由一个单独的本地存储引擎管理,数据导入和查询最终都下沉到所涉及的子表副本上,同时子表也是数据均衡和恢复的基本单位。在聚合模型、更新模型、主键模型下,分桶键必需是排序键中的列。
- 分桶列选择:
- 选择高基数的列(例如唯一 ID)来作为分桶键,可以保证数据在各个 bucket 中尽可能均衡。如果数据倾斜情况严重,用户可以使用多个列作为数据的分桶键,但
end
- 选择高基数的列(例如唯一 ID)来作为分桶键,可以保证数据在各个 bucket 中尽可能均衡。如果数据倾斜情况严重,用户可以使用多个列作为数据的分桶键,但
