我用StarRocks已经三年了。

三年前,我们团队在选型OLAP引擎,对比了ClickHouse、Doris、Druid等,最后选择了StarRocks。从最开始的测试验证,到后来的生产环境大规模使用,踩了很多坑,也总结了很多经验。

本文分享这三年使用StarRocks的心得体会,包括选型、建模、性能优化、运维、踩坑记录,以及一些只有用久了才明白的道理。

一、为什么选StarRocks

先说说我们为什么选StarRocks。

1. 当时的选型背景

三年前,我们的业务快速发展,数据量越来越大,原来的MySQL查询越来越慢。我们需要一个OLAP引擎,支持大数据量下的快速分析。

当时的候选方案:

  • ClickHouse:查询快,但不支持高并发,Join能力弱
  • Apache Doris:MPP架构,支持Join,但社区活跃度一般
  • Druid:时序查询快,但不支持Join,灵活性差
  • StarRocks:MPP架构,支持Join,查询快,社区活跃

经过测试,StarRocks在我们的场景下表现最好:查询速度快,支持高并发,Join能力强,而且兼容MySQL协议,迁移成本低。

2. StarRocks的特点

StarRocks的核心特点:

  • MPP架构:分布式并行计算,查询快
  • 向量化执行:CPU利用率高
  • CBO优化器:智能选择执行计划
  • 实时更新:支持主键模型,秒级更新
  • 兼容MySQL协议:用MySQL客户端就能连接
  • 丰富的数据模型:明细模型、聚合模型、更新模型、主键模型
  • 弹性扩展:可以在线扩缩容

这些特点,让StarRocks既能做离线分析,也能做实时分析。

二、数据建模的经验

用了三年,我觉得数据建模是StarRocks最关键的部分。模型建好了,性能自然好;模型建不好,再怎么优化也没用。

1. 选择合适的数据模型

StarRocks有四种数据模型:

  • 明细模型(Duplicate Key):保留明细数据,适合日志、流水等场景
  • 聚合模型(Aggregate Key):按维度聚合,适合报表、统计等场景
  • 更新模型(Unique Key):按主键更新,适合需要更新的场景
  • 主键模型(Primary Key):更新模型的升级版,性能更好,推荐使用

选型建议:

  • 不需要更新,只追加:用明细模型
  • 需要预聚合,提升查询性能:用聚合模型
  • 需要更新,且更新频繁:用主键模型
  • 老版本不支持主键模型:用更新模型

2. 分区分桶的设计

分区和分桶,直接影响查询性能。

分区:

  • 按时间分区:最常用,如按天、按月分区
  • 按枚举值分区:如按地区、业务线分区
  • 分区数不要太多,一般几十到几百个
  • 分区裁剪要能生效,查询条件要带分区字段

分桶:

  • 分桶列选择高基数的列,如用户ID、订单ID
  • 分桶数根据数据量和集群规模设置
  • 一般每个分桶的数据量在1-10GB之间
  • 分桶数最好是BE节点数的整数倍

常见错误:

  • 分区太多,元数据压力大
  • 分桶太少,数据倾斜
  • 分桶列基数太低,数据分布不均
  • 查询不带分区字段,全表扫描

3. 字段类型的选择

字段类型的选择,也会影响性能和存储。

  • 能用小类型就不用大类型:如能用TINYINT就不用INT
  • 字符串类型用VARCHAR,不要用STRING(STRING在StarRocks中是VARCHAR的别名)
  • 日期时间用DATETIME,不要用字符串
  • 精确数值用DECIMAL,不要用DOUBLE(会有精度问题)
  • 低基数字符串可以用字符串字典编码(低基数优化)

4. 宽表还是星型模型

StarRocks支持Join,所以可以用星型模型(事实表+维度表)。

但在实际使用中,我们发现:

  • 简单查询,星型模型够用
  • 复杂查询,多表Join性能不如宽表
  • 高并发场景,宽表性能更稳定

所以,我们的做法是:

  • 明细层用星型模型,保持灵活性
  • 应用层用宽表,提升查询性能
  • 通过ETL把星型模型加工成宽表

三、性能优化的经验

性能优化,是用StarRocks的日常。

1. 查询优化

查询优化的几个关键点:

  • 分区裁剪:查询条件一定要带分区字段,避免全表扫描
  • 谓词下推:尽量把过滤条件下推到存储层
  • 选择合适的Join策略:StarRocks支持Broadcast Join、Shuffle Join、Colocate Join,小表用Broadcast,大表用Shuffle,同分布用Colocate
  • 避免SELECT *:只查需要的列,减少IO
  • 合理使用子查询:子查询不要嵌套太深
  • 用EXPLAIN看执行计划:慢查询一定要看执行计划,找到瓶颈

