2. Pinot整体架构
Pinot 的分布式架构,说白了就是一套分工明确的协作系统。我刚开始接触时也觉得组件有点多,但真正用起来就会发现——每个角色各司其职,缺一不可。
整个系统由四个核心组件构成:Controller、Broker、Server、Minion。它们之间通过 Apache Helix 做集群管理,ZooKeeper 负责元数据存储和协调。
一句话总结:Controller 管元数据,Broker 管查询路由,Server 管数据存储与计算,Minion 管后台任务。
1. Controller:集群的大脑
Controller 是整个集群的元数据管理中心。它负责管理 Table 和 Segment 的元数据,处理 Segment 的分配、迁移、下线和重新平衡。
我个人习惯把 Controller 想象成「集群的管家」。它不参与实际的数据查询,但所有组件的状态变更都要经过它。
避坑指南:我曾经在生产环境中遇到过 Controller 单点故障导致整个集群无法做元数据变更的问题。建议至少部署 3 个 Controller 实例,配合 Helix 做 Leader 选举。
Controller 的核心职责包括:
- Table 管理:创建、更新、删除 Table 定义
- Segment 管理:分配 Segment 到 Server,触发 Segment 合并
- 集群监控:通过 Helix 监控各节点健康状态
- 重平衡:当节点增减时自动重新分配 Segment
2. Broker:查询的入口
Broker 是客户端查询的第一站。它接收 SQL 查询,解析后根据路由信息分发到对应的 Server,最后合并结果返回给客户端。
你想想看,一个查询可能涉及几十个甚至上百个 Segment。Broker 要做的就是把查询拆成多个子查询,并行发送到不同 Server,再等所有结果回来做合并。这中间还有超时控制、错误重试等逻辑。
关键点:Broker 本身不存储数据,也不做计算。它只负责路由和结果合并。所以 Broker 是无状态的,可以水平扩展。
Broker 的查询流程大致如下:
- 接收客户端 SQL 查询
- 解析 SQL,生成查询计划
- 从 ZooKeeper 获取路由信息
- 将查询分发到目标 Server
- 等待所有 Server 返回结果
- 合并结果,返回给客户端
3. Server:数据的基石
Server 是 Pinot 的数据存储和计算节点。每个 Server 负责管理多个 Segment,每个 Segment 包含一个数据分片。
Server 内部做了很多优化。比如列式存储、多种索引(倒排索引、StarTree 索引等)、预聚合等。这些设计让 Pinot 能在毫秒级返回聚合查询结果。
我记得有一次做性能调优,发现某个查询特别慢。排查后发现是 Server 上 Segment 分布不均匀,导致某些 Server 负载过高。后来通过 Controller 的重平衡功能解决了。
| 特性 | 说明 |
|---|---|
| 列式存储 | 只读取查询涉及的列,减少 I/O |
| 多种索引 | 倒排索引、范围索引、StarTree 索引 |
| 预聚合 | 支持预计算聚合结果,加速查询 |
| Segment 隔离 | 每个 Segment 独立存储,故障隔离 |
4. Minion:后台任务执行者
Minion 是 Pinot 的后台任务执行组件。它负责执行一些耗时或资源密集型的任务,比如 Segment 合并、数据转换、协议升级等。
嗯,这里要注意。Minion 不是必须的组件。如果你的集群规模不大,或者不需要后台任务,可以不用部署 Minion。但一旦数据量上来,Minion 的价值就体现出来了。
注意:Minion 任务默认是异步执行的。如果任务失败,Controller 会重新调度。我曾经遇到过 Minion 任务卡死的情况,后来加了超时机制才解决。
常见的 Minion 任务类型:
- Segment 合并:将多个小 Segment 合并成大 Segment,减少元数据量
- 数据转换:将数据从一种格式转换为另一种格式
- 索引重建:重新生成索引,优化查询性能
- 协议升级:将旧版本 Segment 升级到新版本
组件协作流程
四个组件不是孤立的。它们通过 ZooKeeper 和 Helix 紧密协作。我画了一张时序图,方便你理解一次完整查询的流程:
- 客户端向 Broker 发送 SQL 查询
- Broker 从 ZooKeeper 获取路由表
- Broker 将查询分发到对应的 Server
- Server 执行查询,返回结果
- Broker 合并结果,返回给客户端
同时,Controller 和 Minion 在后台默默工作。Controller 监控集群状态,Minion 执行后台任务。这些都不影响在线查询。
个人经验:我建议在部署时,Broker 和 Server 分开部署。虽然可以混部,但分开后更容易做资源隔离和故障排查。Controller 和 Minion 可以共用节点,因为它们都不是实时路径上的组件。