RESTful 分布式锁

RESTful 分布式锁

设计上,HttpProxy 提供了一种新的接入方式,本身是无持久化状态的,它与传统 C++ SDK 看到的后端是同一个,也就是说后端数据是共享的。设有两个客户端争抢同一把锁(Lock),每个客户端创建一个 Lease,然后以 Lease 作为 Owner 去创建锁,藉由锁的唯一性确保了同一时间只有一个客户端能抢到锁。锁是一种临时节点,它的生命期与 Owner Lease 绑定,当持有锁的客户端与 Lease 的心跳停止后,Lease 会在预定时间内超时终结掉自己,其占有的锁也会随之被自动释放掉,以便其他存活的客户端抢占,进而锁的存活性得以确保。

![锁代理请求]](https://s2.ax1x.com/2019/09/26/ueN5uD.png)

Proxy Failover

引入 Proxy 之后,故障转移(Failover)与先前有所不同。当一台 Proxy 发生故障之后,客户端只需要将请求转到另外一台 Proxy 即可。当后端节点发生故障之后,Proxy 会与新的后端节点重连并重建会话,这个过程对客户端几乎无感。

Failover 时长是衡量 Failover 性能的重要指标。Proxy 引入前,Failover 时长主要取决于后端的选举时间和客户端请求超时时长,在引入 Proxy 之后,Proxy 与后端的 Failover 切换时间也需要考虑在内。一般的停机故障发生时,Proxy 能在秒级甚至毫秒级完成 Failover,在大多数情况下是客户端无感的。然而,在所有故障类型中,断网是对 Failover 时长影响最极端的场景。

引入 Proxy 后对 Failover 带来的另外一个影响是“写漂移”的问题,我们所谓的“写漂移”是指这样一种情况,客户端发起的请求经过很长时间后到达服务端,与客户端后来重试发起的请求之间产生冲突的问题。引入 Proxy 之前,“写漂移”的问题是通过 TCP 耦合的会话机制来防护的。具体地,TCP 的顺序性保证了在一个 TCP 连接的周期内不会出现漂移的乱序问题,当 Failover 发生的时候,会话的重建过程确保了先前 TCP 连接上的请求被丢弃,从而避免了“写漂移”问题。在引入 Proxy 之后,从客户端端到后端拉通了看,有序性被打破了,所以“写漂移”发生是存在可能性的。对于分布式锁而言,无论是 Lease 的创建和心跳,还是锁的创建和删除,都是满足幂等性条件的,“写漂移”不对此构成正确性问题。