美文网首页
了解cephfs锁必须要知道的事情

了解cephfs锁必须要知道的事情

作者: 要厉害的 | 来源:发表于2020-03-01 23:28 被阅读0次

    1、本文讨论的锁不是flock。flock是posix标准中对文件某部分偏移加的锁。而这里的锁指的是MDS集中管理多客户端对于文件并发访问时,Dentry和Inode等数据结构控制的锁。每个锁内有parent变量记录的就是该锁相关的Dentry或者Inode。Cephfs采用和GPFS类似的并发更新元文件的方式。同一份元数据分散多个MDS节点,但是有一个Auth节点,该节点负责

    - 串行更新(serializing updates)

    - 将元数据持久化到磁盘上(committing changes to disks)

    - 保证缓存一致性(consistency)

    - 维护节点之间的一致性(cache coherence)

    多路并发的MDS节点会更新每个副本,但是会周期性地向AUTH发送当前节点最新的数据。

    2、锁的类型分为LocalLock、SimpleLock、ScatterLock、FileLock

    无论何种类型的锁,都有一个state变量记录当前锁的状态。每个锁都有相关的状态机控制状态转移。根据状态机可以确定:

    - 下一步锁的状态(next_state)

    - 其他副本(Object比如Inode在多mds的其他mds也有副本叫replica)的状态

    - 允许谁可读(can_read)、谁可加读锁(can_rdlock)、谁可加写(can_wrlock)、谁可以加排他锁(can_xlock)等。这里的谁被抽象成为ANY、AUTH、XCL等。ANY指的任何拥有Object副本的MDS,AUTH(authority)指的是被授权Object的MDS,XCL指的是被授权Object的MDS或者排他执行的客户端。

    - 对应的caps是什么,包括拥有Object副本的MDS的此时应该使用的caps(针对不同的角色也分为4种)

    复杂程度而言,可以根据sm_state_t结构体里面定义的条数判断,LocalLock最简单,SimpleLock/ScatterLock相对复杂,FileLock最为复杂。

    3、锁的状态有很多,都是以LOCK_开头的(除了LOCK_AC_*之外,它代表锁的某种行为)。一般而言,LOCK_<状态>都是稳定状态(标准是在状态机其next_state为0,也有例外),比如LOCK_SYNC/LOCK_LOCK/LOCK_MIX等。LOCK_<状态1>_< 状态2>是中间状态,比如LOCK_SYNC_LOCK就是从LOCK_SYNC状态向LOCK_LOCK状态转移的中间状态,日志中可以看到“sync->lock”就是这种状态dump出来信息。

    4、每个Inode里面有多个Lock,每个Lock对应2中介绍的4种类型的锁。每种锁关联的是不同的文件系统资源。

    LocalLock  -  versionlock

    SimpleLock用在nlink、atime、mtime等属性的处理上。其特点是"共享读、互斥写"。

    SimpleLock  - authlock  linklock  xattrlock(扩展属性相关)  snaplock(快照相关)    flocklockpolicylock(layout相关)  

    ScatterLock用在需要处理迭代的数据结构,比如目录树或者目录下面的统计信息,其特点是“共享读、共享写”

    ScatterLock -  dirfragtreelock nestlock 

    FileLock既用在处理atime、ctime等需要互斥操作的属性上,也有需要共享写的统计信息上。

    FileLock - filelock

    5、Cap当中的s代表share,意味着客户端拥有读相关信息的能力,比如删除inodes时mds会设置CEPH_CAP_LINK_SHARED,即Cap为Ls,客户端读到该标志位,会判断inode的nlink信息是否为0,0则代表删除客户端执行针对删除的操作。x代表允许客户端更新相关信息的能力(独占执行的能力)。

    6、Cap和锁的关系

    客户端是根据MDS赋予的cap确定相关行为。MDS则根据客户端发来的请求和当前锁的状态,确定授予(grant)或者剥夺(revoke)客户端的caps。

    7、打算对一个inode或者dentry加锁,需要先确定给其中的哪些锁加什么类型的操作。一般有rdlock、wrlock、remote_wrlock、xlock等。

    rdlock  读锁操作,当一个资源加了读锁之后,不能再加独占锁对其修改。

    wrlock  写锁操作

    remote_wrlock  远端写锁操作

    xlock  独占锁操作,比如修改某项资源,一定要让锁执行该操作。

    使用场景比如,

    在创建快照的时候需要给执行目录的inode的snap锁加上独占操作。

    xlocks.insert(&diri->snaplock));

    ls的时候会对父目录至根目录的dentry都加rdlock防止被修改。

    rdlock.insert(&dn->lock)

    日志里面“isnap sync r=<NUM>”之类的输出代表当前snap锁处在sync状态,锁上有NUM个读锁操作(见SimpleLock.h SimpleLock::_print())。

    8、Locker中*_start 表示对某个锁执行某种类型的锁操作。*_finish表示结束对某个锁加某种类型的锁操作。*_try代表尝试去执行某种类型的锁操作是否能够成功。这里的*代表rdlock、wrlock、remote_wrlock、xlock等。

    9、Locker中有操作状态的转变函数,将任何中间状态变为*_sync同步状态,*_excl 独占执行状态、*_lock锁状态、*_xlock独占锁状态。*可以是simple/scatter/file代表不同的锁类型。比如Locker::file_xsyn函数会让filelock进入xsyn状态,XSYN状态出现在如下场景中:

    如果一个客户端在执行ls –al的时候想要rdlock。此时如果一个EXCL的客户端正在缓存写,那么MDS会让锁进入XSYN状态,进入这个状态写会被停止,但是缓存不会刷到磁盘(提升效率)。  

    10、MDS和其他MDS处理锁相互发的是MLock请求。执行发送的函数是Locker::send_lock_message。内容是锁和相关的转换操作(LOCK_AC_*定义的行为)。

    由auth的MDS发给replica的MDS有如下所示。replica的MDS收到之后会将其本地保留的锁状态,尽可能转换为消息中定义的锁状态。

    LOCK_AC_SYNC      //向SYNC状态转换

    LOCK_AC_MIX          //向MIX状态转换

    LOCK_AC_LOCK      //向LOCK状态转换

    LOCK_AC_LOCKFLUSHED      //向LOCKFLUSHED状态转换

    相关文章

      网友评论

          本文标题:了解cephfs锁必须要知道的事情

          本文链接:https://www.haomeiwen.com/subject/wvjjfhtx.html