Ozone Debug

容器副本调试工具

师成师成· 更新于 2026-09-28· 阅读 13 分钟· 0 次阅读

登录后可跨设备保存划线和私人笔记登录

该工具处理来自 Ozone 数据节点的容器日志文件,以跟踪状态转换。它提供了 CLI 命令,可基于不同属性查询容器。

背景

容器是 Ozone 最重要的部分。Ozone 的大多数操作都在容器上进行。Ozone 中的容器在其生命周期中会经历不同的状态。过去我们遇到过多种与容器状态相关的问题。为了调试问题,我们总是采用手动步骤,针对容器排查问题,这非常耗时。为了优化可调试性,我们可以展示容器的历史时间线及其他相关信息。

解决方案

开发一个离线工具,用于分析 dn-container 日志文件,帮助我们发现集群中各数据节点上与容器相关的问题。

组件 1:解析器

该组件负责处理日志文件、提取相关日志条目,并以批量方式存储,以便插入数据库。

命令如下:

ozone debug log container --db=<path to db> parse --path=<path to logs folder> --thread-count=<n>

日志文件解析与校验

  • 目录遍历:工具会递归扫描指定目录下的容器日志文件,只有文件名符合 dn-container-<roll>.log.<datanodeId> 模式的文件才会被处理。日志文件会使用多个线程并发解析,以提高处理效率。

  • 逐行处理:每条日志行以竖线分隔符进行拆分,并解析为键值对组件。

  • 字段提取:关键字段包括:

    • 时间戳
    • logLevel:INFO、WARN、ERROR。
    • ID、BCSID、State 和 Index:从键值对中提取。
  • 错误信息捕获:日志行中剩余的非结构化部分会存储为 errorMessage,这在 WARN 或 ERROR 级别的日志中尤为重要。

  • 副本索引过滤:仅处理 Index = 0 的日志条目。这使得当前处理仅限于基于 Ratis 复制的容器。后续改进可能会支持 EC 复制。

组件二:数据库

该工具使用临时 SQLite 数据库存储和管理从容器日志中提取的信息。这有助于组织数据,从而方便地分析 Datanode 上每个容器副本的完整历史和最新状态。

工具创建/维护的 2 个主要表

  1. DatanodeContainerLogTable —— 详细日志历史
    该表存储每个 Datanode 上每个容器副本的状态变更完整历史记录。

    • 容器 ID
    • Datanode ID
    • 状态(如 OPEN、CLOSED 等)
    • BCSID(块提交序列 ID)
    • 时间戳
    • 日志级别
    • 错误信息(如有)
    • Index 值

    该表中的数据展示了状态转换和 BCSID 变更的完整时间线,有助于追踪每个容器副本随时间演变的过程。

  2. ContainerLogTable —— 最新状态摘要
    该表仅包含每个唯一容器与 Datanode 组合的最新状态和 BCSID。

    • 容器 ID
    • Datanode ID
    • 最新状态
    • 最新 BCSID

    该表提供了所有容器副本当前状态和 BCSID 的简化视图,便于快速检查状态和生成摘要。

组件三:CLI 命令

列出存在重复 OPEN 状态的容器

此 Ozone debug CLI 命令通过跟踪前三个 "OPEN" 状态,帮助识别被打开次数超过要求数量(Ratis 要求为 3)的容器。如果在初始事件之后,在同一 Datanode 或不同的 Datanode 上再次出现 "OPEN" 状态,该命令会将其标记为异常。

该命令会显示列出的每个容器的容器 ID 以及处于 'OPEN' 状态的副本数量,同时还会提供存在重复 'OPEN' 状态条目的容器总数。

命令如下:

ozone debug log container --db=<path to db> duplicate-open

示例输出:

Container ID: 2187256 - OPEN state count: 4
.
.
.
Container ID: 12377064 - OPEN state count: 5
Container ID: 12377223 - OPEN state count: 5
Container ID: 12377631 - OPEN state count: 4
Container ID: 12377904 - OPEN state count: 5
Container ID: 12378161 - OPEN state count: 4
Container ID: 12378352 - OPEN state count: 5
Container ID: 12378789 - OPEN state count: 5
Container ID: 12379337 - OPEN state count: 5
Container ID: 12379489 - OPEN state count: 5
Container ID: 12380526 - OPEN state count: 5
Container ID: 12380898 - OPEN state count: 5
Container ID: 12642718 - OPEN state count: 4
Container ID: 12644806 - OPEN state count: 4
Total containers that might have duplicate OPEN state : 1579

显示单个容器的详细信息及分析结果

此 Ozone debug CLI 命令会提供通过命令传入的容器 ID 所对应容器的每个副本的完整状态转换历史。该命令还会对该容器进行分析,例如检测容器是否存在以下问题:

  • 重复的 OPEN 状态
  • 副本数不匹配
  • 副本数不足或副本数过多
  • 不健康的副本
  • Open-unhealthy(打开但不健康)
  • Quasi-closed 状态卡住的容器

该命令会提供以下关键详细信息:

  • 数据节点 ID
  • 容器 ID
  • BCSID(块提交序列 ID)
  • 时间戳
  • 索引值
  • 消息(如果该副本关联了相应消息)

