禅与计算机 禅与计算机
首页
  • Java基础

    • 一文搞懂Java核心技术
    • Java面向对象知识点大总结,建议收藏
    • 聊聊Java中的异常
    • 聊聊Java中的常用类String
    • 万字长文带你细聊Java注解本质
    • 来聊聊Java的反射机制
    • 深入解析Java泛型的魅力与机制
    • Java集合框架深度解析与面试指南
    • Java常用集合类HashMap深度解析
    • LinkedHashMap源码到面试题的全解析
    • 深入解析CopyOnWriteArrayList的工作机制
    • Java基础IO总结
    • Java三大IO模型小结
    • Java BIO NIO AIO详解
    • Java进阶NIO之IO多路复用详解
    • Java8流式编程入门
    • 一文速通lambda与函数式编程
    • Java8函数式方法引用最佳实践
    • Java异常:从原理到实践
  • Java并发编程

    • Java并发编程基础小结
    • 深入理解Java中的final关键字
    • 浅谈Java并发安全发布技术
    • 浅谈Java并发编程中断的哲学
    • Java线程池知识点小结
    • 浅谈Java线程池中拒绝策略与流控的艺术
    • synchronized关键字使用指南
    • 深入源码解析synchronized关键字
    • 详解JUC包下的锁
    • 详解并发编程中的CAS原子类
    • LongAdder源码分析
    • AQS源码解析
    • 深入剖析Java并发编程中的死锁问题
    • Java并发容器总结
    • 详解Java并发编程volatile关键字
    • 并发编程ThreadLocal必知必会
    • CompletableFuture基础实践小结
    • CompletableFuture异步多任务最佳实践
    • 硬核详解FutureTask设计与实现
    • 线程池大小设置的底层逻辑与场景化方案
    • 来聊一个有趣的限流器RateLimiter
  • JVM相关

    • 从零开始掌握 JVM
    • JVM核心知识点小结
    • JVM指令集概览:基础与应用
    • JVM类加载器深度解析
    • JVM方法区深度解析
    • Java内存模型JMM详解
    • Java对象大小的精确计算方法
    • 逃逸分析在Java中的应用与优化
    • 从零开始理解JVM的JIT编译机制
    • G1垃圾回收器:原理详解与调优指南
    • JVM故障排查实战指南
    • JVM内存问题排错最佳实践
    • JVM内存溢出排查指南
    • 简明的Arthas使用教程
    • 简明的Arthas配置及基础运维教程
    • 基于Arthas Idea的JVM故障排查与指令生成
    • 基于arthas量化监控诊断java应用方法论与实践
    • 深入剖析arthas技术原理
    • 探索JVM的隐秘角落:元空间详解
  • 深入理解Spring框架

    • Spring 核心知识点全面解析
    • Spring核心功能IOC详解
    • Spring AOP 深度剖析与实践
    • Spring 三级缓存机制深度解析
    • 深入 Spring 源码,剖析设计模式的落地实践
    • 探索 Spring 事务的奥秘
    • 深入解析Spring Bean的生命周期管理
    • 解读 Spring Boot 核心知识点
    • Spring Boot 启动优化实战:1分钟到13秒的排查与优化之路
    • Spring Boot自动装配原理及实践
    • 一文快速上手Sharding-JDBC
    • sharding-jdbc如何实现分页查询
    • 基于DynamicDataSource整合分库分表框架Shardingsphere
  • 计算机组成原理

    • 计算机硬件知识小结
    • CPU核心知识点小结
    • 浅谈CPU流水线的艺术
    • 从Java程序员视角聊聊CPU缓存
    • CPU任务调度和伪共享问题小结
    • CPU MESI缓存一致性协议
    • CPU内存管理机制
    • 内存深度解析
    • 磁盘存储原理
    • 详解计算机启动步骤
    • CPU南北桥架构与发展史
    • CPU中断机制与硬件交互详解
  • 操作系统

    • 如何实现一个高性能服务器
    • Linux文件结构与文件权限
    • Linux常见压缩指令小结
    • Linux核心系统调用详解
    • Linux进程管理
    • Linux线程管理
    • 进程与线程深度解析
    • Linux进程间通信机制
    • 零拷贝技术原理与实践
    • CPU缓存一致性问题深度解析
    • IO任务与CPU调度艺术
  • 计算机网络

    • 网卡通信原理详解
    • 网卡数据包处理指南
    • 基于抓包详解TCP协议
  • 编码最佳实践

    • 浅谈现代软件工程TDD最佳实践
    • 浅谈TDD模式下并发程序设计与实现
    • 面向AI编程新范式Trae后端开发环境搭建与实践
    • 基于Vibe Coding的Redis分页查询实现
    • 告别AI无效对话:资深工程师的提示词设计最佳实践
  • 实用技巧与配置

    • Mac常用快捷键与效率插件指南
    • Keynote技术科普短视频制作全攻略
  • 元认知

    • 摩擦感:AI时代的写作自省
    • 从断墨寻径浅谈程序员的元学习能力
    • AI时代专注力培养
    • 如何阅读一本书:技术书籍的读书笔记方法论
  • 开发工具

    • IDEA配置详解与高效使用指南
    • Windows环境下JDK安装与环境变量配置
    • Windows 10 下的 Maven 安装配置教程
  • Nodejs
  • 博客搭建
  • Redis

    • Redis核心知识小结
    • 解锁Redis发布订阅模式
    • 掌握Redis事务
    • Redis主从复制技术
    • Redis的哨兵模式详解
    • 深度剖析Redisson分布式锁
    • 详解redis单线程设计思路
    • 来聊聊Redis所实现的Reactor模型
    • Redis RDB持久化源码深度解析
    • 来聊聊redis的AOF写入
    • 来聊聊Redis持久化AOF管道通信的设计
    • 来聊聊redis集群数据迁移
    • Redis SDS动态字符串深度解析
    • 高效索引的秘密:redis跳表设计与实现
    • 聊聊redis中的字典设计与实现
  • MySQL

    • MySQL基础知识点小结
    • 解读MySQL 索引基础
    • MySQL 索引进阶指南
    • 解读MySQL Explain关键字
    • 探秘 MySQL 锁:原理与实践
    • 详解MySQL重做日志redolog
    • 详解undoLog在MySQL MVCC中的运用
    • MySQL二进制日志binlog核心知识点
    • MySQL高效插入数据的最佳实践
    • MySQL分页查询优化指南
    • MySQL流式查询的奥秘与应用解析
    • 来聊聊分库分表
    • 来聊聊大厂常用的分布式ID生成方案
  • ElasticSearch

    • Elasticsearch核心原理与架构设计
    • ES 基础使用指南
    • ElasticSearch如何写入一篇文档
    • 深入剖析Elasticsearch文档读取原理
    • 聊聊ElasticSearch性能调优
    • Spring借助Easy-Es操作ES
  • Netty

    • 一文快速了解高性能网络通信框架Netty
    • Netty网络传输简记
    • 来聊聊Netty的ByteBuf
    • 来聊聊Netty消息发送的那些事
    • 解密Netty高性能之谜:NioEventLoop线程池阻塞分析
    • 详解Netty中的责任链Pipeline如何管理ChannelHandler
    • Netty Reactor模型常见知识点小结
    • Netty如何驾驭TCP流式传输?粘包拆包问题全解
    • Netty解码器源码解析
  • 消息队列

    • 一文快速入门消息队列
    • 消息队列RocketMQ入门指南
    • 基于RocketMQ实现分布式事务
    • RocketMQ容器化最佳实践
    • RocketMQ常见问题与深度解析
    • Kafka快速安装与使用指南
  • Nginx

    • Linux下的nginx安装
    • Nginx基础入门总结
    • Nginx核心指令小结
    • Nginx进程结构与核心模块初探
    • Nginx应用进阶HTTP核心模块配置
    • Nginx缓存及HTTPS配置小记
    • nginx高可用实践简记
    • Nginx性能优化
  • 微服务基础

    • 微服务基础知识小结
    • 分布式事务核心概念小结
    • OpenFeign核心知识小结
    • 微服务组件Gateway核心使用小结
    • 分布式事务Seata实践
    • 用 Docker Compose 完成 Seata 的整合部署
  • Nacos

    • Nacos服务注册原理全解析
    • Nacos服务订阅流程全解析
    • Nacos服务变更推送流程全解析
    • 深入解析SpringCloud负载均衡器Loadbalancer
    • Nacos源码环境搭建与调试指南
  • Seata

    • 深度剖析Seata源码
  • Docker部署

    • 一文快速掌握docker的理念和基本使用
    • 使用docker编排容器
    • 基于docker-compose部署微服务基本环境
    • 基于docker容器化部署微服务
    • Gateway全局异常处理及请求响应监控
    • Docker图形化界面工具Portainer最佳实践
  • Go基础

    • 一文带你速通Go语言基础语法
    • 一文快速掌握Go语言切片
    • 来聊聊go语言的hashMap
    • 一文速通go语言类型系统
    • 浅谈Go语言中的面向对象
    • go语言是如何实现协程的
    • 聊聊go语言中的GMP模型
    • 极简的go语言channel入门
    • 聊聊go语言基于epoll的网络并发实现
    • 写给Java开发的Go语言协程实践
  • mini-redis实战

    • 来聊聊我用go手写redis这件事
    • mini-redis如何解析处理客户端请求
    • 实现mini-redis字符串操作
    • 硬核复刻redis底层双向链表核心实现
    • 动手复刻redis之go语言下的字典的设计与落地
    • Go 语言下的 Redis 跳表设计与实现
    • Go 语言版 Redis 有序集合指令复刻探索
    • 基于 Claude Code 复刻 Redis 慢查询指令实践
  • 项目编排

    • Spring脚手架创建简记
    • Spring脚手架集成分页插件
    • Spring脚手架集成校验框架
    • maven父子模块两种搭建方式简记
    • SpringBoot+Vue3前后端快速整合入门
    • 来聊聊Java项目分层规范
  • 场景设计

    • Java实现文件分片上传
    • 基于时间缓存优化浏览器轮询阻塞问题
    • 基于EasyExcel实现高效导出
    • 10亿数据高效插入MySQL最佳方案
    • 从开源框架中学习那些实用的位运算技巧
    • 对账核销场景设计与重构实践
    • 记一次StarRocks源码级排错和既有架构优化实践
  • CI/CD

    • 基于NETAPP实现内网穿透
    • 基于Gitee实现Jenkins自动化部署SpringBoot项目
    • Jenkins离线安装部署教程简记
    • 基于Nexus搭建Maven私服基础入门
    • 基于内网的Jenkins整合gitlab综合方案简记
  • 监控方法论

    • SpringBoot集成Prometheus与Grafana监控
    • Java监控度量Micrometer全解析
    • 从 micrometer计量器角度快速上手promQL
    • 硬核安利一个监控告警开源项目Nightingale
  • Spring AI

    • Spring AI Alibaba深度实战:一文掌握智能体开发全流程
    • Spring AI Alibaba实战:JVM监控诊断Arthas Agent的工程化构建与最佳实践
  • 大模型评测

    • M2.7 真能打!我用两个真实场景测了测,结果有点意外
    • Qoder JetBrains插件评测:祖传代码重构与接口优化实战
  • AI工具链

    • Claude Code 实战指南:从安装配置到企业级开发流程
    • 一次 Claude Code 启动失败的 AI 辅助排查复盘
    • 基于提示词工程与KITE框架的Redis签到功能开发实践
    • Claude Code 记忆管理:CLAUDE.md 最佳实践
    • Claude Code 规则管理:Rules 拆分编排与迭代实践(文末送书)
    • VSCode与Claude Code后端开发环境搭建与AI编程工作流实践
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)

