跳转到内容

Apache Pinot — LinkedIn 起家的实时 OLAP

是什么

Apache Pinot 是一个给”用户直接看的实时仪表板”用的列式 OLAP 数据库。日常类比:像新闻演播室的实时收视率屏——主播在镜头前刚说完一句话,制作间已经能看到这一秒收视曲线的拐点;不是”等明天看昨天的报表”,而是亿级用户同时查、查的还是几秒前的数据

它擅长的场景:

  • 数据带时间戳 + 一直流进来(点击、订单、风控事件)
  • 维度基数高(按用户/广告/地区切片)
  • 查询简单但 QPS 极高(GROUP BY + SUM/COUNT,几百毫秒返回)
  • 面向终端用户——不是分析师偶尔跑一次,而是 App 里每个用户每次刷新都查

LinkedIn 当年造它就是为了 “Who viewed your profile” 这一页:每个用户登录都要看自己被谁看过、按时间聚合,亿级用户 × 秒级新鲜度 × 毫秒级响应。传统 OLAP 跑批来不及,OLTP 数据库扛不住聚合。

为什么重要

Pinot 把”实时分析”的标准从分钟级推到毫秒级,并且把它变成用户面向的能力,而不是只给内部分析师用。

它和 Druid 是同一时代、同一思路(Lambda 架构落地)的两个工业代表,但 Pinot 在三件事上做得更激进:

  • 节点角色更少(3 类 vs Druid 的 6 类),运维心智负担轻
  • Star-Tree 索引:一种独有的预聚合数据结构,让高频 GROUP BY 不必扫原始行
  • 延迟目标更狠:Druid 通常瞄秒级 dashboard,Pinot 瞄 p99 几十毫秒的 user-facing 查询

理解 Pinot 等于理解:当”实时”变成产品功能而不是后台报表,数据库要做哪些妥协。

核心要点

抓三个关键词:段、节点角色、Star-Tree

段(Segment):数据按时间切成不可变文件,每段几百万行。段是查询单元也是分发单元——查询命中哪些段就并行扫哪些段。

三类节点(比 Druid 简洁):

  • Controller:管元数据、调度、段分配(背后用 Apache Helix + ZooKeeper)
  • Broker:接 SQL,拆子查询发出去,合并结果
  • Server:存段 + 本地查询,分两种:
    • Realtime Server:从 Kafka/Pulsar 拉流,在内存里攒段
    • Offline Server:存已封存的段,从 HDFS/S3 加载

实时段在内存写满或到时间后 commit——数据落盘并交给 Offline Server,Realtime 转去做下一段。用户全程感觉不到这次切换

Star-Tree 索引:对一组维度组合(如 “国家 × 设备 × 广告位”)预先算好 SUM/COUNT 存成一棵稀疏树。查询时若维度组合命中树节点就直接读聚合值,否则降级到原始扫描。空间换时间——只对高频聚合查询有效,维度基数太高反而爆炸。

配套索引层(按列可开关):inverted、sorted、range、bloom、text(Lucene)、JSON、geo、timestamp。比 Druid 多得多——Pinot 的哲学是”索引堆够,扫描少”。

实践案例

案例 1:一条点击事件的命运

广告平台每秒 10 万次点击进 Kafka。Pinot 怎么处理:

  1. Realtime Server 订阅 Kafka topic,拉到 {ts, region, ad_id, clicks}
  2. 在内存里建实时段,写入即刻可查(与 Druid 几秒延迟不同,Pinot 通常亚秒)
  3. 段达到阈值(行数/时间/大小)→ commit:序列化、上传深度存储、通知 Controller
  4. Controller 把段分配给某个 Offline Server,Realtime 释放内存
  5. 后续查询走 Offline Server(更省内存、更快)

整个迁移对查询透明——Broker 永远在最新元数据里查段在哪。

案例 2:一次高 QPS 查询的路径

SELECT region, SUM(clicks)
FROM ad_events
WHERE ts BETWEEN '2026-05-31 09:00' AND '2026-05-31 11:00'
AND device = 'mobile'
GROUP BY region

正常路径:Broker 定位涉及 8 个段 → 并行下发到 Server → 各自扫”region/device/clicks”列 → 局部聚合 → Broker 合并。

有 Star-Tree 时:如果建了 “(region, device) → SUM(clicks)” 的预聚合,Server 直接从树里读聚合值,跳过整段扫描。同样 8 个段、原本要扫几百万行,现在只读几百个聚合节点——延迟从几百毫秒降到几十毫秒。

