分布式系统 服务单点问题的探讨( 二 )


分布式系统 服务单点问题的探讨

文章插图
第一个方案就是就是增加一个备用节点 , 备用节点和业务进程也可以进行通信 , 但是所有的业务消息都发往节点进行处理 。节点和Slave节点之间采用ping的方式进行通信 。Slave节点会定时发送ping包给节点 , 节点收到后会响应一个Ack包 。当Slave节点发现节点没有响应的时候 , 就会认为节点挂了 , 然后把自己升级为节点 , 并且通知业务进程把消息转发给自己 。
该方案看起来也是挺完美的 , 好像不存在什么问题 , Slave升级为后所有的业务消息都会发给它 。但是 , 如果在内部有一些自己的业务逻辑 , 比如说随机生成一些业务数据 , 并且定时存档 。那么当和Slave之间的网络出现问题的时候 , Slave会认为挂了 , 就会升级为 , 同样会执行的相应的业务逻辑 , 同样也会生成一些业务数据回写到DB 。但是 , 其实是没有挂的 , 它同样也在运行对应的业务逻辑(即使业务进程的消息没有发给旧的了) , 这样就会出现两个进行写同一份数据了 , 造成数据的混乱 。所以说 , 该方案并不是一个很好的方案 。
那么怎么解决可能会出现多个的问题?
换个角度看 , 该问题其实就是怎么去裁决 , 哪个节点是的问题 。
方案一:引入第三方的服务进行裁决 。
我们可以引入 , 由进行裁决 。同样 , 我们启动两个主节点 , “节点A”和节点B 。它们启动之后向去注册一个节点 , 假设节点A注册的节点为 , 节点B注册的节点为 , 注册完成后进行选举 , 编号小的节点为真正的主节点 。那么 , 通过这种方式就完成了对两个进程的调度 。
分布式系统 服务单点问题的探讨

文章插图
有一套机制 , 可以保证不会出现多个的情况 , 具体可以参考:
方案二: 通过选举算法和租约的方式实现的选举
对于方案一的缺点主要要多维护一套的服务 , 如果原本业务上并没有部署该服务的话 , 要增加该服务的维护也是比较麻烦的事情 。这个时候我们可以在业务进程中加入的选举方案 。目前有比较成熟的选举算法 , 比如Paxos和Raft 。然后再配合租约机制 , 就可以实现的选举 , 并且确保当前只有一个的方案 。但是 , 这些选举算法理解起来并不是那么地容易 , 要实现一套完善的方案也是挺难的 。所以不建议重复造轮子 , 业内有很多成熟的框架或者组件可以使用 , 比如微信的 。
分布式系统 服务单点问题的探讨

文章插图
比如上图的方案中 , 三个节点其实都是对等的 , 通过选举算法确定一个 。为了确保任何时候都只能存在一个 , 需要加入租约的机制 。一个节点成为后 , 和非节点都会进行计时 , 在超过租约时间后 , 三个节点后可以发起“我要成为”的请求 , 进行重新选举 。由于三个节点都是对等的 , 任意一个都可以成为 , 也就是说租期过后 , 有可能会出现切换的情况 , 所以为了避免的频繁切换 , 节点需要比另外两个节点先发起自己要成为的请求(续租) , 告诉其他两个节点我要继续成为 , 然后另外两个节点收到请求后会进行应答 , 正常情况下另外两个节点会同意该请求 。关键点就是 , 在租约过期之前 , 非节点不能发起“我要成为”的请求 , 这样就可以解决频繁切换的问题 。