sharkchili

计算机禅修者
首页
  • Java基础

    • 一文搞懂Java核心技术
    • Java面向对象知识点大总结,建议收藏
    • 聊聊Java中的异常
    • 聊聊Java中的常用类String
    • 万字长文带你细聊Java注解本质
    • 来聊聊Java的反射机制
    • 深入解析Java泛型的魅力与机制
    • Java集合框架深度解析与面试指南
    • Java常用集合类HashMap深度解析
    • LinkedHashMap源码到面试题的全解析
    • 深入解析CopyOnWriteArrayList的工作机制
    • Java基础IO总结
    • Java三大IO模型小结
    • Java BIO NIO AIO详解
    • Java进阶NIO之IO多路复用详解
    • Java8流式编程入门
    • 一文速通lambda与函数式编程
    • Java8函数式方法引用最佳实践
    • Java异常:从原理到实践
  • Java并发编程

    • Java并发编程基础小结
    • 深入理解Java中的final关键字
    • 浅谈Java并发安全发布技术
    • 浅谈Java并发编程中断的哲学
    • Java线程池知识点小结
    • 浅谈Java线程池中拒绝策略与流控的艺术
    • synchronized关键字使用指南
    • 深入源码解析synchronized关键字
    • 详解JUC包下的锁
    • 详解并发编程中的CAS原子类
    • LongAdder源码分析
    • AQS源码解析
    • 深入剖析Java并发编程中的死锁问题
    • Java并发容器总结
    • 详解Java并发编程volatile关键字
    • 并发编程ThreadLocal必知必会
    • CompletableFuture基础实践小结
    • CompletableFuture异步多任务最佳实践
    • 硬核详解FutureTask设计与实现
    • 线程池大小设置的底层逻辑与场景化方案
    • 来聊一个有趣的限流器RateLimiter
  • JVM相关

    • 从零开始掌握 JVM
    • JVM核心知识点小结
    • JVM指令集概览:基础与应用
    • JVM类加载器深度解析
    • JVM方法区深度解析
    • Java内存模型JMM详解
    • Java对象大小的精确计算方法
    • 逃逸分析在Java中的应用与优化
    • 从零开始理解JVM的JIT编译机制
    • G1垃圾回收器:原理详解与调优指南
    • JVM故障排查实战指南
    • JVM内存问题排错最佳实践
    • JVM内存溢出排查指南
    • 简明的Arthas使用教程
    • 简明的Arthas配置及基础运维教程
    • 基于Arthas Idea的JVM故障排查与指令生成
    • 基于arthas量化监控诊断java应用方法论与实践
    • 深入剖析arthas技术原理
    • 探索JVM的隐秘角落:元空间详解
  • 深入理解Spring框架

    • Spring 核心知识点全面解析
    • Spring核心功能IOC详解
    • Spring AOP 深度剖析与实践
    • Spring 三级缓存机制深度解析
    • 深入 Spring 源码,剖析设计模式的落地实践
    • 探索 Spring 事务的奥秘
    • 深入解析Spring Bean的生命周期管理
    • 解读 Spring Boot 核心知识点
    • Spring Boot 启动优化实战:1分钟到13秒的排查与优化之路
    • Spring Boot自动装配原理及实践
    • 一文快速上手Sharding-JDBC
    • sharding-jdbc如何实现分页查询
    • 基于DynamicDataSource整合分库分表框架Shardingsphere
  • 计算机组成原理

    • 计算机硬件知识小结
    • CPU核心知识点小结
    • 浅谈CPU流水线的艺术
    • 从Java程序员视角聊聊CPU缓存
    • CPU任务调度和伪共享问题小结
    • CPU MESI缓存一致性协议
    • CPU内存管理机制
    • 内存深度解析
    • 磁盘存储原理
    • 详解计算机启动步骤
    • CPU南北桥架构与发展史
    • CPU中断机制与硬件交互详解
  • 操作系统

    • 如何实现一个高性能服务器
    • Linux文件结构与文件权限
    • Linux常见压缩指令小结
    • Linux核心系统调用详解
    • Linux进程管理
    • Linux线程管理
    • 进程与线程深度解析
    • Linux进程间通信机制
    • 零拷贝技术原理与实践
    • CPU缓存一致性问题深度解析
    • IO任务与CPU调度艺术
  • 计算机网络

    • 网卡通信原理详解
    • 网卡数据包处理指南
    • 基于抓包详解TCP协议
  • 编码最佳实践

    • 浅谈现代软件工程TDD最佳实践
    • 浅谈TDD模式下并发程序设计与实现
    • 面向AI编程新范式Trae后端开发环境搭建与实践
    • 基于Vibe Coding的Redis分页查询实现
    • 告别AI无效对话:资深工程师的提示词设计最佳实践
  • 实用技巧与配置

    • Mac常用快捷键与效率插件指南
    • Keynote技术科普短视频制作全攻略
  • 元认知

    • 摩擦感:AI时代的写作自省
    • 从断墨寻径浅谈程序员的元学习能力
    • AI时代专注力培养
    • 如何阅读一本书:技术书籍的读书笔记方法论
  • 开发工具

    • IDEA配置详解与高效使用指南
    • Windows环境下JDK安装与环境变量配置
    • Windows 10 下的 Maven 安装配置教程
  • Nodejs
  • 博客搭建
  • Redis

    • Redis核心知识小结
    • 解锁Redis发布订阅模式
    • 掌握Redis事务
    • Redis主从复制技术
    • Redis的哨兵模式详解
    • 深度剖析Redisson分布式锁
    • 详解redis单线程设计思路
    • 来聊聊Redis所实现的Reactor模型
    • Redis RDB持久化源码深度解析
    • 来聊聊redis的AOF写入
    • 来聊聊Redis持久化AOF管道通信的设计
    • 来聊聊redis集群数据迁移
    • Redis SDS动态字符串深度解析
    • 高效索引的秘密:redis跳表设计与实现
    • 聊聊redis中的字典设计与实现
  • MySQL

    • MySQL基础知识点小结
    • 解读MySQL 索引基础
    • MySQL 索引进阶指南
    • 解读MySQL Explain关键字
    • 探秘 MySQL 锁:原理与实践
    • 详解MySQL重做日志redolog
    • 详解undoLog在MySQL MVCC中的运用
    • MySQL二进制日志binlog核心知识点
    • MySQL高效插入数据的最佳实践
    • MySQL分页查询优化指南
    • MySQL流式查询的奥秘与应用解析
    • 来聊聊分库分表
    • 来聊聊大厂常用的分布式ID生成方案
  • ElasticSearch

    • Elasticsearch核心原理与架构设计
    • ES 基础使用指南
    • ElasticSearch如何写入一篇文档
    • 深入剖析Elasticsearch文档读取原理
    • 聊聊ElasticSearch性能调优
    • Spring借助Easy-Es操作ES
  • Netty

    • 一文快速了解高性能网络通信框架Netty
    • Netty网络传输简记
    • 来聊聊Netty的ByteBuf
    • 来聊聊Netty消息发送的那些事
    • 解密Netty高性能之谜:NioEventLoop线程池阻塞分析
    • 详解Netty中的责任链Pipeline如何管理ChannelHandler
    • Netty Reactor模型常见知识点小结
    • Netty如何驾驭TCP流式传输?粘包拆包问题全解
    • Netty解码器源码解析
  • 消息队列

    • 一文快速入门消息队列
    • 消息队列RocketMQ入门指南
    • 基于RocketMQ实现分布式事务
    • RocketMQ容器化最佳实践
    • RocketMQ常见问题与深度解析
    • Kafka快速安装与使用指南
  • Nginx

    • Linux下的nginx安装
    • Nginx基础入门总结
    • Nginx核心指令小结
    • Nginx进程结构与核心模块初探
    • Nginx应用进阶HTTP核心模块配置
    • Nginx缓存及HTTPS配置小记
    • nginx高可用实践简记
    • Nginx性能优化
  • 微服务基础

    • 微服务基础知识小结
    • 分布式事务核心概念小结
    • OpenFeign核心知识小结
    • 微服务组件Gateway核心使用小结
    • 分布式事务Seata实践
    • 用 Docker Compose 完成 Seata 的整合部署
  • Nacos

    • Nacos服务注册原理全解析
    • Nacos服务订阅流程全解析
    • Nacos服务变更推送流程全解析
    • 深入解析SpringCloud负载均衡器Loadbalancer
    • Nacos源码环境搭建与调试指南
  • Seata

    • 深度剖析Seata源码
  • Docker部署

    • 一文快速掌握docker的理念和基本使用
    • 使用docker编排容器
    • 基于docker-compose部署微服务基本环境
    • 基于docker容器化部署微服务
    • Gateway全局异常处理及请求响应监控
    • Docker图形化界面工具Portainer最佳实践
  • Go基础

    • 一文带你速通Go语言基础语法
    • 一文快速掌握Go语言切片
    • 来聊聊go语言的hashMap
    • 一文速通go语言类型系统
    • 浅谈Go语言中的面向对象
    • go语言是如何实现协程的
    • 聊聊go语言中的GMP模型
    • 极简的go语言channel入门
    • 聊聊go语言基于epoll的网络并发实现
    • 写给Java开发的Go语言协程实践
  • mini-redis实战

    • 来聊聊我用go手写redis这件事
    • mini-redis如何解析处理客户端请求
    • 实现mini-redis字符串操作
    • 硬核复刻redis底层双向链表核心实现
    • 动手复刻redis之go语言下的字典的设计与落地
    • Go 语言下的 Redis 跳表设计与实现
    • Go 语言版 Redis 有序集合指令复刻探索
    • 基于 Claude Code 复刻 Redis 慢查询指令实践
  • 项目编排

    • Spring脚手架创建简记
    • Spring脚手架集成分页插件
    • Spring脚手架集成校验框架
    • maven父子模块两种搭建方式简记
    • SpringBoot+Vue3前后端快速整合入门
    • 来聊聊Java项目分层规范
  • 场景设计

    • Java实现文件分片上传
    • 基于时间缓存优化浏览器轮询阻塞问题
    • 基于EasyExcel实现高效导出
    • 10亿数据高效插入MySQL最佳方案
    • 从开源框架中学习那些实用的位运算技巧
    • 对账核销场景设计与重构实践
    • 记一次StarRocks源码级排错和既有架构优化实践
  • CI/CD

    • 基于NETAPP实现内网穿透
    • 基于Gitee实现Jenkins自动化部署SpringBoot项目
    • Jenkins离线安装部署教程简记
    • 基于Nexus搭建Maven私服基础入门
    • 基于内网的Jenkins整合gitlab综合方案简记
  • 监控方法论

    • SpringBoot集成Prometheus与Grafana监控
    • Java监控度量Micrometer全解析
    • 从 micrometer计量器角度快速上手promQL
    • 硬核安利一个监控告警开源项目Nightingale
  • Spring AI

    • Spring AI Alibaba深度实战:一文掌握智能体开发全流程
    • Spring AI Alibaba实战:JVM监控诊断Arthas Agent的工程化构建与最佳实践
  • 大模型评测

    • M2.7 真能打!我用两个真实场景测了测,结果有点意外
    • Qoder JetBrains插件评测:祖传代码重构与接口优化实战
  • AI工具链

    • Claude Code 实战指南:从安装配置到企业级开发流程
    • 一次 Claude Code 启动失败的 AI 辅助排查复盘
    • 基于提示词工程与KITE框架的Redis签到功能开发实践
    • Claude Code 记忆管理:CLAUDE.md 最佳实践
    • Claude Code 规则管理:Rules 拆分编排与迭代实践(文末送书)
    • VSCode与Claude Code后端开发环境搭建与AI编程工作流实践
