在客户端服务器系统中,每一台计算机都是一个节点,客户端希望通过网络操作服务器上的数据。在分布式系统中可能遇到的问题是:
消息丢失和损坏
-
消息丢失
待确认的消息;客户端每次发送命令到服务器,服务器收到之后发送一个确认消息,如果客户端在一个合理的时间内未收到消息就重新发送
-
消息损坏
在消息中包含校验字段,比如使用哈希算法,添加消息的摘要,通过校验确保消息没被损坏;如果考虑恶意篡改,可能还需要使用签名
多服务器和多客户端的情况下,由于网络的不确定性,可能导致不一致的状态
解决一致性的问题的方法:
1. 串行化命令
如果对于一组服务器,所有的节点按照相同的顺序执行一组命令,同样的数据,同样的算法得到的结果应该是相同的,也就是说这组节点是可以实现状态复制。
在系统中设计一个节点为串行化器,所有需要发送命令都发送到串行化器,然后由串行化器同步到其他服务器,保证相同的顺序;
- 应用: 主从复制
- 缺点:单点故障
2. 两段式提交
另外一种保证一致性的思路是,客户端向服务器提交请求或者数据的时候确保只有一个客户端在发送命令,完成这条命令之后,才接受其他的请求;也就是使用分布式锁;
1. 客户端向所有的服务器请求锁
2. if 客户端获取所有服务器的锁 then
向每台服务发送命令,然后释放锁
else
释放已经获取到的锁
随机等待一段时间,重新获取锁
end
-
应用: 数据库系统2 段式提交事务
-
缺点:相对于序列化器只需要保证该节点运行正常就可以,但是这种分布式锁的方式,需要获取所有的节点的锁,任何一个服务器故障导致系统不能正常运行,因此容错性不好;
-
改进方法
分布式锁的方案本质是如果有2个客户端(A和B)同时请求,至少有一个公共的服务器节点拒绝 A和B中的一个,保证同时只有一个请求。因此这种情况下我们可以让客户端获取超过一半的节点的锁;如果超过一半的节点成功锁定,那么其他请求必定无法获取超过一半节点的锁。 -
继续改进
当服务器节点比较多的时候,获取一半的锁仍然开销比较大,能不能获取更少的锁来保证同时只有一个请求能够获取锁呢?
网格仲裁系统
将服务器节点组成网格形状,如下图所示,当客户端发送一条命令的时候,让客户端获取方形矩阵中的第i行和第i列,如果获取成功,则可以执行命令;
如果同时有2个客户端同时发送命令,假设客户端A需要获取第1行和第1列,而客户端2需要获取第二行和第2列;他们中间必然有重复的节点,这些重复的节点保证只有一个客户端能够成功的获取锁;这种方案在16个服务器节点的情况下需要获取7个锁,但是上面的方案(一半以上)需要至少获取9个锁
-
本节结束,后来我们继续分析分布式一致性算法Paxos。
网友评论