☰
Grafana Mimir 对象存储 Block 清单工具 listblocks(mimirtool blocks list)实战指南
2026/10/13 1:47:38 网站建设 项目流程
  • 时序数据库
  • 后端
  • 数据存储
  • 可观测性
  • 云原生

【免费下载链接】mimir

Grafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.

项目地址:https://gitcode.com/gh_mirrors/mimir/mimir
点击查看免费下载

本指南系统讲解 Grafana Mimir 仓库内置的listblocks工具——它作为mimirtool blocks list子命令实现,用于列出并展示指定租户(tenant)在对象存储中的 TSDB block 信息。你将掌握全部命令行参数、tabbed/json/yaml三种输出格式、GCS/Azure/S3 等后端配置方式,并从源码层面理解 block 元数据、deletion-mark / no-compact-mark 标记文件与并发读取等底层实现原理,可直接用于日常存储巡检、block 排查与运维脚本编写。

1. 工具定位:listblocks 是什么

listblocks是 Grafana Mimir 提供的一个对象存储巡检工具,作用是显示对象存储中某个租户所属 block 的元数据信息,包括 block ID、起止时间范围、时长、压缩级别、来源、标签、统计量(series/chunks/samples)、块大小等。

从仓库源码看,它并未作为独立二进制发布,而是注册在mimirtool的blocks命令族之下。pkg/mimirtool/commands/blocks.go中BlocksCommand注册了五个子命令:

  • list:列出并展示 block 详情(即本文主题 listblocks)
  • mark:给 block 打标记
  • copy:复制 block
  • split:拆分 block
  • undelete:撤销删除标记

因此命令行形态为mimirtool blocks list [flags],对应文档标题中的listblocks即该子命令背后的核心逻辑。

2. 命令行参数详解

list命令的所有 flag 在源码 pkg/mimirtool/commands/blocks/list/list.go 中注册,与原文档保持一致并补充了更精确的语义说明。

2.1 核心参数

参数必填默认值说明
--user是—要列出 block 的用户(租户)ID,缺失时命令直接报错no user specified(见Validate())
--format否tabbed输出格式,必须为tabbed、json、yaml三者之一,非法值报错an invalid format was specified
--show-deleted否false同时展示标记了删除(deletion-mark)的 block
--show-labels否false展示 block 的外部标签(external labels)
--show-ulid-time否false展示从 block ULID 中解析出的创建时间
--show-sources否false展示该 block 的压缩来源(compaction sources)
--show-parents否false展示父 block(parents,即压缩前的源 block ULID 列表)
--show-compaction-level否false展示压缩级别(compaction level)
--show-block-size否false根据meta.json中的文件明细计算并展示 block 大小(可用时)
--show-stats否false展示 block 统计量:series、chunks、samples 数量
--split-count否0非 0 时输出 split number,用于判断 split compaction 时 block 会归入哪个分片组
--min-time否未设置仅打印minTime >= 该值的 block
--max-time否未设置仅打印maxTime <= 该值的 block
--use-ulid-time-for-min-time-check否false为 true 时,ULID 时间早于--min-time的 block 不加载其meta.json,可大幅减少对象读取,但可能漏掉含未来时间戳数据的 block

补充:源码中还有一个文档未提及的--show-hints(展示压缩 hints),以及对象存储后端通用参数(见第 4 节)。源码注册的完整 flag 集合以 list.go 为准。

2.2 关键参数的行为细节

--split-count与--show-stats等:这些开关不仅控制"是否打印列",还控制输出内容。从 buildBlocksList 的实现看:

  • 仅当--split-count > 0时,输出splitID = HashBlockID(blockULID) % splitCount;
  • 仅当--show-ulid-time时,输出ulidTime;
  • 仅当--show-deleted时,输出deletionTime(由 deletion-mark 文件中的deletion_time转换而来);
  • 仅当--show-stats时,输出numSeries、numSamples、numChunks;
  • minTime、maxTime、duration、durationSeconds是无条件输出的基础字段。