关于
收藏
  • 分类
  • 标签
  • 归档
GitHub (opens new window)
  • 场景设计

    • 对账核销场景设计与重构实践
    • 记一次StarRocks源码级排错和既有架构优化实践
      • 写在文章开头
      • 背景说明
      • 排查过程
        • 根因定位与推导
        • 临时止血
        • 源码级优化
        • 架构调优
        • 版本升级
      • 线上验收结果
      • 常见问题
        • StarRocks 的 FE 和 BE 分别负责什么?查询 Plan 是在哪个节点生成的?
        • 为什么写入会干扰查询 Plan?底层机制是什么?
        • 你们 StarRocks 的部署架构是怎样的?
        • 升级 3.x 版本有没有遇到兼容性问题?
        • 除了这个参数调优,StarRocks 还有哪些常见的查询优化手段?
      • 复盘与总结
      • 参考
  • 面试题
  • 场景设计
sharkchili
2026-05-13
目录

记一次StarRocks源码级排错和既有架构优化实践

# 写在文章开头

在AI飞速发展的时代,笔者还是会停下脚步进行复盘,例如这次要讲的一个项目架构上的优化,笔者也常想,借助此时的AI的知识语料和上下文推理的能力,如果再次面对这个问题。我会有什么样的决策?最终又会收获什么?

