M3 — Uber 的分布式 TSDB
是什么
M3 是 Uber 2014-2018 年内部打磨、2018 年开源(Apache 2.0)的分布式时序数据库套件,专门解决 Prometheus 单机扛不住的”超大规模监控”。日常类比:
- prometheus 是社区诊所——一个医生看一片,记录都在自己抽屉,搬家就麻烦
- victoriametrics 是连锁诊所——同一品牌不同分店,文件柜都一样
- M3 是国家级医院网络——挂号 / 检验 / 影像 / 病案各部门独立、互相协作,能撑数十亿患者
M3 不是单个二进制,而是四个组件拼起来的系统:M3DB(存储)、M3 Coordinator(Prom 适配)、M3 Aggregator(下采样)、M3 Query(查询)。
为什么重要
不理解 M3,下面这些事都没法解释:
- 为什么 Uber 内部要写一套”自己的 TSDB”——单 Prometheus 顶不住每秒80 亿 metric 写入
- 为什么 Prometheus 官方推荐的 remote storage 列表里有 M3——它是水平扩展替代方案,不是周边
- 为什么同样号称”Prom 长期存储”,Thanos / Cortex 是”拼起来”,M3 是”重写存储引擎”
- 为什么 Chronosphere 这家公司值十亿美元——它就是 M3 原班团队商业化
核心要点
M3 的设计可以拆成 三层:
-
存储层 M3DB:自研时序存储,数据按 shard 切分,副本走 Cassandra 风格的 ring + gossip。压缩用类 Gorilla 的 XOR + delta-of-delta,时间戳压到 1.37 字节/样本。
-
索引层 自研倒排索引:用 Roaring Bitmap + FST(有限状态转换器)存 tag → series 的映射。Prometheus 的索引全部装内存,M3 的索引可以部分常驻 + 部分按需加载,所以能扛得住更高的 series 基数。
-
协调层 Etcd + Coordinator:Etcd 存 placement(哪个 shard 在哪台机),元数据强一致;Coordinator 是无状态网关,对外说 Prometheus remote_write/remote_read 协议,对内把请求分发给对应 shard。
实践案例
案例 1:Prometheus 加 M3 当远端
最常见的接入方式:让现有 Prometheus 把数据双写一份到 M3,本地保留 2 小时供告警,长期数据查 M3。
remote_write: - url: "http://m3coordinator:7201/api/v1/prom/remote/write"remote_read: - url: "http://m3coordinator:7201/api/v1/prom/remote/read"Prometheus 推数据进 Coordinator,Coordinator 按 shard hash 分发到 M3DB 节点。Grafana 直接连 Coordinator 的 PromQL 端点,数据看起来跟纯 Prom 一模一样。
案例 2:四组件部署形态
生产环境分四个角色,各自独立扩缩容:
[Prometheus / 应用] │ remote_write ▼[M3 Coordinator] ── 路由 ──┐ ▼ [M3 Aggregator] ── 下采样 ──┐ ▼ [M3DB cluster] ▲ [M3 Query] ◄── Grafana- Coordinator:无状态,可以多副本。负责协议翻译 + 请求路由
- Aggregator:负责把 10 秒原始数据实时聚合成 1 分钟、5 分钟、1 小时多档 rollup
- M3DB:有状态分片存储,每 shard 默认 3 副本
- M3 Query:分布式 fanout 查询引擎,并行从多个 M3DB 拉数据再合并
案例 3:单机 Docker 起一个完整 M3
学习 / 评估时不必上集群,一个二进制起 M3DB single-node:
docker run -p 7201:7201 -p 9000:9000 \ --name m3db_local \ quay.io/m3db/m3dbnode:latest7201 是 Coordinator 端口(PromQL / remote_write),9000 是 M3DB 内部端口。然后建 namespace(namespace 类似数据库里的 schema,决定 retention 和 resolution):
curl -X POST localhost:7201/api/v1/services/m3db/namespace \ -d '{"name":"default","options":{"retentionOptions":{"retentionPeriodNanos":"86400000000000"}}}'注意里面的 JSON 用了双引号,这是 HTTP 接口要求;写到配置文件里也是 YAML 格式。
踩过的坑
-
Etcd 是必需的,不是可选:M3 的 placement(shard 到节点的映射)写在 etcd,不是 M3DB 内部。生产部署必须先有 etcd 集群;测试环境用 single-node 把 etcd embed 进去,但 placement 一旦改坏,整个集群读不到数据。
-
Namespace 的 retention 不能”只增不减改大”:建 namespace 时定的 retentionPeriod=24h,后面想改成 7d——不能。要新建一个 namespace,写双写,等历史够 7 天再切。这设计是为防止把已删数据”复活”,但运维起来很反直觉。
-
Coordinator 和 Aggregator 经常被新人混:Coordinator 是无状态网关,每次调用都转发;Aggregator 是有状态聚合器,缓存窗口数据做 rollup。文档里两个名字长得像,但部署、扩缩容策略完全不同——Coordinator 挂了重启就行,Aggregator 挂了窗口数据可能丢。
-
高基数 label 把倒排索引炸了:M3 的倒排索引虽然分级加载,但 series 基数(不同 label 组合数)超过千万级别后,写入路径上的索引更新会变成瓶颈。Uber 内部踩过的教训:user_id / request_id 这种唯一 ID 不能进 label,要么 hash 截断,要么走日志系统。
适用 vs 不适用场景
适用:
- 单 Prometheus 已经撑不住的中大型公司——百万 series/s 以上写入
- 需要多年长期存储且查询要快——M3 按 shard 切分,不会因为数据多就慢
- 已有 Prometheus / Graphite 生态,要无缝替换底层存储——Coordinator 兼容三种协议
- 团队有专人运维基础设施,能搞定 etcd + Cassandra 风格分片
不适用:
- 团队规模小、运维人力少——M3 部署复杂度比 victoriametrics 高一个量级
- 数据规模低于百万 series/s——杀鸡用牛刀,VM 或单 Prom 就够
- 想要 SQL 查询——M3 只支持 PromQL / M3QL / Graphite 三种
- 需要日志 / 追踪——M3 是纯指标系统,日志走 ELK / Loki,追踪走 Jaeger
历史小故事(可跳过)
- 2014 年:Uber 监控用 Graphite + Carbon,业务暴涨后单机扛不住,开始研发内部 M3
- 2015-2017 年:M3 在 Uber 内部完整迭代,名字是 “Metrics Monitoring Mission”
- 2018 年 8 月:M3 在 KubeCon 北美开源(Apache 2.0),主仓 m3db/m3
- 2019 年:原核心团队 Rob Skillington / Martin Mao 离开 Uber,成立 Chronosphere
- 2020 年起:Chronosphere 基于 M3 做商业版本,公司估值进入十亿美元级独角兽
M3 不是社区驱动型项目——它是先有真实超大规模的内部需求,迭代成熟后才开源,所以代码反而比”先开源后扩规模”的项目更成熟。
学到什么
- 超大规模监控的瓶颈不在算力在索引——M3 最难的部分是倒排索引能否撑住高基数 label
- 协议兼容是降低迁移成本的杠杆——M3 兼容 Prom 三种协议,让企业可以”先双写再切换”
- Cassandra ring + gossip 这套架构虽老但稳——M3 把它套用到时序数据,证明了基础设施模式的复用性
- 开源时机很重要——内部跑稳后再开源,比”边开源边迭代”省了大量 breaking change
延伸阅读
- 官方文档:M3 Docs(从架构到部署都在)
- 设计博客:Uber 工程 — M3 Open Source(开源时的设计 RFC)
- 源码:GitHub - m3db/m3(Go,单 monorepo 装四组件)
- KubeCon 演讲:M3 — Uber Open Source Metrics Platform
关联
- prometheus —— M3 的协议兼容目标,remote_write / PromQL 全照搬
- victoriametrics —— 同样定位”Prom 长期存储”,但 VM 走单二进制无状态路线
- opentsdb —— 第一代分布式 TSDB,依赖 HBase;M3 选自带存储不外挂 KV
- grafana —— 最常见的 M3 前端,连 Coordinator 当 Prom 数据源即可
反向链接
- grafana —— Grafana — 监控可视化看板
- opentsdb —— OpenTSDB — HBase 上的第一代分布式 TSDB
- prometheus —— Prometheus — 时序监控系统
- victoriametrics —— VictoriaMetrics — 高性能 Prometheus 替代