分布式锁SanLock基本原理

两种算法

SanLock的实现基于两种算法,这两种算法都是在多个节点可以同时访问的共享存储(iSCSI、FCoE等)、或者分布式文件系统(NFS、GlusterFS)上建立的。

Light-Weight Leases

向一个数据块中写入一个数据,然后等待一段时间,如果发现没有被改变,则获取该数据块的所有权。该算法很简单,空间占用小,但是速度慢。

Disk Paxos

是Paxos算法在存储上的变种,每个节点占用一个数据块,可以写自己的数据块,但只能读其他节点的数据块。当需要获取所有权时,向自己的数据块写入提案号和提案者唯一ID,然后读取其他节点的数据块并进行冲突检测,如果没有冲突则成功。该算法相对复杂,空间占用大,但是速度快。

两种对象

使用者必须首先加入一个Lockspace,然后再请求或释放Resources。

Lockspace

Lockspace

  • 使用Light-Weight Leases算法实现Delta Leases租约,当sanlock获取一个Delta Leases后,会定时(默认为20秒)使用自己的CPU时间更新其时间戳。
  • 每个Lockspace由多个Delta Leases租约实现,默认有2000个,每个512字节,总共1M。
  • 一个Lockspace最多支持2000个节点,每个节点使用不同的Delta Leases,使用从1到2000的序号标识。
  • 一个Lockspace代表一个集群,每个Delta Leases代表一个节点,使用其序号标识节点的Host ID。
  • 节点使用唯一的主机名,通过Lockspace获取其节点的Host ID,如果没有指定主机名,则sanlock会自动生成一个UUID来替代(每次重新获取时,这个UUID会变)。
  • 一个Delta Leases保证Lockspace中的Host ID只能被一个节点使用。
  • 当一个节点获取Delta Leases成功后,就相当于加入到这个Lockspace(集群)中,然后就可以使用与之关联的Resources了。
  • 因为使用的是“等待”和“观察”算法,检测Delta Leases的冲突是非常耗时的。如果多个节点竞争同一个Delta Leases,延迟会继续增加。

Resources

Resources

  • 使用Disk Paxos算法实现Paxos Leases租约,使用一个Paxos Leases租约实现一个Resources。
  • Resources必须以Lockspace为加锁解锁的上下文环境,因此每个Resources必须属于一个Lockspace。
  • 一个Resources至少占用1M空间,包含唯一的Resource名字和所属的Lockspace。
  • 在一个Resources中,每个节点有一个扇区(默认512字节)空间可以写自己的投票,也可以读取其他节点的投票情况。
  • 每个Resources的第一个扇区被称为“Leader Record”,其中包含最后一次投票的结果,每次竞争的获胜者把投票结果写进“Leader Record”(获胜者也可以把其他竞争者选为所有者)。
  • 当获胜者被选出后,对这个Resources所在的磁盘区域就不需要任何的IO操作了。
  • 当释放Resources时,只需清除“Leader Recorder”中的当前所有者既可。
  • sanlock不会定时更新Paxos Leases的租约,是否过期主要看其所属的Lockspace的时间戳,以减少磁盘读写量。
  • 当获得Resources所有权的节点失效时,Resources中的所有者依旧指向这个失效节点。当其他节点试图获取其所有权时,发现他已经由所有者了,然后就根据其Host ID检查其所属Lockspace的对应Delta Leases是否过时。如果未过时,则所有者不变;如果过时,则获取这个Resources的所有权。
  • 两个节点之间的交互仅限于试图获取相同的Resources时,或者检查对方的Delta Leases是否超的时候,除此之外相互之间没有任何相互影响。
  • 使用者必须自己记住Lockspace和Resources租约的位置,sanlock不会保存其位置。

过期与失效

每个节点的sanlock守护进程会定期更新本节点已获得Host ID的Lockspace中的时间戳,以确保自己是该Host ID的唯一所有者。

  • 当获取Host ID的节点无法正常更新其时间戳时,将会失去对应资源的访问权,所拥有的Host ID就会因超时而过期,其他节点就可以获取其Host ID以及所属的Resources。

  • 当一个节点的sanlock无法周期更新自己Host ID的时间戳时,应主动停止所有使用与该Lockspace有关联的Resources的进程,同时sanlock会进入“Recovery Mode”,以防止与其他节点访问冲突。

  • 当一个进程崩溃或退出时没有释放自己已获取所有权的Resources,sanlock会自动(sanlock会收到终止进程的套接字POLLIN和POLLHUP事件)释放其所有权(使用持久化的Resources租约除外,这个我没研究过怎么用以及如何实现)。

  • 如果sanlock崩溃,且使用了看门狗,系统会由于没有喂狗而被看门狗复位。

问题思考:

1. 假设节点X获取了某个Locspace的Host ID为1,资源A,此时资源A属于Host ID 1。
2. 当节点X失效后,另外一个节点Y获取其Host ID 1成功,但并没有去试图获取资源A的所有权。
3. 此时资源A所属的Host ID依旧为1,而实际上并没有节点拥有该资源的所有权。
4. 这时节点Z使用Host ID 2获取资源A,然后通过其所属的Host ID为1,没有失效,因此获取所有权失败。
5. 所有节点都将无法获得资源A的所有权,会陷入死锁。

规避方法:

所有节点都永远不要使用相同的Host ID(至少在一个同一个Lockspac中不要有多个节点竞争相同的Host ID)。

失效处理:

  • 正常终止(Graceful Shutdown) - sanlock会通知其他进程处理此种情况,如果在规定时间(-g选项设置)没有处理或者终止,则会使用SIGTERM信号强制其退出。
  • 强制终止(Forced Shutdown) - 如果进程在规定时间没有处理或者终止,使用SIGKILL信号强制终止。
  • 主机复位(Host Reset) - 在以上两种情况都失败时,sanlock会停止喂狗,由看门狗复位主机。

也可以通过设置force_mode和killpath参数来修改处理方式。

看门狗与隔离

被动隔离

  • sanlock通过wdmd服务间接访问/dev/watchdog设备,实现一个硬件(软件)设备的复用。
  • Watchdog可以使用专用硬件,也可以使用软件实现的softdog,但软件实现的效果会差一些。
  • 当sanlock出现异常或因为某个Lockspace超时而停止喂狗时,系统就会复位,防止脑裂。

主动隔离

sanlock中使用fence_sanlock功能实现主动隔离。为每个节点创建一个Resources租约,fence_sanlock获取该节点所属Resources的所有权。如果其他节点获取该Resources,则会被该节点发现,然后主动停止向wdmd喂狗,最后被看门狗复位。

Fence_Sanlock

转载于:https://my.oschina.net/LastRitter/blog/1538457

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值