--min-time/--max-time过滤:过滤在内存中完成——所有已加载的meta.json都会先读入,再按 block 的minTime/maxTime(毫秒时间戳)与过滤值比较决定是否输出(list.go)。因此这两个参数节省的是输出量而非读取量。

--use-ulid-time-for-min-time-check优化:该开关让过滤前置到"读取阶段"。在 pkg/util/listblocks/listblocks.go 的LoadMetaFilesAndMarkers中,遍历租户目录时如果ulidMinTime非零且block ULID 时间 < ulidMinTime,则直接跳过该 block 目录,不再读取其meta.json。由于 ULID 时间通常接近数据写入时间、且可能早于block 实际包含的数据时间范围(例如写入了未来时间戳的数据),所以文档明确警告:开启后"可能错误地跳过某些 block"。

3. 三种输出格式

默认tabbed格式面向人工阅读,无需借助其他工具;json与yaml格式便于机器解析,可配合jq/yq等工具做脚本化处理。三种格式输出的字段集合相同,仅呈现方式不同。

3.1 tabbed(默认)

Block ID Min Time Max Time Duration No Compact Size 01HRB9NDFKKYM8CKGPBEY0E8QX 2024-03-06T00:00:00Z 2024-03-07T00:00:00Z 24h0m0s [Time: 2025-04-10T19:48:56Z Reason: manual] 687 MiB 01HRDWWNZQCH1MWCWKK4VMW08R 2024-03-07T00:00:00Z 2024-03-08T00:00:00Z 24h0m0s 688 MiB

输出由 Go 标准库text/tabwriter对齐(printTabbedOutput)。表头与数据行会依据启用的开关动态增删列:例如启用--split-count会增加Split ID列,启用--show-ulid-time增加ULID Time列,启用--show-deleted增加Deletion Time列,启用--show-stats增加Series/Samples/Chunks列,--show-labels/--show-sources/--show-parents/--show-hints分别追加对应列。No Compact列仅在 block 存在no-compact-mark.json时打印[Time: ... Reason: ...],否则留空。

3.2 json(为便于阅读此处做了美化缩进)

[ { "blockID": "01HRB9NDFKKYM8CKGPBEY0E8QX", "duration": "24h0m0s", "durationSeconds": 86400, "maxTime": "2024-03-07T00:00:00Z", "minTime": "2024-03-06T00:00:00Z", "noCompact": { "time": "2025-04-10T19:48:56Z", "reason": "manual" }, "size": "687 MiB", "sizeBytes": 720756845 }, { "blockID": "01HRDWWNZQCH1MWCWKK4VMW08R", "duration": "24h0m0s", "durationSeconds": 86400, "maxTime": "2024-03-08T00:00:00Z", "minTime": "2024-03-07T00:00:00Z", "size": "688 MiB", "sizeBytes": 721221809 } ]

3.3 yaml

- blockID: 01HRB9NDFKKYM8CKGPBEY0E8QX duration: 24h0m0s durationSeconds: 86400 maxTime: "2024-03-07T00:00:00Z" minTime: "2024-03-06T00:00:00Z" noCompact: time: "2025-04-10T19:48:56Z" reason: manual size: 687 MiB sizeBytes: 720756845 - blockID: 01HRDWWNZQCH1MWCWKK4VMW08R duration: 24h0m0s durationSeconds: 86400 maxTime: "2024-03-08T00:00:00Z" minTime: "2024-03-07T00:00:00Z" size: 688 MiB sizeBytes: 721221809