命令格式如下:

ozone debug log container --db=<path to database> info <containerID>

示例输出:

Timestamp               | Container ID | Datanode ID | Container State  | BCSID   | Message             | Index Value
----------------------------------------------------------------------------------------------------------------------
2024-06-04 15:07:55,390 | 700          | 100         | QUASI_CLOSED     | 353807 | No error             | 0
2024-06-04 14:50:18,177 | 700          | 150         | QUASI_CLOSED     | 353807 | No error             | 0
2024-04-04 10:32:29,026 | 700          | 250         | OPEN             | 0      | No error             | 0
2024-06-04 14:44:28,126 | 700          | 250         | CLOSING          | 353807 | No error             | 0
2024-06-04 14:47:59,893 | 700          | 250         | QUASI_CLOSED     | 353807 | Ratis group removed  | 0
2024-06-04 14:50:17,038 | 700          | 250         | QUASI_CLOSED     | 353807 | No error             | 0
2024-06-04 14:50:18,184 | 700          | 250         | QUASI_CLOSED     | 353807 | No error             | 0
2024-04-04 10:32:29,026 | 700          | 400         | OPEN             | 0      | No error             | 0
Container 700 might be QUASI_CLOSED_STUCK.

按健康状态列出容器

此 Ozone debug CLI 命令列出所有处于 UNDER-REPLICATED(副本不足)、OVER-REPLICATED(副本过多)、UNHEALTHY(不健康)或 QUASI_CLOSED 卡住状态的容器。

此命令会显示 容器 ID 以及每个列出的容器在指定健康状态下的副本数量。

所使用的命令选项:

  • 按健康类型列出容器:此选项默认仅在结果中提供 100 行数据
ozone debug log container --db=<path to db> list --health=<type>
  • 按健康类型列出容器,并指定返回的行数上限:
ozone debug log container --db=<path to db> list --health=<type>  --length=<limit>
  • 按健康状态类型列出所有容器,并覆盖行数限制:
ozone debug log container --db=<path to db> list --health=<type>  --all

示例输出:

ozone debug log container --db=path/to/db list --health=UNHEALTHY --all
Container ID = 6002 - Count = 1
Container ID = 6201 - Count = 1
.
.
.
Container ID = 136662 - Count = 3
Container ID = 136837 - Count = 3
Container ID = 199954 - Count = 3
Container ID = 237747 - Count = 3
Container ID = 2579099 - Count = 1
Container ID = 2626888 - Count = 1
Container ID = 2627711 - Count = 1
Container ID = 2627751 - Count = 2
Number of containers listed: 25085

根据最终状态列出容器

此 Ozone debug CLI 命令用于列出所有以 CLI 命令中指定的状态作为其最新状态的容器的副本。

该命令提供以下关键信息:

  • Datanode id
  • Container id
  • BCSID
  • TimeStamp —— 与该容器副本状态关联的最近时间戳
  • Index Value
  • Message(如果该特定副本有关联信息)

所使用的命令选项:

  • 按状态列出容器:默认情况下,结果中仅提供 100 行
ozone debug log container --db=<path to db> list --lifecycle=<state>
  • 按状态列出容器,并指定行数上限:
ozone debug log container --db=<path to db> list --lifecycle=<state> --length=<limit>
  • 按状态列出所有容器,并覆盖行数限制:
ozone debug log container --db=<path to db> list --lifecycle=<state> --all

示例输出:

ozone debug log container --db=path/to/db list --lifecycle=CLOSED --all
Timestamp                 | Datanode ID | Container ID | BCSID  | Message        | Index Value
---------------------------------------------------------------------------------------------------
2024-07-23 12:02:12,981   | 360         | 1            | 75654  | No error       | 0
2024-07-23 11:56:21,106   | 365         | 1            | 75654  | Volume failure | 0
2024-07-23 11:56:21,106   | 365         | 1            | 75654  | Volume failure | 0
2024-08-29 14:11:32,879   | 415         | 1            | 30     | No error       | 0
2024-08-29 14:11:17,533   | 430         | 1            | 30     | No error       | 0
2024-06-20 11:50:09,496   | 460         | 1            | 75654  | No error       | 0
2024-07-23 12:02:11,633   | 500         | 1            | 75654  | No error       | 0
2024-06-20 12:03:24,230   | 505         | 2            | 83751  | No error       | 0
2024-07-10 04:00:33,131   | 540         | 2            | 83751  | No error       | 0
2024-07-10 04:00:46,825   | 595         | 2            | 83751  | No error       | 0

注意

  • 本工具假定所有 dn-container 日志文件已经从 DataNode 中提取出来,并放入了某个目录。
  • 对于解析命令,如果未提供 DB 路径,则会在当前工作目录下创建一个新的数据库文件,默认文件名为 container_datanode.db。
  • 对于所有其他命令,如果未提供 DB 路径,则会在当前目录下查找默认的数据库文件(container_datanode.db)。如果该文件不存在,则会抛出错误,要求提供有效的路径。

评论

登录后参与评论

正在加载评论…