注意
本文档适用于 Ceph 开发版本。
MDS 日志记录
CephFS元数据池
CephFS使用一个单独的(元数据)池来管理Ceph文件系统中的文件元数据(inode和dentry)。元数据池包含Ceph文件系统中所有文件的信息,包括文件系统层次结构。此外,CephFS还维护与文件系统中其他实体相关的元信息,如文件系统日志、打开文件表、会话映射等。
本文档描述了Ceph元数据服务器如何使用和依赖日志记录。
CephFS MDS日志记录
CephFS元数据服务器在执行文件系统操作之前,将元数据事件日志流式传输到元数据池中的RADOS。活跃的MDS守护进程管理CephFS中文件和目录的元数据。
CephFS使用日志记录的原因有几个:
一致性:在MDS故障转移时,可以重播日志事件以达到一致的文件系统状态。此外,需要多次更新后端存储的元数据操作需要进行日志记录,以实现崩溃一致性(以及其他一致性机制,如锁定等)。
性能:日志更新是(主要是)顺序的,因此更新日志的速度很快。此外,更新可以批量为单个写入,从而节省更新文件不同部分的磁盘寻道时间。拥有一个大的日志也有助于备用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记录的各种事件类型。
EVENT_COMMITTED: 将请求(id)标记为已提交。
EVENT_EXPORT: 将目录映射到MDS等级。
EVENT_FRAGMENT: 跟踪目录碎片化的各个阶段(拆分/合并)。
EVENT_IMPORTSTART: 当MDS等级开始导入目录片段时记录。
EVENT_IMPORTFINISH: 当MDS等级完成导入目录片段时记录。
EVENT_NOOP: 用于跳过日志区域的空操作事件类型。
EVENT_OPEN: 跟踪哪些inode有打开的文件句柄。
EVENT_RESETJOURNAL: 用于将日志标记为reset截断后。
EVENT_SESSION: 跟踪打开的客户端会话。
EVENT_SLAVEUPDATE: 记录已转发到(从属)mds的操作的各个阶段。
EVENT_SUBTREEMAP: 目录inode到目录内容(子树分区)的映射。
EVENT_TABLECLIENT: 记录MDS客户端表视图的转换状态(快照/锚点)。
EVENT_TABLESERVER: 记录MDS服务器表视图的转换状态(快照/锚点)。
EVENT_UPDATE: 记录inode上的文件操作。
EVENT_SEGMENT: 记录新的日志段边界。
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. 如果您想支持这一点和我们的其他工作,请考虑加入现在加入.