几点字段语义说明:

  • duration为人类可读时长(如24h0m0s),durationSeconds为向下取整的秒数;
  • noCompact字段仅在存在 no-compact 标记时出现,内含标记时间与reason;
  • size与sizeBytes仅在启用--show-block-size时出现,数值来自meta.json中thanos.files各文件字节数之和(GetBlockSizeBytes,见 pkg/util/listblocks/listblocks.go),以 1024 为基的humanize.IBytes格式输出;
  • 启用--show-stats时额外出现numSeries/numSamples/numChunks,启用--show-labels时出现labels(map 形式),启用--show-sources时出现sources(ULID 数组),启用--show-parents时出现parents(父 block ULID 数组)。

4. 构建与运行:多对象存储后端示例

4.1 构建 mimirtool

list是 mimirtool 的子命令。在 Mimir 仓库根目录执行:

go build ./cmd/mimirtool

也可以直接使用 Mimir 官方 release 提供的预编译二进制。构建完成后得到mimirtool可执行文件,即可按下面的示例调用。

4.2 后端通用参数

除list自身参数外,每个受支持的对象存储后端还会注入一批以--backend及相关前缀开头的通用参数。这些参数由bucket.Config.RegisterFlags(见 pkg/storage/bucket/client.go)及各后端自身的 flag 注册逻辑(S3 见 pkg/storage/bucket/s3/config.go)注册。核心通用项包括:

  • --backend:选择后端,如s3、gcs、azure、swift、filesystem;
  • --storage-prefix:所有对象在存储中的公共前缀(仅允许数字与英文字母),Mimir 各组件写入对象时配置了该前缀,则巡检时也需保持一致。

4.3 Google Cloud Storage(GCS)

mimirtool blocks list \ --user <user> \ --backend gcs \ --gcs.bucket-name <bucket name> \

4.4 Azure Blob Storage

mimirtool blocks list \ --user <user> \ --backend azure \ --azure.container-name <container name> \ --azure.account-name <account name> \ --azure.account-key <account key> \

4.5 Amazon S3(含兼容服务)

mimirtool blocks list \ --user <user> \ --backend s3 \ --s3.bucket-name <bucket name> \ --s3.access-key-id <access key id> \ --s3.secret-access-key <secret access key> \ --s3.endpoint <endpoint> \

补充说明(源码依据见 pkg/storage/bucket/s3/config.go):

  • --s3.endpoint既可以是 AWS S3 官方端点,也可以是 S3 兼容服务(如 MinIO)的hostname:port地址;
  • 若使用本地/S3 兼容测试环境,可加--s3.insecure以http://访问端点;
  • --s3.region未设置时客户端会发起GetBucketLocation自动探测;
  • 支持--s3.native-aws-auth-enabled走 AWS SDK 默认凭据链,以及--s3.session-token临时凭证、--s3.signature-version签名版本等高级选项。

5. 源码级原理:listblocks 是如何工作的

5.1 整体流程

list子命令的执行入口在 Run:

  1. 校验--user与--format(Validate);
  2. 基于bucket.Config创建对象存储客户端bucket.NewClient;
  3. 调用listblocks.LoadMetaFilesAndMarkers读取租户目录下的全部meta.json与标记文件;
  4. 调用buildBlocksList组装字段(过滤、开关判断、格式化);
  5. 按--format分别走printTabbedOutput(tabwriter)或json.Marshal/yaml.Marshal输出。

5.2 元数据与标记文件读取

核心读取逻辑在LoadMetaFilesAndMarkers(pkg/util/listblocks/listblocks.go):

  • 先扫描<user>/markers/目录,识别deletion-mark.json与no-compact-mark.json文件(listMarkerFiles);
  • 再迭代租户根目录,用block.IsBlockDir识别 block 目录,跳过已标记删除(除非--show-deleted)和 ULID 时间早于--min-time(仅当开启--use-ulid-time-for-min-time-check)的目录;
  • 标记文件与meta.json的读取均通过concurrency.ForEachJob以并发度上限 32执行(concurrencyLimit = 32),对象不存在(IsObjNotFoundErr)时静默跳过。