2. Colocate Join

Colocate Join是StarRocks的一个重要特性,能大幅提升Join性能。

原理:把相关的表按相同的分桶列分桶,Join时数据在同一个节点,不需要数据shuffle。

使用方法:

  • 相关表的分桶列相同
  • 分桶数相同
  • 建表时加上"colocatewith" = "groupname"

效果:Join性能提升3-5倍。

3. 物化视图

物化视图,是预计算的一种方式,能大幅提升查询性能。

适用场景:

  • 固定的报表查询
  • 常用的聚合查询
  • 多表Join的查询

注意事项:

  • 物化视图会占用存储空间
  • 数据更新时,物化视图也要更新,有写入开销
  • 不要建太多物化视图,维护成本高

4. 索引优化

StarRocks支持前缀索引和Bitmap索引。

  • 前缀索引:默认就有,按排序键的前36字节建立索引。排序键要选择常用的过滤字段
  • Bitmap索引:适合低基数列(如性别、状态),加速过滤查询
  • Bloom Filter索引:适合高基数列,加速等值查询

合理使用索引,能大幅提升查询性能。

四、实时数据导入的经验

StarRocks支持多种数据导入方式。

1. 导入方式选择

  • Stream Load:HTTP方式导入,适合实时小批量导入
  • Broker Load:通过Broker导入HDFS、S3等存储的数据,适合离线批量导入
  • Routine Load:订阅Kafka,实时导入,适合流式数据
  • Spark Load:通过Spark导入,适合大数据量离线导入
  • INSERT INTO:SQL方式导入,适合测试和小数据量

我们的选择:

  • 实时数据:Routine Load订阅Kafka
  • 离线数据:Broker Load从HDFS导入
  • 小批量实时:Stream Load

2. 导入性能优化

导入性能优化的几个点:

  • 批量导入:不要一条条导入,要批量导入,每批几百到几千条
  • 合理设置并发:导入并发不要太高,避免压垮集群
  • 合并小文件:导入前合并小文件,减少导入任务数
  • 主键模型的更新:主键模型更新性能好,但要注意内存占用
  • 监控导入状态:及时发现失败的导入任务

3. 导入的常见问题

  • 数据倾斜:分桶列选择不当,导致某些分桶数据过多
  • 导入失败:数据格式错误、网络问题、集群故障
  • 导入延迟:Kafka消息堆积,导入跟不上
  • 数据重复:导入任务重试导致数据重复(用主键模型或幂等导入解决)

五、运维的经验

运维,是用StarRocks的另一个日常。

1. 集群监控

监控的关键指标:

  • BE节点:CPU、内存、磁盘、网络
  • 查询:QPS、延迟、错误率
  • 导入:导入速率、延迟、失败率
  • 存储:数据量、压缩比、磁盘使用率
  • Compaction:Compaction任务数、积压情况

我们用Prometheus + Grafana监控,设置了告警规则,发现问题及时处理。

2. 扩容缩容

StarRocks支持在线扩缩容。

  • 扩容:增加BE节点,数据会自动均衡。扩容时注意观察数据均衡进度,避免在业务高峰期扩容
  • 缩容:先Decommission节点,等数据迁移完成后再下线。不要直接下线节点,会导致数据不可用

3. 备份恢复

数据备份很重要。

StarRocks支持:

  • 快照备份:对表做快照,备份到HDFS或S3
  • 增量备份:只备份变化的数据
  • 跨集群备份:备份到另一个集群

建议:

  • 定期备份,至少每周一次
  • 重要数据每天备份
  • 定期测试恢复,确保备份可用
  • 备份数据存放在不同的机房,避免单点故障

4. 升级

StarRocks版本更新比较快,升级要注意:

  • 先在测试环境验证
  • 阅读版本更新日志,注意不兼容的变化
  • 滚动升级,先升级FE,再升级BE
  • 升级前做备份
  • 升级后观察一段时间,确认稳定

六、踩过的坑

用了三年,踩了不少坑。

坑一:数据倾斜

这是最常见的坑。

现象:某些查询特别慢,某些BE节点CPU特别高。

原因:分桶列选择不当,数据分布不均。