答案是未知的,我可能会在别的维度有所收获,也可能没有。不过好在这件事发生在过去,我合理的通过自己的元认知并协调各方资源维稳的修复这个问题。

所以,笔者今天还是非常乐意将这件事分享出来,希望让读者能够借助这个时间的资源,放大这份能力和工作理念。

SharkChili · 计算机路上的禅修者

开源贡献

  • mini-redis:教学级 Redis 精简实现 · https://github.com/shark-ctrl/mini-redis
  • Nightingale:深度源码研究

关注公众号,回复 【加群】 加入技术社群

# 背景说明

笔者所负责的一个核心平台涉及大量交易业务的聚合分析和报表查询,考虑到检索性能表现同时避免核心交易流水库受这些聚合查询的扰动出现严重的性能损耗,团队的业务建立初期就选用 StarRocks 作为业务库,对应的数据也是采用 Flink 监听 MySQL 变更进行同步:

随着业务的稳步拓展,交易流水稳步上升,与之带来的既有报表分析查询业务偶发出现如下问题报错:

The tablet write operation update metadata take a long time
1

# 排查过程

# 根因定位与推导

因为是初次遇到该问题,结合语义笔者也没有能得出一个大概,于是到官方社区检索下面这段回答:

结合笔者在团队中看到的grafana面板上的指标综合分析,初步判断是近期攀升的交易流水频繁写入,导致平台上的实时查询计划在校验期间被这些写入请求所扰动,进而导致校验不合法从而导致检索失败:

# 临时止血

初步定位问题根因之后,本着风险点最小的方式先进行临时止血,再从长计议,针对既有表象和论坛上一些说法,我们协调的交易侧服务相关负责人进行一次技术会议,给出如下临时方案:

  • 所有接口统一捕获该问题,并进行一次重试
  • 若重试依然失败,直接降级到一个MySQL从库,牺牲一点查询效率,保证报表分析数据能够给到业务侧

starrocks-perf-3.drawio

业务将该问题推导优先级,并花费三天时间完成临时改造并送到生产,期间笔者也针对既有问题,在grafana上面板上补充监控该问题的重试次数和落入MySQL的频率,以观察问题持续严重性并及时针对临时止血策略进行动态调整。

# 源码级优化

通过上述一系列策略,我们相对平稳的压住业务上的异常。本着定位根因有效根治的理念,笔者在上述方案落地后,结合ELK面板上既有问题的栈帧, 通读了 StarRocks 官方文档和既有版本的 StarRocks 源码,最终了解到的问题的全貌。

作为分布式列式存储数据库,starrocks将节点分为FE和BE,对于读写请求,starrocks都会交由FE节点校验该计划的合理性,明确无误之后,将执行计划分发给各个 BE 执行,其中会选定一个 BE 节点作为 Coordinator 负责调度执行并聚合结果返回给客户端:

