注意

本文档适用于 Ceph 开发版本。

MDS 日志记录

CephFS元数据池

CephFS使用一个单独的(元数据)池来管理Ceph文件系统中的文件元数据(inode和dentry)。元数据池包含Ceph文件系统中所有文件的信息,包括文件系统层次结构。此外,CephFS还维护与文件系统中其他实体相关的元信息,如文件系统日志、打开文件表、会话映射等。

本文档描述了Ceph元数据服务器如何使用和依赖日志记录。

CephFS MDS日志记录

CephFS元数据服务器在执行文件系统操作之前,将元数据事件日志流式传输到元数据池中的RADOS。活跃的MDS守护进程管理CephFS中文件和目录的元数据。

CephFS使用日志记录的原因有几个:

  1. 一致性:在MDS故障转移时,可以重播日志事件以达到一致的文件系统状态。此外,需要多次更新后端存储的元数据操作需要进行日志记录,以实现崩溃一致性(以及其他一致性机制,如锁定等)。

  2. 性能:日志更新是(主要是)顺序的,因此更新日志的速度很快。此外,更新可以批量为单个写入,从而节省更新文件不同部分的磁盘寻道时间。拥有一个大的日志也有助于备用MDS预热其缓存,这有助于间接地帮助MDS故障转移。

每个活跃的元数据服务器在元数据池中维护自己的日志。日志分布在多个对象上。元数据服务器会修剪不需要的(被认为是旧的)日志条目。

日志事件

除了日志记录文件系统元数据更新外,CephFS还记录各种其他事件,如客户端会话信息和目录导入/导出状态等。这些事件由元数据服务器用于重新建立所需的状态,例如,当重播日志事件时,Ceph MDS在重新启动时尝试重新连接客户端,当日志中的特定事件类型指定客户端实体类型在与MDS重新启动之前有会话时。

为了检查日志中记录的事件列表,CephFS提供了一个命令行工具cephfs-journal-tool可以按如下方式使用:

cephfs-journal-tool --rank=<fs>:<rank> event get list

cephfs-journal-tool也用于发现和修复损坏的Ceph文件系统。(参见cephfs-journal-tool了解更多细节)

日志事件类型

以下是MDS记录的各种事件类型。

  1. EVENT_COMMITTED: 将请求(id)标记为已提交。

  2. EVENT_EXPORT: 将目录映射到MDS等级。

  3. EVENT_FRAGMENT: 跟踪目录碎片化的各个阶段(拆分/合并)。

  4. EVENT_IMPORTSTART: 当MDS等级开始导入目录片段时记录。

  5. EVENT_IMPORTFINISH: 当MDS等级完成导入目录片段时记录。

  6. EVENT_NOOP: 用于跳过日志区域的空操作事件类型。

  7. EVENT_OPEN: 跟踪哪些inode有打开的文件句柄。

  8. EVENT_RESETJOURNAL: 用于将日志标记为reset截断后。

  9. EVENT_SESSION: 跟踪打开的客户端会话。

  10. EVENT_SLAVEUPDATE: 记录已转发到(从属)mds的操作的各个阶段。

  11. EVENT_SUBTREEMAP: 目录inode到目录内容(子树分区)的映射。

  12. EVENT_TABLECLIENT: 记录MDS客户端表视图的转换状态(快照/锚点)。

  13. EVENT_TABLESERVER: 记录MDS服务器表视图的转换状态(快照/锚点)。

  14. EVENT_UPDATE: 记录inode上的文件操作。

  15. EVENT_SEGMENT: 记录新的日志段边界。

  16. EVENT_LID: 标记没有逻辑子树映射的日志的开始。

日志段

MDS日志由逻辑段组成,代码中称为LogSegments。这些段用于将多个事件收集到的元数据更新合并到一个逻辑单元中,以便进行修剪。每当日志尝试提交元数据操作(例如,将文件创建作为omap更新到dirfrag对象进行刷新)时,它都会在LogSegment的可重播更新批次中这样做。如果MDS在更新各种元数据对象的过程中失败,则必须重播这些更新。更新以批量方式执行的原因是将同一元数据对象(dirfrag)的更新分组在一起,这些更新可能在同一时间段内更新多个omap条目。

一旦段被修剪,它就被认为是“过期的”。一个过期的段有资格被日志记录器删除,因为它的所有更新都已刷新到后端RADOS对象。这是通过更新日志记录器的“过期位置”来实现的,以使其超过过期段的末尾。当MDS重新启动时,一些过期的段可能会保留在日志中,以提高缓存局部性。

在CephFS的大部分历史中(截至2023年),日志段由子树映射ESubtreeMap事件界定。主要原因是在重播任何其他事件之前,必须先有子树映射的副本才能开始日志恢复。

现在,日志段可以由事件界定,这些事件是SegmentBoundary。这包括,ESubtreeMap, EResetJournal, ESegment(2023年),或ELid(2023年)。对于ESegment,这种轻量级的段边界允许MDS更频繁地记录子树映射,同时保持日志段较小以保持修剪事件简短。为了保持第一个事件日志重播看到的是ESubtreeMap的约束,以该事件开头的段被认为是“主要段”,并且对过期段的删除添加了一个新约束:日志的第一段必须始终是一个主要段。

The ELid事件存在以将MDS日志标记为“新”的,其中需要逻辑和日志序列号才能进行其他操作,特别是MDSTable操作。MDS在创建或关闭等级时使用此事件。在从初始状态重播等级时不需要子树映射。LogSegment and log sequence number is required for other operations to proceed, in particular the MDSTable operations. The MDS uses this event when creating a rank or shutting it down. No subtree map is required when replaying the rank from this initial state.

配置

日志段的目标大小按事件数量控制:

mds_log_events_per_segment

MDS日志段中的最大事件数

type:

uint

default:

1024

min:

1

自上次主要段以来,次要mds日志段的数量由:

mds_log_minor_segments_per_major_segment

自上次主要段以来,次要mds日志段的数量,之后开始记录/日志主要段。

type:

uint

default:

16

min:

4

这控制了MDS修剪过期日志段的频率(值越高,MDS越少更新日志过期位置以进行修剪)。

目标最大段数由:

mds_log_max_segments

日志中的最大段数(对象),在我们启动修剪之前。设置为-1以禁用限制。

type:

uint

default:

128

min:

8

由于等待修剪到下一个主要段的非主要段,MDS通常略高于此数字。

由 Ceph 基金会带给您

Ceph 文档是一个社区资源,由非盈利的 Ceph 基金会资助和托管Ceph Foundation. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.