关于协会网站建设的几点思考,为什么邮箱突然进不去了总提示正在进入不安全网站,点击排名优化,wordpress 覆盖原始图片对比效果简介在分布式系统中#xff0c;最常见的场景就是主备架构。但是如果主机不幸宕机#xff0c;如何正确的通知客户端当前后端服务器的状况成为一个值得研究的问题。本文描述了一种简单的模型用于解决此问题。背景以一个分布式的Key-Value数据库为背景。数据库对外提供3个接口Ge…简介在分布式系统中最常见的场景就是主备架构。但是如果主机不幸宕机如何正确的通知客户端当前后端服务器的状况成为一个值得研究的问题。本文描述了一种简单的模型用于解决此问题。背景以一个分布式的Key-Value数据库为背景。数据库对外提供3个接口Get(key)Put(key, value)Append(key, value)客户端对数据库的操作请求必须发往主机 只有当主机不可访问主机宕机或网络问题时备机代替主机并且再从集群中选一个新的机器作为备机。问题来了 客户端如何知道当前谁是主机谁是备机目的为了保证客户端与服务器就谁是主机谁是备机这个问题达成共识。整体架构为了解决这个问题我们在Server和Clint中间加入一个ViewServer。viewserver的作用相当于一个中介。举个例子当客户端想要执行Put操作时需要先向viewserver询问当前的Primary是谁随后客户端根据viewserver的回复将Put请求发到相应的server。Viewviewserver返回给客户端的信息需要包含至少3条信息1. 当前主机是谁2. 当前备机是谁3. 当前状态的版本号我们将这3个信息称为viewserver的当前View。typedef struct View {Viewnum intPrimary stringBackup string}CopyServer在多个server中只有一个主机一个备机其余的server都处于空闲状态。所有的server都需要每隔一段时间向viewserver发送Ping消息以证明自己还活着。并且通过Ping的返回值得到当前viewserver认为的主机和备机是谁。这样如果主机和备机都正常在一段时间之后后端server都会有一致的主机和备机。Client在操作后端server之前先讯问viewserver当前主机是谁ViewServerviewserver的功能比较复杂主要负责回复客户端当前View检测后端的server的存活情况保证当前主机得到最新的View在检测后端server存活情况时有几种情况主机Primary失联备机Backup失联空闲机器失联当检测到主机或者备机失联时viewserver应该对当前View做调整。如果主机失联则把备机选做主机然后从空间机器中挑选一个作为备机。如果备机失联只从空闲机器中选择一个作为备机即可。但是这两种情况都需要对View的版本号进行增加。这个View版本号只有后端server关心客户端只关心当前主机。加入这个版本号的目的主要是为了确保当前主机得到了最新的View。比如备机的更换会需要主机向备机做数据拷贝如果主机得不到这个消息整个主备系统就失效了。上图描述了两台server与viewserver之间的通信每次server端Ping需要包含一个参数用于表示当前这个server所了解到了View版本号1. 在初始状态server1向viewserver发送Ping并且用做为参数由于初始状态viewserver还没有选择主机和备机所以先到先得选择server1为主机于是返回给server1的iew为server1, NULL, 1, 表示当前主机为server1 备机为NULL, 望的到的版本号为(希望一段时间后当前的主机Primary以这个新版本号发起Ping).2. server2此时加入了集群向viewserver发送了Ping 由于server2与server1没有联系所以Ping的参数还是用表示这是新加入的机器虽然此时viewserver发现又有了一台机器加入并且当前只有主机没有备机但是还不能选择server2做为备机因为server1还没有用做为参数发起Ping, 说明viewserver当前的这个View主机为server1备机为NULL可能还没有被当前主机server1收到因此返回给server2的View为[server1, NULL, 1].3. server1顺利收到viewserver返回的View,得知viewserver想要版本号为的Ping, 于是隔一个PingInerval再向viewserver发起Ping同时以为参数. viewserver顺利收到这个Ping, 发现正是自己希望得到的(当前主机以新版本号发起的Ping), 并且了解到一个事实当前主机server1已经知道了当前最新的主备情况于是viewserver将View的版本号更新.返回给server1[server1, NULL, 2]4. server2在一个PingInterval后再次向viewser发起Ping, 因为之前一次Ping返回的ViewNum为, 因此用为参数当viewserver顺利收到Ping时由于viewserver知道当前主机server1以经获得了它目前保存的这个状态因此将server2选为备机, 构成了一个新的状态主机为server1, 备机为server2, 这个状态还没有任何server知道 当前的主机server1显然也不知道因此ViewNum不能更新于是返回[server1, server2, 2]给server2.5. server1向viewserver发起Ping(2), viewserver通过这个Ping得知当前主机server1以经获得了自己最新的状态然后server1失联6. server向viewserver发起Ping(2)在长期没有的到server1的Ping后viewserver会认为server1以经不能继续对外提供服务了于是选择备机server2做为主机如果有其他空闲机器可以从中选一个做为新的备机viewserver之所以选择server2做为备机是因为确定server2可以万全代替以经失联的server1, 因为server2做为备机这个信息server1以经收到了确保server2的状态与server1相同是server1的工作比如主机会向备机发送数据做数据同步存在的问题If the view service has not yet received an acknowledgment for the current view from the primary of the current view, the view service should not change views even if it thinks that the primary or backup has died. That is, the view service may not proceed from view X to view X1 if it has not received a Ping(X) from the primary of view X.