结合starrocks FE源码,笔者发现,在FE校验执行阶段,当明确感知执行计划收到干扰时,FE会休眠10ms之后进行重试,当再次重试失败后,就会抛出上述错误,对应的笔者也给出这段校验充实的核心逻辑,即 StatementPlanner 的createQueryPlanWithReTry方法核心逻辑,可以看到它会基于系统参数max_query_retry_time在plan校验失败后,进行短暂休眠在重试:

// StatementPlanner 核心逻辑
// 1. 执行计划重试循环,默认最多重试2次(由 max_query_retry_time 控制)
for (int i = 0; i < Config.max_query_retry_time; ++i) {
    long planStartTime = OptimisticVersion.generate();

    // 2. 生成逻辑计划
    LogicalPlan logicalPlan = new RelationTransformer(transformerContext).transformWithSelectLimit(query);

    // 3. 优化逻辑计划,生成物理计划
    OptExpression optimizedPlan = optimizer.optimize(...);

    // 4. 构建执行计划
    ExecPlan plan = PlanFragmentBuilder.createPhysicalPlan(...);

    // 5. 关键校验:检查计划生成期间表的 Schema 是否发生变化
    isSchemaValid = olapTables.stream().noneMatch(t -> t.lastSchemaUpdateTime.get() > planStartTime);

    // 6. 二次校验:检查表的版本更新是否在计划构建期间完成
    isSchemaValid = isSchemaValid && olapTables.stream().allMatch(t ->
            t.lastVersionUpdateEndTime.get() < buildFragmentStartTime &&
                    t.lastVersionUpdateEndTime.get() >= t.lastVersionUpdateStartTime.get());

    if (isSchemaValid) {
        return plan; // 校验通过,返回执行计划
    }

    // 7. 如果检测到有表正在更新中(开始时间 > 结束时间),等待10ms后重试
    // 10ms 对应 publish_version_interval_ms 配置项
    if (olapTables.stream().anyMatch(t -> t.lastVersionUpdateStartTime.get() > t.lastVersionUpdateEndTime.get())) {
        Thread.sleep(10);
    }
}
// 重试次数耗尽,抛出异常 → 页面崩溃
Preconditions.checkState(false, "The tablet write operation update metadata " +
                "take a long time");
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35

