分布式共识机制

2020-11-12 11:29:55 浏览数 (1)

C/S模式

  1. 我们先从最简单的两台计算机开始,一台是服务器,一台是客户端,即C/S模式。客户端希望操作服务器节点上的数据。
  2. 既然客户端想要操作服务器上的数据,就必然需要进行网络通信,发送命令。但我们并不能保证客户端发送的每一条消息都会被服务器收到。
  3. 那么当服务器收到消息后,会发送一个确认消息给客户端,如果客户端没有收到服务器发送的确认消息,则客户端会重新发送一条相同的消息命令。
  4. 但是客户端发送消息命令到达服务器端的时间可能是不同的。服务器发送确认消息到达客户端的时间也是不同的。
  5. 这将导致在多个服务器和多个客户端间接收到的消息命令的顺序也是不同的。则在不同的服务器之间,它们的状态是不同的。
  6. 对于一组服务器来说,如果所有的服务器都按照同一个顺序来执行一组命令序列(这组命令序列可能是多个客户端发送过来的),则这组服务器实现了状态复制。因为单个服务器更容易办到这一点,我们通常只对单个服务器发送消息命令,单个服务器也肯定是按照一个顺序来执行一组命令序列。
  7. 当单个服务器收到一条命令的时候,它可以将这条命令转发给其他的服务器。当它收到其他服务器的确认信息之后,它会通知客户端这条命令已被成功执行。
  8. 单个服务器容易产生宕机,如果我们不使用单个服务器转发命令,而是采用两阶段提交,某一个客户端先尝试获取所有服务器的锁,如果获取到了所有服务器的锁,则开始发送命令。这样所有服务器将无法接收其他客户端的命令,保证了所有服务器的命令顺序一致性,客户端发送完命令后再释放所有服务器的锁。如果这个客户端拿不到所有服务器的锁,则释放掉自己拿到的服务器的锁,等待一段时间,再重新尝试拿取所有服务器的锁。当然为了节省时间,我们认定客户端拿到半数服务器的锁就可以开始执行命令了,因为一个客户端拿到半数服务器的锁,那么其他的客户端就不可能再拿到大部分服务器的锁了,这样只拿到一小部分锁的客户端就得释放锁。
  • Paxos

当我们采用两阶段提交的方案时,而不是单台服务器转发,那么当多个客户端同时企图获取大部分服务器的锁的时候,会发生什么情况呢?客户端是否必须释放它们所有获得的锁,以避免死锁。又或者客户端获取部分锁之后挂掉了呢?

如果我们让这种锁可以过期如何?我们称这种可以过期的锁为票。这样就不会一直锁住没有被释放锁的服务器。首先是客户端向所有服务器请求一张票,票是服务器发给客户端的,当客户端收到半数服务器发送过来的票的时候,就会将这张票和命令一起发送给所有服务器。如果服务器发现收回来的票是自己最新发送出去的时候,并且没有过期,就会给客户端一个正反馈。客户端收到了过半服务器的正反馈,就会通知所有的服务器开始执行命令。但服务器一直没有收到客户端执行命令的通知,它同时还会继续接受其他客户端发送过来的票请求,并将发送一张最新的票给其他客户端。当有其他客户端得到半数票以后,会将新票和自己的命令发送给所有服务器。这个时候如果部分服务器收到了这个命令和票的时候,而之前的收到了过半服务器正反馈的客户端通知所有服务器开始执行命令,这个时候就会出现所有服务器的命令不一致。

0 人点赞