- 时序数据库
- 后端
- 数据存储
- 可观测性
- 云原生
【免费下载链接】mimir
Grafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.
Grafana Mimir 是一套为 Prometheus 提供水平可扩展、高可用、多租户长期存储的时序数据库系统。本文以官方 Glossary(术语表)为骨架,逐条拆解 Blocks storage、Chunk、Churn、Hash ring、Memberlist、HA tracker、WAL 等核心术语的准确定义,并结合仓库源码与配置项给出底层实现依据,帮助读者快速建立对 Mimir 数据模型与分布式架构的整体认知。
为什么需要一份术语表
Grafana Mimir 的文档、配置和源码中频繁出现一系列高度领域化的术语,例如block、chunk、ring、WAL、tenant。这些术语之间往往存在衍生与互指关系(例如 "Ring" 指向 "Hash ring","Org" 与 "User" 都指向 "Tenant")。对于刚接触 Mimir 的开发者而言,准确理解这些概念是读懂架构图、排查分布式读写问题、解读告警与日志的前提。
本文整理自 Mimir 官方 Glossary(见 docs/sources/mimir/references/glossary.md),并对每个术语补充了当前仓库中可验证的源码与配置依据,力求"一词一义、一词一证"。
Blocks storage(块存储)
Blocks storage 是 Mimir 基于 Prometheus TSDB 构建的存储引擎。Mimir 将时序数据以 Prometheus 原生 TSDB 的 block(数据块)形式写入对象存储,支持的后端包括:
- AWS S3
- Google Cloud Storage(GCS)
- Azure Blob Storage
- OpenStack Object Storage(Swift)
从源码结构看,Mimir 的 ingest 侧直接依赖github.com/prometheus/prometheus/tsdb(见 pkg/ingester/ingester.go 第 33 行的 import),而对象存储相关的 bucket 抽象集中在 pkg/storage/bucket 目录,存储配置项则定义在 pkg/storage/tsdb/config.go。这意味着 Mimir 并没有另起炉灶发明存储格式,而是复用 Prometheus 久经生产验证的 block 格式,将其从"单机本地磁盘"扩展到"分布式对象存储"。
Chunk(块)
Chunk 是包含一条 series(序列)的编码后时间戳-值(timestamp-value)对的对象。它是比 block 更细粒度的数据组织单位:
- block是 TSDB 落盘/上传对象存储的目录级单元,包含元数据、索引与多个 chunk 文件;
- chunk则是 block 内部按序列组织、经过编码压缩的时间戳-值批量数据。
写入路径上,ingester 先在内存 TSDB head 中积累 chunk,待达到压缩条件后固化到 block 中;查询时 store-gateway 负责从 block 中读取并解压相关 chunk。因此 chunk 编码格式(例如 float chunk encoding)甚至被作为租户级限流/覆盖项暴露出来,详见 pkg/util/validation/exporter/exporter.go 中的float_chunk_encoding相关逻辑。
Churn(流失/序列更替)
Churn 描述 series 进入 idle(空闲)状态的频率。一条 series 在被监控目标停止导出后即变为 idle,典型场景是被监控的进程或节点被终止。
Churn 之所以重要,是因为它直接决定了:
- 时序数据量:高 churn 意味着需要跟踪、索引和查询的 series 数量增长更快;
- 内存压力:ingester 需要为不断新增的 series 维护索引与样本缓冲区;
- 存储成本:store-gateway 需要加载更多 block 元数据来响应查询。
Mimir 通过 pkg/ingester/activeseries 等模块跟踪活跃 series,并依靠 TSDB head 的闲置压缩(见下文 Flushing)及时收敛失效数据的内存占用。
Component(组件)
Grafana Mimir 由多个组件(component)组成,每个组件为系统提供一项特定功能。官方术语表列出的核心组件包括:
| 组件 | 职责定位 | 仓库对应目录 |
|---|---|---|
| Compactor | 压缩、去重、合并存储桶中的 block | pkg/compactor |
| Distributor | 校验数据、对写入进行分片与复制 | pkg/distributor |
| Ingester | 接收写入,在内存中积累数据并周期落盘 | pkg/ingester |
| Query-frontend | 查询前端,负责拆分、缓存与排队查询 | pkg/frontend |
| Query-scheduler | 调度查询请求到 query-frontend | pkg/scheduler |
| Store-gateway | 提供对长期存储中 block 的查询访问 | pkg/storegateway |
| Alertmanager(可选) | 多租户告警管理 | pkg/alertmanager |
| Ruler(可选) | 周期评估告警/记录规则 | pkg/ruler |
组件既可按微服务模式独立部署,也可按单进程模式(monolithic mode)合并运行,开发环境示例见 development/mimir-monolithic-mode 下的 docker-compose 配置。
Flushing(刷盘)
Flushing 是 ingester 将时序数据从内存卸载(offload)并写入长期存储的操作。它是 Mimir 写入路径上"内存 → 对象存储"的关键转换环节。
与 Flushing 相关的配置集中在 pkg/storage/tsdb/config.go 的 TSDBConfig 中:
blocks-storage.tsdb.head-compaction-idle-timeout(默认1h):TSDB head 闲置该时长后触发压缩(compaction),并附加最多 25% 的抖动以避免所有 ingester 同时压缩;blocks-storage.tsdb.flush-blocks-on-shutdown(默认false):关闭时是否将未完成的 block 刷到存储;若为false,重启后会复用未完成的 block 而非立即上传;blocks-storage.tsdb.wal-compression-enabled(默认false):是否对 TSDB WAL 进行压缩(详见 WAL 一节)。
在 pkg/ingester/ingester.go 中,ingester 的 lifecycler 会携带cfg.BlocksStorageConfig.TSDB.FlushBlocksOnShutdown与i.Flush回调,从而在实例退出时协调刷盘动作,保证数据不丢失。
Gossip(流言协议)
Gossip 是一种让组件之间无需集中式 key-value store 即可协调的协议。在 Mimir 中,Gossip 被用于:
- 集群成员管理;
- 节点故障检测;
- hash ring 状态在节点间的传播。
Mimir 使用的 Gossip 协议具体实现是Memberlist(见下节),它允许在不部署 Consul/etcd 的情况下,仅凭节点间相互通信维护一致的集群状态视图,这对单二进制部署尤其友好。
HA tracker(高可用跟踪器)
HA tracker 是 Grafana Mimir distributor 的一项功能,用于对两台及以上、配置为抓取相同目标的 Prometheus 服务器所上报的时序进行去重。它是 Prometheus 高可用(HA)双写场景的核心组件。
HA tracker 的实现位于 pkg/distributor/ha_tracker.go,关键配置与行为:
- 通过
distributor.ha-tracker.enable(对应HATrackerConfig.EnableHATracker)启用; - 需要 Prometheus 端附加 HA 专用标签(cluster 与 replica);
- 集群内部通过选举(election)决定当前接受哪个 replica 的样本,其他 replica 的样本被丢弃;
- 选出的 replica 状态通过
elected_replica_status等指标对外暴露,其中enable-elected-replica-metric默认关闭以避免高基数指标(见 pkg/distributor/ha_tracker.go 中EnableElectedReplicaMetric的注释)。
值得注意的默认值:HA tracker 的 KVStore 后端在未显式配置时默认设置为memberlist(见HATrackerConfig.RegisterFlags中 "Set the default to memberlist before registering flags" 的注释),支持的取值包括 consul、etcd、inmemory、memberlist、multi,其中 memberlist 为官方推荐。
Hash ring(哈希环)
Hash ring 是 Mimir 用于分片(sharding)、复制(replication)与服务发现(service discovery)的分布式数据结构。组件通过 key-value store 或 Gossip 共享 hash ring 状态。
底层机制(依据 vendor/github.com/grafana/dskit/ring 的 dskit ring 实现):
- Token 分配:每个实例在环上认领若干 token(默认通过
RandomTokenGenerator生成,见 basic_lifecycler.go 的注释),token 将环划分为多个区间; - 键到实例映射:对每个数据键(如 series 的 tenant ID 与 label 集合)计算哈希得到 key,再从 key 位置顺时针查找 token,
findInstancesForKey(见 ring.go)依次收集 token 对应的实例形成副本集合; - 复制与容错:
ReplicationStrategy.Filter(见 replication_strategy.go)基于minSuccess = (replicationFactor / 2) + 1的多数派(quorum)要求,过滤心跳超时的病态实例并计算可容忍的最大失败数MaxErrors; - 心跳健康检查:实例通过
BasicLifecycler定期向 KV store 写心跳,读侧用HeartbeatTimeout判定实例是否健康; - 区域感知(zone awareness):启用后,副本集合会尽量跨不同可用区(availability zone)分布,
findInstancesForKey中按 zone 跟踪已查找/已命中实例数(见 ring.go); - 分片减容(Shuffle sharding):
ShuffleShard(见 ring.go)为每个租户从完整环中挑选固定大小的子环,减少故障爆炸半径。
写入路径上,distributor 对每条 series 计算tokenForLabels(userID, labels)(见 pkg/distributor/distributor.go),通过 hash ring 确定由哪些 ingester 接收该 series。
Key-value store(键值存储)
Key-value store 是一种将键与值关联的数据库。在 Mimir 中,它是 hash ring 状态与 HA tracker 选举状态的共享后端,支持 consul、etcd、inmemory、memberlist、multi 等后端(multi 表示多个后端组合)。
选择要点:
- memberlist:去中心化,基于 Gossip,无需额外基础设施,适合中小规模与单二进制部署;
- consul / etcd:集中式 KV store,适合大规模集群或已有此类基础设施的环境。
成员管理与 Gossip 协议的具体实现来自 dskit 库的 vendor/github.com/grafana/dskit/kv/memberlist,其中KVInitService(见 kv_init_service.go)负责在首次调用时初始化并启动 memberlist KV,若 KV 服务失败会将错误上报给上层服务管理框架。
Memberlist
Memberlist 使用 Gossip 管理集群成员关系与成员故障检测。它源自 HashiCorp 的 memberlist 库,被 dskit 封装为可承载 KV 数据的广播与合并机制(见 vendor/github.com/grafana/dskit/kv/memberlist/memberlist_client.go 与 broadcast.go)。
在 Mimir 中,memberlist 承担两类角色:
- KV 后端:作为 hash ring、HA tracker 等共享状态的存储与传播通道;
- 集群通信层:节点间通过 TCP/UDP 相互探测存活状态,当节点加入或离开时,其他节点通过 Gossip 在秒级内感知变化。
Mimir 的成员管理配置集中在-memberlist.*前缀下(见 pkg/mimir/mimir.go 中的默认值,如memberlist.packet-dial-timeout: 500ms、memberlist.max-concurrent-writes: 5等),单二进制多实例部署可直接借助 memberlist 完成自动发现,无需额外依赖。
Org / User / Tenant
Org(Organisation)与 User 均指代同一个概念:Tenant(租户)。在 Mimir 中,tenant 与 Prometheus/Cortex 生态中的 "Org"、"User" 是历史命名差异,语义完全相同。
Ring
Ring 即 Hash ring,详见上文"Hash ring"小节。
Sample(样本)
Sample 是时间序列中单个带时间戳的值。以官方术语表给出的序列node_cpu_seconds_total{instance="10.0.0.1",mode="system"}为例,其样本流可能如下:
# Display format: <value> @<timestamp> 11775 @1603812134 11790 @1603812149 11805 @1603812164 11819 @1603812179 11834 @1603812194每个样本由一个值(如11775)和一个 Unix 秒级时间戳(如1603812134)构成,是 Mimir 存储与查询处理的最小数据单元。
Series(序列)
Series 是隶属于同一指标(metric)、且具有相同标签键值对集合的样本流。给定单一指标node_cpu_seconds_total,可以存在多条 series,每条 series 由指标名与唯一标签组合唯一标识:
node_cpu_seconds_total{instance="10.0.0.1",mode="system"} node_cpu_seconds_total{instance="10.0.0.1",mode="user"} node_cpu_seconds_total{instance="10.0.0.2",mode="system"} node_cpu_seconds_total{instance="10.0.0.2",mode="user"}series 是 Mimir 中标签索引、分片(sharding)、去重(deduplication)与计费(cost attribution)的基本单位。Mimir 的连续测试(continuous test)模块会在运行时写入并查询固定 series 集合以验证端到端正确性,相关实现见 pkg/continuoustest。
Tenant(租户)
Tenant 是写入并查询 Mimir 的一组 series 的所有者。Mimir 对不同租户的 series 与告警进行隔离。多租户是 Mimir 的核心能力之一:
- 数据隔离:每个租户的数据在存储桶中以租户 ID 为前缀分目录存放;
- 限流与配额:每个租户可配置独立的 series 数量上限、活跃 series 上限、查询超时等限制(见 pkg/util/validation 与 overrides exporter 的 per-tenant 指标导出逻辑);
- 认证授权:租户通过请求中的身份信息(如
X-Scope-OrgID头部或认证中间件)被识别,Mimir 的 tenant 解析逻辑见 pkg/util/tenant(含tenant.TenantIDs等辅助函数)。
Time series(时间序列)
Time series 即 Series,二者等价,详见上文"Series"小节。
Write-ahead log(WAL,预写日志)
WAL 是 ingester 存储在磁盘上的追加式(append-only)日志,用于在进程重启后恢复其内存状态。它的设计目标与 Prometheus TSDB WAL 一致:
- 写入路径先把样本追加到 WAL,再更新内存中的 TSDB head;
- 若 ingester 进程崩溃或重启,内存数据丢失后通过回放(replay)WAL 恢复;
- WAL 中的记录可压缩(
blocks-storage.tsdb.wal-compression-enabled,默认false),以减少磁盘占用与回放开销。
相关源码佐证:
- ingester 启动路径中明确"在回放 WAL 期间不施加内存 series 限制",见 pkg/ingester/ingester_http.go 的注释;
- WAL 回放并发度是可测试的配置行为,测试用例见 pkg/ingester/ingester_test.go 中
expectedTSDBWALReplayConcurrency相关断言; - 因此,"重启不丢已确认数据"的持久性保障由 WAL + Flushing(落块)共同承担。
术语关系速查
| 术语 | 关联关系 |
|---|---|
| Org / User | → Tenant |
| Ring | → Hash ring |
| Time series | → Series |
| Memberlist | 基于 Gossip,可充当 Key-value store 后端 |
| Hash ring | 依赖 Key-value store 或 Gossip 共享状态 |
| HA tracker | 依赖 Key-value store(推荐 memberlist)记录选举状态 |
| Block / Chunk | Chunk 属于 Block 内部更细粒度的数据组织单元 |
结语
这份术语表覆盖了 Mimir 从数据模型(Sample/Series/Chunk/Block)、写入与持久化(WAL/Flushing)、分布式协调(Hash ring/Key-value store/Gossip/Memberlist)到多租户(Tenant)与高可用(HA tracker)的完整技术栈。建议读者在阅读架构文档、编写配置或排查告警时,随时回到本文核对术语含义;结合上文给出的源码与配置路径,可以进一步深入 Mimir 的实现细节。相关概念在官方文档体系中的完整阐述,可从 docs/sources/mimir/references/glossary.md 出发继续查阅对应的架构专题文档。
- 时序数据库
- 后端
- 数据存储
- 可观测性
- 云原生
【免费下载链接】mimir
Grafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.
相关推荐
Cortex 术语表深度解读:Series、Hash Ring、WAL 等核心概念与源码印证
Cortex 术语表深度解读:Series、Hash Ring、WAL 等核心概念与源码印证 导读 :Cortex 是一个水平可扩展、高可用、多租户的长期 Pr
可观测性时序数据库后端指标监控dep 术语表精讲:Atom、Deduction、Solver 与 Sync 等核心概念全解析
dep 术语表精讲:Atom、Deduction、Solver 与 Sync 等核心概念全解析 本篇技术指南以 dep(Go dependency manage
EASTL 术语表解析:深入理解EASTL核心概念
EASTL 术语表解析:深入理解EASTL核心概念 前言 EASTL(Electronic Arts Standard Template Library)是游戏
开发工具
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考