改版通知

巨人肩膀网站已全新改版。若您仍依赖旧站功能或数据,欢迎联系我们,我们会协助处理。联系我们

StarRocks高效导入与分区分桶策略解析

ckckck2025年1月10日59 浏览

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_storeolap_table_sink_send_interval_ms 会影响 Broker Load 的速度,但影响有限。
  • BE 服务器 CPU 核数对导入速度有影响,核数越多越快。
  • BE 服务器 CPU 主频对导入速度有影响,主频越高越快。

参数

  • FE 参数
    • load_parallel_instance_num = 32
    • max_broker_concurrency = 400
  • BE 参数
    • flush_thread_num_per_store = 8
    • olap_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