结合这段源代码,笔者顺着max_query_retry_time这个参数定位到参数定义加载相关代码段,看到其元注解存在一个mutable的语义且设置为true,大体推测这个参数是可以修改的:

	 @ConfField(mutable = true)
    public static int max_query_retry_time = 2;
1
2

于是,笔者再次回到官网检索相关资料,最终印证了这个说法,于是,笔者提供了更进一步的止血策略,即调大最大重试次数。

借助上一轮预埋的监控,笔者让相关服务负责人调大接口层面的重试次数和降低的代码逻辑,最终看到在4次左右就,既有的 StarRocks 就可以完成聚合查询,所以我们尝试将该参数设置为5,初步保证的业务的稳定性。

# 架构调优

明确没有生产上的担忧之后,考虑到既有重试存在重新分析和延迟开销,可能对未来拓展的业务带来性能瓶颈,所以我们还是需要更进一步的去进行优化保证准实时性。于是,我们将目标指向了写入端。

我们写入端是通过 Canal 监听 MySQL binlog 写入 Kafka 让 Flink 进行批攒后进行写入操作:

深入代码了解内部逻辑,我们就需要进一步了解为什么批攒的情况下还是会导致写入频繁。结合监控面板和代码逻辑,明确批攒在15000时触发写入,按照每分钟10w的量级,理论上批攒写入应该是控制在10次左右,但是grafana面板却出现50次左右。对此,进一步分析写入时的数据详情。

结合ELK的观测日志和 StarRocks 数据同步接口 Stream Load 的要求,我们最终定位到原因。由于 Stream Load 的 columns 参数要求单次请求中所有数据行必须包含相同的列集合,当批攒的数据来源于不同字段的变更操作时,必须按字段集合拆分为多个 Stream Load 请求。结合运维部一贯维稳将 MySQL 日志设置为 statement 级别的作风,笔者得出如下定论:

  1. 业务敏捷拓展,导致既有交易流水表涉及各种不同字段的插入和更新操作
  2. 运维部的同步组件只给出主键和变更列
  3. Flink 按照批攒时,对应15000条数据构建出多个请求
  4. 频繁写入,导致业务报表查询频繁报错

针对该问题,笔者的理念是在binlog同步段将字段打齐同步,当然,为了保证运维部所担忧的传输开销等资源占用问题,笔者提出监听slave rows数据的方式进行全列同步。由此,我们更进一步的降低写入的频率,随后我们稳步将参数进行缩小直至变为1,每日报错也仅偶发出现几次,于是将重试次数设置为3。

除此之外,因为写入由单接口即可完成,数据延迟这也有显著的降低。

# 版本升级

出于未来的考量,我们还是希望能够解决偶发重试的问题,结合starrocks社区和github的issues,我们发现在3.2的最高版本有一个分支修复了这个问题,它在plan阶段绕过执行计划的校验,仅校验schema这些变更:

所以,在上述的一系列操作之后,我们构建一个备库搭建全新版本的数据库,并采用灰度的方式将部分流量移动到该库表下测试其查询稳定性。经过一段时间的运行后,除了一些SQL语法兼容性问题以外,不再出现查询报错。所以,我们最终将最新版本的库提上生产,并在一次深夜通过全量同步+离线补数和并调整flink偏移量完成订正,由此完成问题修复闭环。

# 线上验收结果

经过一个月的监控观测,我们完成的以下指标的推进:

  • 经过一个月的监控观测,报表查询未再出现因 Plan 校验失败导致的报错,页面崩溃问题完全消除
  • 意外收获:升级后 LIMIT 查询性能大幅提升,优化器支持先取 LIMIT 再关联
-- 查询交易流水表,关联支付参数表和客户信息表
-- 按交易时间降序、订单号降序排列,取前 10 条
SELECT t.column_list
FROM t_trade_detail t
LEFT JOIN t_pay_config pp ON t.order_no = pp.order_no
    AND pp.created_time >= '20260106000000'
    AND pp.created_time <= '20260106235959'
LEFT JOIN t_customer_info s ON t.cust_id = s.cust_id
WHERE t.trade_time >= '20260106000000'
    AND t.trade_time <= '20260106235959'
    AND t.status IN ('2')
ORDER BY t.trade_time DESC, t.order_no DESC
LIMIT 10
1
2
3
4
5
6
7
8
9
10
11
12
13

升级后优化器会先取出 LIMIT 结果再进行关联,避免全表关联后再截取:

# 常见问题

# StarRocks 的 FE 和 BE 分别负责什么?查询 Plan 是在哪个节点生成的?

FE(Frontend)负责 SQL 解析、查询计划生成、元数据管理;BE(Backend)负责数据存储和查询执行。查询 Plan 在 FE 生成。

# 为什么写入会干扰查询 Plan?底层机制是什么?

StarRocks 的写入是通过发布版本(publish version)来实现的,每次写入会更新 tablet 的元数据。FE 在生成查询 Plan 时需要获取一致的版本快照,如果写入频繁导致版本持续变更,Plan 校验就会失败触发重试。

# 你们 StarRocks 的部署架构是怎样的?

3 FE(其中1个 Leader、2个 Follower)+ 3 BE,FE 负责查询计划和元数据管理,BE 负责数据存储和查询执行。

# 升级 3.x 版本有没有遇到兼容性问题?

系统层面没有太大问题,期间就是遇到一些官方优化后所导致的SQL语法兼容性问题,我们也都有在准生产环境稳步跟进

# 除了这个参数调优,StarRocks 还有哪些常见的查询优化手段?

  • 物化视图、Colocate Group、分区裁剪、Bucket Shuffle Join 等。

# 复盘与总结

这是笔者在AI工具猛烈发展之前所遇到的一个问题,当然,读者也可以忽略这个背景。这篇文章笔者并没有过分去强调某个技术和原理,更着重去说明笔者如何推理思考既有问题的推理过程,如何基于信息拆解出子问题,然后去分析,再进行下一步决策,并结合风险评估维稳逐步推进,再完成验收。

SharkChili · 计算机路上的禅修者

开源贡献

  • mini-redis:教学级 Redis 精简实现 · https://github.com/shark-ctrl/mini-redis
  • Nightingale:深度源码研究

关注公众号,回复 【加群】 加入技术社群

# 参考

存算一体升级到3.1.6后 查询报错 The tablet write operation update metadata take a long time:https://forum.mirrorship.cn/t/topic/10579 (opens new window)

【3.1.10版本】查询报错The tablet write operation update metadata take a long time:https://forum.mirrorship.cn/t/topic/13976 (opens new window)

The tablet write operation update metadata take a long time:https://forum.mirrorship.cn/t/topic/13181 (opens new window)

starrocks:https://github.com/StarRocks/starrocks/tree/3.2.1 (opens new window)

FE 配置 - 用户管理、查询引擎和导入导出:https://docs.starrocks.io/zh/docs/administration/management/FE_parameters/user_query_loading/#max_query_retry_time (opens new window)

编辑 (opens new window)
上次更新: 2026/05/13, 10:27:33
对账核销场景设计与重构实践

← 对账核销场景设计与重构实践

最近更新
01
对账核销场景设计与重构实践
05-12
02
Windows 10 下的 Maven 安装配置教程
05-11
03
基于 Claude Code 复刻 Redis 慢查询指令实践
05-11
更多文章>
Theme by Vdoing | Copyright © 2025-2026 Evan Xu | MIT License | 桂ICP备2024034950号 | 桂公网安备45142202000030
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式
×
×