写在前面
本文一起看下分布式理论中的分布式互斥(distributed mutual[ˈmjutʃuəl] exclusion)问题,以及解决该问题相关算法。
1:什么是分布式互斥
我们先看下什么是临界资源(critical resource),临界资源是同时只能被一个程序访问的共享资源,而分布式互斥就是多个服务以排它的访问方式来访问临界资源,或者是多个服务对临界资源的互斥访问方式。本文我们要分析的算法就是用来解决分布式互斥问题的。主要有以下3中:
1:集中式算法
2:分布式算法
3:令牌环算法
接下来分别看下。
2:分布式互斥算法
2.1:集中式算法
集中式算法的核心思想是,引入一个协调者的角色,所有需要访问临界资源的服务都需要通过该协调者获取访问资格,当有多个服务申请访问同一个临界资源时,协调者根据时间的先后来决定给哪个服务发放临界资源访问资格,其他的服务在队列中等待已获取临界资源访问资格的服务释放访问资格后再来访问,这个过程可能如下图:
此时程序3释放访问资格,协调者将访问资格发放给等待队列中中的程序4,同理,如果是程序4释放访问资格的话,协调者又会将访问资格发放给程序2。可以看到每个服务从申请临界资源访问授权到释放临界资源访问授权,经历了如下的3次交互:
1:服务向协调者发送临界资源申请请求
2:协调者给服务发放临界资源访问授权
3:服务将临界资源访问授权归还协调者
接下来我们看下集中式算法的优点和不足。
- 优点
协调者实现简单,服务申请资源访问需要的交互次数少。 - 缺点
服务的性能严重依赖协调者,当协调者压力大或出现问题时,服务相关接口或功能将不可用。当同时申请临界资源的服务器较多时,协调者将会承受比较大的请求压力,如有100个服务,同时会有100*3=300个请求到达协调者。
从以上可以看出该算法对协调者的要求较高,如果是协调者具备高可用,高性能特点的话,该算法是大有用武之地的,比如协调者的具体实现redis cluster 。
2.2:分布式算法
分布式算法的过程是,如果某服务想要获取一个临界资源访问权限的话则需要向其它所有其他服务发出申请,只有当所有的其他服务都同意之后才能获取临界资源访问权限,某服务在收到其他服务的访问请求后,如果是自己不需要或并未正在使用临界资源的访问权限,则返回同意,否则记录要申请的临界资源,申请资源服务ID,申请的时间
等信息到自己的临界资源申请请求队列中,待自己释放临界资源的访问权限后,取出第一个服务申请,返回同意,如下程序1、2、3需要访问共享资源A。在时间戳为8的时刻,程序1想要使用资源A,于是向程序2和3发起使用资源A的申请,希望得到它们的同意。在时间戳为12的时刻,程序3想要使用资源A,于是向程序1和2发起访问资源A的请求:
因为程序1在时间戳8已经获取了临界资源A的访问权限,所以会将将程序3在时间戳12申请访问临界资源A的请求放到请求队列中,在自己使用完毕后,再返回给程序3同意的消息,如下图:
可以看到一个服务想要获取某临界资源访问权限的话需要经过如下交互:
1:向n-1个其他服务器发送申请
2:接收其他n-1个服务的同意响应
每次都需要2*(n-1)次交互才能获取某临界资源的访问权限,当n较大,即集群规模比较大时,这个沟通成本还是比较高的,接下来我们看下这种算法的优点和缺点是什么。
- 优点
实现简单,每个服务都能够按照时间顺序公平的访问临界资源。 - 缺点
当集群规模大,申请临界资源的服务较多时,容易产生信令风暴
,即服务无法正常处理收到的请求,假设集群规模是100,同时有50个服务都要访问临界资源,则每个服务在向外发出99个临界资源申请请求的同时,并接受99个服务的响应,还要接收来自其他49个服务的临界资源请求。则总共是(99+99+49)*50
,另外当某服务响应同意延迟时,会造成整个集群的阻塞,因此该算法可用性低。
经过以上分析,该算法适用于小规模集群,比如只有几个节点,如hadoop中的分布式文件系统HDFS就使用了该算法,比如有计算机1,计算机2,计算机3,假设计算机1要修改某临界资源文件,则需要向计算机2,计算机3发送请求,二者向其返回同意,然后计算机1开始修改,修改后再将修改的文件同步给计算机2和计算机3,这个过程如下图:
总结就是,该算法适用于临界资源使用频率低,并且集群规模小的场景中。
3.3:令牌环算法
令牌环算的过程是,所有的服务组成一个逻辑上的环状结构,然后令牌按照顺时针或者逆时针(方向无所谓)
的方向在服务中挨个流转,如果是当前服务需要访问临界资源则使用该令牌开始访问临界资源,如果是不需要则流转到下一个服务节点,这个过程如下图:
这种算法要求每个节点都记录所有其他节点的信息,从而能够形成一个逻辑上的环状结构,并且因为是挨个传递,所以中间会存在大量的无效传递,即无效网络通信,是不必要的消耗,比如从服务节点1开始传递,而服务节点99需要令牌,则服务节点99就需要等待98次传递才能获取临界资源的访问权限,因为经过了97次无效传递的同时,所以需要等待较长的时间,会降低集群的整体性能。因此这种算法适用于每个服务节点访问临界资源的频率都很高(减少无效传递)
,并且使用令牌的时间都很短(减少每个服务节点获取令牌的时延)
的场景。
写在后面
参考文章列表: