【ceph】CEPH 单活MDS主从切换流程|REPLAY

代码基于ceph nautilus版本

MDS关键概念

想要理解MDS切换过程,首先需要理清一些基本概念。

MDSMAP

  • 包含整个ceph集群的所有mds的状态信息:fs个数、fs名称、各mds状态、数据池、元数据池信息,等等
  • 包含当前的MDS map epoch(纪元),即地图创建的时间,以及它最后一次改变的时间。它还包含用于储存元数据的池,元数据服务器的列表,以及哪些元数据服务器up和in。要查看MDS map,请执行ceph fs dump。

RANK

  • rank定义了多mds直接对元数据负载的划分,每个mds最多只能持有一个rank,每个rank对应一个目录子树,rank id从0开始。
  • Ranks定义了元数据工作负载在 多个元数据服务器守护进程(multiple Metadata Server (MDS) daemons)之间的共享方式。ranks的数量是MDS守护进程的最大数量,可以在同一时间活动。每个MDS守护进程 handles分配给该rank的Ceph文件系统元数据的一个子集(a subset of the Ceph File System metadata。
  • 每个MDS守护程序最初启动时都没有rank。Monitor会给守护进程分配一个rank。一个MDS守护进程在同一时间只能拥有一个rank。守护进程只有在它们被停止时才会失去rank。

这里注意一种特殊情况,即stand-replay状态下的mds也是持有rank的,s且 id和其follow的active mds的rank id相同,如下图所示

MDS JOURNAL

  • cephfs的journal是用于记录元数据事件的日志
  • journal以event形式存放在rados的metadata pool中
  • 在处理每个io行为时,先写journal再执行实际的io操作
  • 每个active mds维护自己的journal
  • journal被分割为多个object
  • mds会修剪(trim)不需要的journal条目
  • journal event 查看:cephfs-journal-tool --rank=<fs>:<rank> event get list

(cephfs-journal-tool — Ceph Documentation  中文:https://www.bookstack.cn/read/ceph-10-zh/8a5dc6d87f084b2a.md)

下面是一个journal event示例(中间还有很多内容被折叠了):

CAPS

即cephfs实现的分布式锁,详见https://docs.ceph.com/docs/master/cephfs/client-auth/

MDS状态机

理解mds的切换首先需要认识清除mds有哪些状态,以及可以进行哪些状态跃迁。有关mds状态机的知识在官网上有详细的介绍:https://docs.ceph.com/docs/master/cephfs/mds-states/

MDS类图

参考下图:注意图中仅列出了mds部分架构和核心类,实际的组成更复杂,涉及的类和逻辑也更多。

冷备OR热备

  • 冷备:默认配置下,除active mds外其余MDS均处于standby状态,除了保持和mon的心跳,其他什么都不做,cache为空,无rank。

  • 热备:配置allow_standby_replay为true,每个active mds都会有一个专属standby-replay mds在follow,持有和active mds相同的rank id,不断从rados中读取journal加载到cache中以尽可能和actvie mds保持同步。

显然在热备状态下会有一个standby-replay的mds一直在更新cache,这样在切换发生时其切换流程会更快。

切换流程分析

首先分析切换过程之前,先明确MDS切换的两个核心思想

  1. 新的active的mds的选举,是由mon来决定的,整个切换过程涉及mon和mds的多次交互
  2. 所有切换过程均是通过mdsmap来驱动的,mdsmap中标记了对当前集群中各mds状态的规划,mds每处理完一个阶段的规划后会主动向mon请求下一个阶段

上文中已介绍了mds的消息分发处理,而在切换流程中,mon和mds的交互都是mdsmap,下面先看一下mdsmap的处理流程:

MDSDaemon::handle_mds_map:

MDSRankDispatcher::handle_mds_map:
逻辑太多,只截取了部分代码

void MDSRankDispatcher::handle_mds_map(
    const MMDSMap::const_ref &m,
    const MDSMap &oldmap)
{
  // I am only to be passed MDSMaps in which I hold a rank
  ceph_assert(whoami != MDS_RANK_NONE);

  // 当前状态为oldstate,从mds map中获取新的状态为state,
  // 如果两者不相等,则更新last_state和incarnation,incarnation表示rank当前在哪个dameon?
  MDSMap::DaemonState oldstate = state;
  mds_gid_t mds_gid = mds_gid_t(monc->get_global_id());
  state = mdsmap->get_state_gid(mds_gid);
  if (state != oldstate) {
    last_state = oldstate;
    incarnation = mdsmap->get_inc_gid(mds_gid);
  }

  version_t epoch = m->get_epoch();

  // note source's map version
  // 当前mds集群状态已经准备变更,进入了新的epoch,那么需要更新其他mds的epoch值
  if (m->get_source().is_mds() &&
      peer_mdsmap_epoch[mds_rank_t(m->get_source().num())] < epoch) {
    dout(15) << " peer " << m->get_source()
	     << &#
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值