这就是 LinkedIn 用 Pinot 撑起亿级 QPS user-facing dashboard 的核心武器。

案例 3:和 Druid 的取舍对比

LinkedIn 内部曾同时跑 Druid 和 Pinot。后来选 Pinot 主推的原因:

  • 运维更轻:3 类节点 vs 6 类
  • 延迟更稳:Star-Tree 让 p99 可预测
  • 索引更全:text/geo/JSON 内嵌

但 Pinot 也有代价——Schema 改动更僵Join 长期是短板(直到多阶段引擎),所以分析师跑探索性查询的场景仍偏 Druid 或 Trino。

踩过的坑

  1. Star-Tree 不是免费午餐:维度基数高(如用户 ID)时预聚合树会爆炸。要选确实高频的维度组合做预聚合,其余降级到普通索引。

  2. Realtime 段 OOM 风险:内存攒段意味着 segment.flush.threshold.rows / time / size 三个参数没调好就崩。生产部署必踩。

  3. Schema 半固定:维度(dimensions)和指标(metrics)摄取时就要分开声明。改列类型要重灌历史段,代价不小。

  4. Join 历史包袱:早期单阶段引擎几乎只支持 Lookup Join。多阶段查询引擎(MSQE) 2023 起支持分布式 Hash Join,但成熟度仍在追 Trino。复杂 OLAP 别期待 ClickHouse/Trino 级体验。

  5. 运维门槛仍高:3 类节点 + Helix + ZooKeeper + 深度存储 + Kafka。最小生产部署机器数量并不少——和 ClickHouse 单机相比,小规模反而更贵。

适用 vs 不适用场景

适用

  • 用户面向的实时仪表板(毫秒级 p99,亿级 QPS)
  • 时间序列 + 高基数维度(广告、风控、订单流、IoT)
  • Kafka 实时流入 + 历史回溯统一查询
  • 高频固定模式聚合(GROUP BY + SUM/COUNT)

不适用

  • 强事务、点更新 → PostgreSQL/TiDB
  • 复杂多表 Join、ad-hoc 探索 → Trino/ClickHouse
  • 全文搜索为主 → Elasticsearch(Pinot 内嵌 Lucene 但定位不在此)
  • 数据量小(< 100GB)→ 单机 ClickHouse/DuckDB 省心

历史小故事(可跳过)

  • 2013:LinkedIn 工程团队为 “Who viewed your profile” 立项,目标亿级用户 × 秒级新鲜度 × 毫秒级响应
  • 2014:内部上线,依赖同样 LinkedIn 出品的 Apache Helix 做集群协调
  • 2015:开源到 GitHub,Apache 2.0 协议
  • 2018:进 Apache 孵化器
  • 2021:毕业为 Apache 顶级项目
  • 2022:核心团队成立 StarTree,发布 Pinot Cloud
  • 2023+:多阶段查询引擎接入 Apache Calcite,支持分布式 Join,向通用 OLAP 拓展

LinkedIn、Uber、Stripe、Walmart、Slack、Confluent 都是已知大用户。

学到什么

  1. “实时”分级别:分钟(Druid 早期)→ 秒(标准实时分析)→ 毫秒(Pinot user-facing)。每提一个量级,架构都要重写一次
  2. 预聚合 vs 实时聚合是 OLAP 永恒的取舍:Star-Tree 是预聚合派的工业代表,DuckDB 等是实时聚合派的代表
  3. 节点角色越少越好维护——Pinot 3 类是工程克制的胜利
  4. Schema 越僵硬,查询越快:半固定 schema 是 Pinot 用”灵活性”换”延迟”的明确选择
  5. 同一思路可以有多条工业路径:Druid 和 Pinot 都解 Lambda 架构,但侧重不同——这告诉我们不存在唯一正确的实时分析架构

延伸阅读

关联

  • druid —— 同样落地 Lambda 架构,但节点更多、延迟目标更宽松
  • clickhouse —— 同样列存 OLAP,强在单机和复杂 Join,弱在 user-facing 高 QPS
  • kafka —— Pinot Realtime Server 的标准上游
  • helix —— LinkedIn 出品的集群状态机,Pinot 调度的底盘

反向链接

  • clickhouse —— ClickHouse — 列式 OLAP 数据库
  • druid —— Apache Druid — 流批一体的实时分析数据库