两个标记文件的 JSON 结构与语义定义在 pkg/storage/tsdb/block/markers.go:

  • DeletionMark:包含id、version、details与deletion_time(Unix 时间戳),表示 block 将在延迟后删除;
  • NoCompactMark:包含id、version、details、no_compact_time与reason,表示 block 被排除在压缩之外。

reason的取值包括manual(人工指定)、block-index-out-of-order-chunk(索引含乱序 chunk)、critical(索引损坏等严重问题)、postings-offset-table-too-large、index-exceeds-64gib、symbol-table-too-large、preemptive(compactor 因接近结构上限而主动标记)。第 3 节示例输出中的Reason: manual即来自这类标记文件。

5.3 排序规则

输出前所有 block 会经过SortBlocks(pkg/util/listblocks/listblocks.go)排序,优先级依次为:

  1. 按minTime升序;
  2. 同minTime时按时长(maxTime - minTime)升序;
  3. 再按 compactor shard 标签(__compactor_shard_id__)排序,先按分片总数、再按分片索引;
  4. 最后按 ULID 时间升序。

该排序逻辑与 compactor 分片/压缩时的处理顺序保持一致,便于肉眼对比 block 之间的时间衔接关系。

5.4 block 大小的计算前提

--show-block-size依赖meta.json中的thanos.files条目(每个文件记录size_bytes)。若某个 block 的meta.json不含文件明细,则size输出为空字符串。因此"size 缺失"不代表 block 不存在,而可能是元数据不完整(如未完成压缩写入的中间状态)。

6. 实战场景示例

6.1 与 jq / yq 组合做脚本化巡检

以 JSON 输出配合jq筛选出某个时间窗口内的 block:

mimirtool blocks list \ --user tenant-a \ --backend s3 \ --s3.bucket-name mimir-tsdb \ --s3.endpoint s3.us-east-1.amazonaws.com \ --format json | jq '.[] | select(.minTime >= "2024-03-01T00:00:00Z" and .maxTime <= "2024-03-08T00:00:00Z")'

6.2 排查压缩异常

同时开启--show-compaction-level、--show-sources、--show-parents,可以看清每个 block 由哪些源 block 压缩而来、当前处于第几级压缩;结合--show-deleted与默认输出的No Compact列,可快速定位被排除压缩或等待删除的 block:

mimirtool blocks list \ --user tenant-a \ --backend gcs \ --gcs.bucket-name mimir-tsdb \ --show-deleted \ --show-compaction-level \ --show-sources \ --show-parents

6.3 大租户下的读取优化

对于 block 数量极大的租户,常规做法(先读全部meta.json再过滤)会产生大量对象读取请求。此时可先按--min-time划定时间窗,并开启--use-ulid-time-for-min-time-check,让工具在遍历目录时直接跳过 ULID 早于窗口的 block,显著降低对象存储请求量。需要谨记该开关可能漏掉"数据时间晚于 ULID"的未来数据 block。

7. 延伸阅读

  • 命令实现:pkg/mimirtool/commands/blocks/list/list.go
  • 读取与排序核心逻辑:pkg/util/listblocks/listblocks.go
  • 标记文件结构与 reason 枚举:pkg/storage/tsdb/block/markers.go
  • 对象存储后端通用配置:pkg/storage/bucket/client.go、pkg/storage/bucket/s3/config.go
  • 命令族注册:blocks下的mark/copy/split/undelete子命令见 pkg/mimirtool/commands/blocks.go
  • 时序数据库
  • 后端
  • 数据存储
  • 可观测性
  • 云原生

【免费下载链接】mimir

Grafana Mimir provides horizontally scalable, highly available, multi-tenant, long-term storage for Prometheus.

项目地址:https://gitcode.com/gh_mirrors/mimir/mimir
点击查看免费下载
上一篇:Ruffle 扩展 3 步安装:Chrome 里 Flash 模拟的白屏自救与掉帧调优
下一篇:Vidi:视频理解和编辑的大规模多模态模型

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询