0%

cephfs学习笔记

  • Cephfs学习笔记

什么是Cephfs

  • Cephfs所在的位置
    • 下面给出了文件系统存储区别于块存储的结构区别
      用户可以在块设备上创建xfs文件系统,也可以创建ext4等其他文件系统。如上图,Ceph集群实现了自己的文件系统来组织管理集群的存储空间,用户可以直接将Ceph集群的文件系统挂载到用户机上使用。
  • Cephfs存储方式的优势
    • 之前介绍了cephfs相比于使用rbd的块存储方式的区别,相比于rbd块存储,cephfs对于共享性有着更好的支持
    • 对于Ceph的文件系统接口,如上图,文件系统的结构状态是维护在远端Ceph集群中的,Ceph文件系统同时挂载到了用户机1和用户机2,当往用户机1的挂载点写入数据后,远端Ceph集群中的文件系统状态结构随之更新,当从用户机2的挂载点访问数据时会去远端Ceph集群取数据,由于远端Ceph集群已更新,所有用户机2能够获取最新的数据。

Cephfs的mds

  • mds状态
    mds在ceph系统正常运行时会有几种状态,下面介绍这几种常见的状态:

    • up:activate
      这个状态代表了现在的mds处在工作状态并且正在被文件系统使用
    • up:standby
      这个状态代表了现在的mds处在灾备状态但是作为备用的mds
    • up:standby_replay
      当一个up:activate的节点发生了fail,有一个standby_replay的mds节点replay实时日志,这样它就有元数据的热缓存,在负责这个 rank 的守护进程失效时,会帮助standby节点更快的接管activate节点。注意到这个状态的mds节点不能用来接管任何一个发生fail的activate节点,只能记录它对应activate的mds节点。一个rank只能够有一个standby_replay节点。

    以下的状态基本上是不常见的或者是中间状态:

    • up:boot
      这个状态基本上是不可见的,因为monitor会很快就把MDS设置为对应的状态
    • up:creating
      这个状态表示mds正在构建一些pre-rank元数据并且进入mds集群来创建一个新的rank
    • up:starting
      这个状态表示了mds正在重启一个被停止了的rank,这会打开关联的per-rank元数据并进入mds集群
    • up:stopping
      当一个rank被停止,monitor会指挥activate状态的目的是节点进入up:stopping状态。这个状态mds不会接受任何新的客户端连接请求,把所有的子树迁移到其他的rank中去,清空自己的元数据日志,如果是自己是rank0,就会直接中断所有的客户端连接并关机。
    • up:replay
      这个状态代表现在的mds正在接管fail的节点,修复日志和元数据
    • up:resolve
      mds在up:replay状态时由于cephfs有多种ranks才进入这种状态,这个mds会处理所有没有提交的MDS间操作。文件系统之中必须所有的等级都处于这个状态才能继续操作。如果发生no rank可能会发生fail从而导致up:replay
    • up:reconnect
      MDS 从up:replay或进入此状态up:resolve。此状态是请求来自客户端的重新连接。任何与 thisrank 有会话的客户端都必须在此期间重新连接,可通过mds_reconnect_timeout.
    • up:rejoin
      MDS 从up:reconnect进入此状态。在这种状态下,MDS 正在重新加入 MDS 集群缓存。特别是,重新建立元数据上的所有 MDS 间锁定。如果没有已知的客户端请求被重放,MDS 直接从这个状态变为up:active。
  • mds主从切换流程

    1. 用户手动发起主从切换fail。
    2. active mds手动信号,发起respawn重启。
    3. standby mds收到信号,经过分布式算法推选为新主active mds。
    4. 新主active mds 从up:boot状态,变成up:replay状态。日志恢复阶段,他将日内容读入内存后,在内存中进行回放操作。
    5. 新主active mds 从up:replay状态,变成up:reconnect状态。恢复的mds需要与之前的客户端重新建立连接,并且需要查询之前客户端发布的文件句柄,重新在mds的缓存中创建一致性功能和锁的状态。
    6. 新主active mds从up:reconnect状态,变成up:rejoin状态。把客户端的inode加载到mds cache。(耗时最多的地方)
    7. 新主active mds从up:rejoin状态,变成up:active状态。mds状态变成正常可用的状态。
    8. recovery_done 迁移完毕。
    9. active_start 正常可用状态启动,mdcache加载相应的信息
  • mds核心组件分析

    • MDSDaemon(MDS守护线程)
      1. Beacon:是mds向monitor的心跳组件,如果mds发送的心跳信号没有从monitor端收到回应,就说明网络通信出现了问题,mds会建立一个消息队列等待所有消息被处理
      2. Messenger:mds的网络通信组件
      3. MonClient:连接monitor的组件
      4. MDSMap:用来处理MDSMap的组件
      5. Objecter:连接osd的组件
      6. MDSRank:MDS的核心组件
      7. MDSRankDispatcher:mds的核心组件
  • mds源码分析

    ceph_mds.cc

    • 该文件位于/src目录下,里面的main函数包括了mds的工作流程
      1. 首先创建守护进程,创建一个messenger实例来处理消息,绑定需要连接的client的地址和端口号。
      2. 获取monitor map, 启动mds,messenger消息队列等待,当mds彻底关闭之后消息队列关闭

        MDSDaemon.h && MDSDaemon.cc

    • 该文件位于/src/mds目录下,里面包括了mds守护进程怎么启动以及mds怎么从一个standby状态被分配到mds集群中
      • int MDSDaemon::init():这个函数包括了初始化Monclient,初始化mgrclient,初始化SaftTimer,初始化Beacon,重置tick等等
      • bool MDSDaemon::ms_dispatch(Message *m):这个函数专门用来处理各种消息。如果mds处于shutdown状态,不处理消息,优先处理daemon message,如果发现不是核心态消息,重新给rank发送消息
      • bool MDSDaemon::handle_core_message(Message *m):这个函数会被ms_dispatch调用,用来具体处理高优先级的消息(从MON,MDS,OSD发来的消息)
      • void MDSDaemon::ms_handle_accept(Connection *con):连接上accept。
      • void handle_mds_map(const cref_t<MMDSMap> &m); :每一个standby状态下的mds会等待monitors分配一个在mds集群中的位置,这里实现的过程就是mds会监听并等待接受一个新的mds map,这个函数包括怎么接受一个core message的mds map以及解码一系列操作。最后还会有一系列关于mds状态切换的代码

        MDSRank.h && MDSRank.cc

      • 概念补充:rank是元数据工作负载在多个 MDS ( ceph-mds ) 守护进程之间共享的方式。ranks是一次可能处于活动状态的 MDS 守护进程的最大数量。每个 MDS 处理分配给该等级的文件系统元数据的子集。每个 MDS 守护进程最初都没有等级。
      • void MDSRankDispatcher::init():初始化,从配置文件中读取log配置以及更新log配置,并创建log。处最后创建progressthread进程。
      • void MDSRankDispatcher::tick() :重置heartbeat超时时间,防止因为超时被monitor kill,flush所有的log,唤醒progress_thread进程,根据mdsmap的状态,如果是active或者是stopping状态就周期性,清空cache,client_lease,log等信息,如果是reconnect,replay等状态也调用对应的方法。
      • void MDSRankDispatcher::shutdown():关闭定时器,MDSlog,finisher,mdcache,objecter,monclient回调op_tracker的shutdown回调函数,关闭messenger
      • bool MDSRank::_dispatch(const cref_t<Message> &m, bool new_msg):专门用来处理laggy状态

        FSMap.h && FSMap.cc

      • fsmap类是一个mdsmap类的集合,里面有三个成员:
        1
        2
        3
        fs_cluster_id_t fscid = FS_CLUSTER_ID_NONE;
        MDSMap mds_map;
        MirrorInfo mirror_info;