解决:

  • 选择高基数的分桶列
  • 必要时用多个列作为分桶列
  • 对倾斜的值做特殊处理(如单独分区)

坑二:Compaction积压

现象:查询越来越慢,磁盘IO很高。

原因:数据导入太频繁,产生很多小版本,Compaction跟不上。

解决:

  • 减少导入频率,增大批量
  • 调整Compaction参数,增加Compaction资源
  • 合并小文件
  • 必要时手动触发Compaction

坑三:内存溢出(OOM)

现象:BE节点OOM,进程崩溃。

原因:

  • 查询太复杂,占用内存太多
  • 并发太高,内存不够
  • 数据导入占用太多内存

解决:

  • 优化查询,减少内存占用
  • 限制并发数
  • 增加内存
  • 调整内存参数,设置查询内存上限

坑四:主键模型的内存占用

现象:用了主键模型后,内存占用很高。

原因:主键模型需要在内存中维护主键索引。

解决:

  • 主键尽量短,减少内存占用
  • 合理设置分桶,分散内存压力
  • 数据量特别大时,考虑用更新模型或明细模型
  • 升级到新版本,主键模型的内存优化在不断改进

坑五:小查询延迟高

现象:简单查询也有几百毫秒的延迟。

原因:

  • 集群负载高
  • 连接数太多
  • 元数据压力大

解决:

  • 用连接池,减少连接数
  • 开启查询缓存
  • 优化小查询的执行路径
  • 升级到新版本,小查询性能在不断优化

七、用了三年才明白的道理

最后,说说一些用了三年才明白的道理。

1. 选型比优化重要

很多人觉得,选什么引擎不重要,用好就行。但我的经验是,选型比优化重要。

如果引擎不适合你的场景,再怎么优化也有限。比如,用ClickHouse做复杂多表Join,再怎么优化也不如StarRocks。

所以,选型时一定要充分测试,选择最适合自己场景的引擎。选对了,后面的事情就简单了。

2. 建模比调参重要

很多人一遇到性能问题,就想调参数。但我的经验是,建模比调参重要。

模型建好了,查询自然快;模型建不好,再怎么调参也没用。

所以,遇到性能问题,先看模型:分区对不对、分桶对不对、数据模型选对了没有、有没有做预聚合。模型优化好了,性能自然就上去了。

3. 没有银弹

StarRocks很强,但不是银弹。

它擅长OLAP分析,但不适合:

  • 事务处理(OLTP)
  • 小数据量的简单查询(MySQL更快)
  • 非结构化数据处理
  • 过于复杂的递归查询

不要指望一个引擎解决所有问题。不同的场景,用不同的引擎,组合使用才是正道。

4. 稳定比性能重要

很多人追求极致性能,但我的经验是,稳定比性能重要。

一个查询慢100毫秒,用户可能感觉不到;但集群挂了,数据丢了,那就是大事故。

所以,在生产环境中:

  • 优先保证稳定性
  • 做好监控和告警
  • 做好备份和恢复
  • 不要盲目追新,稳定版本优先

5. 社区很重要

开源产品,社区很重要。

StarRocks的社区很活跃:

  • 版本更新快,bug修复及时
  • 文档完善,教程丰富
  • 社区论坛活跃,问题能得到及时回答
  • 有企业版支持,生产环境有保障

选开源产品,一定要看社区活跃度。社区不活跃的产品,遇到问题没人帮你。

6. 持续学习

技术在不断发展,StarRocks也在不断进步。

用了三年,我感觉StarRocks变化很大:

  • 性能越来越强
  • 功能越来越丰富
  • 稳定性越来越好
  • 生态越来越完善

要持续学习,跟进新版本的特性,不断优化自己的使用方式。

八、写在最后

用了三年StarRocks,从最开始的摸索,到现在的熟练使用,收获很多。

它帮我们解决了大数据量下的快速分析问题,支撑了业务的快速发展。虽然踩了很多坑,但也学到了很多。

2022年了,OLAP引擎的竞争很激烈,ClickHouse、Doris、StarRocks、Druid,各有各的优势。没有最好的引擎,只有最适合的引擎。

如果你在选型OLAP引擎,建议充分测试,根据自己的场景选择。如果你已经在用StarRocks,希望我的经验能帮你少踩一些坑。

最后,用一句话总结:"StarRocks是一款优秀的OLAP引擎,但用好它需要好的建模、持续的优化和稳定的运维。选对引擎,建好模型,做好运维,你就能发挥它的最大价值。"

愿你的数据查询,又快又稳。