【分布式系统常见的问题以及术语】

分布式系统之----CAP理论 

【分布式的存储系统之一致性哈希算法】

一、选择分布式系统的动机 

(1) 信息交换 

(2) 资源共享 

(3) 通过重复提高可靠性 

(4) 通过并行化提高性能 

(5) 通过专门化简化设计 

(6) 问题本身的特点决定

 

           人多力量大,是没有错误的,但是人多也有坏处

二、分布式系统进程通信,rpc基本原理步骤

1、客户过程以正常方式调用客户存根

2、客户存根生成一个消息,然后调用本地操作系统

3、客户端操作系统将消息发送给远程操作系统,并阻塞客户过程

4、远程操作系统将消息交给服务器存根

5、服务器存根将参数提取出来,然后调用服务器

6、服务器执行要求的操作,操作完成后将结果返回给服务器存根

7、服务器存根将结果打成消息包,然后调用本地操作系统

8、服务器操作系统将消息发送回客户端操作系统

9、客户端操作系统将消息交给客户存根

10、客户存根将结果从消息中提取出来,返回给调用进程

三、并发控制:在集群环境中,关键数据通常是共享存放的,比如放在共享磁盘上。而集群内各个节点的身份是对等的,所有节点对数据有相同的访问权利。此时就必须有某种机制能够控制节点对数据的访问。在ORACLE RAC中,是利用DLM(Distribute Lock Management)机制来进行多个实例间的并发控制。 

四、脑裂(Split Brain)

在集群里,节点间需要通过某种机制(心跳)了解彼此的健康状况,以确保各节点协调工作。假设只是“心跳”出现故障,但各个节点还在正常运行。这时,每个节点都认为其他节点宕机,自己是整个集群环境中的“唯一健在者”,自己应该获得整个集群的“控制权”。在集群环境中,存储设备都是共享的,这就意味着数据灾难,这样一种状况就是“脑裂”。解决这个问题的通常办法是使用投票算法(Quorum Algorithm)。 

裂脑现象:.是由于集群中的节点之间无法正常通讯而导致的集群中出现的不一致的现象  

如果出现这种情况,Oracle RAC会终止一个节点,来保证集群的一致性.裂脑产生后终止实例原则是根据裂脑现象残生的子集群进行投票选择终止的节点,投票规则节点数少终止,一致时node ID小的节点存活

投票算法原理:集群中各个节点需要心跳机制来通报彼此的“健康状况”,假设每收到一个节点的“通报”代表一票。 

五、健忘症(Amnesia)

此问题发生在集群环境配置文件不是集中存放,而是每个节点都有一个本地副本。在集群正常运行时,用户可以在任何节点更改集群的配置,并且这种更改会自动同步到其他节点。但有这种场景:两个节点的集群,节点1因为正常的维护需要被关闭,然后在节点2修改了某些配置,然后关闭节点2,启动节点1.因为之前在节点2做的配置修改没有同步到节点1,所以节点1启动后,它仍然是用旧的配置文件工作,此时就会造成配置丢失,也就是所谓的“健忘症”。 

六、IO隔离(IO Fencing)

此问题是上一个问题的延伸。要保证被赶出的节点不能操作共享数据。因为这时该节点可能还在运行中,如果不加限制很有可能会修改共享数据。 

IO Fencing实现有硬件和软件方式。

对于支持SCSI Reserve/Release命令的存储设备,可以用SG命令实现。正常节点使用SCSI Reserve命令“锁住”存储设备,故障节点发现存储设备被锁住后,就知道自己已经被赶出集群了,也就是说知道自己出现了异常状况,就要自行重启,以恢复到正常工作状态,这个机制也叫作suicide(自杀)。Sun和Veritas使用的是这种机制。

STONITH(Shoot The Other Node In The Head)是另一种实现方式,此方式直接操作电源开关。当一个节点发生故障时,另一个节点如果能侦测到,就会通过串口发出命令,控制故障节点的电源开关,通过暂时断电,而后又上电的方式使得故障节点被重启动。此方式需要硬件支持。

七、缓存的雪崩现象 

缓存雪崩一般是由某个缓存节点失效,导致其他节点的缓存命中率下降, 缓存中缺失的数据(memcache经典场景,当有一个客户端的服务请求过来的时候,首先去查memcache,memcache里面是否缓存过了这个数据,如果没有这个数据,我们就去数据库查询,如果有这个数据,我们就从memcache里面取出来,然后给它返回到客户端,这是一个经典的查询过程,在这个场景中,缓存中缺失的数据,是因为它的缓存节点失效了,所以缺失的数据将去数据库查询。去数据库查询.短时间内,造成数据库服务器崩溃.   重启 DB,短期又被压跨,但缓存数据也多一些.   DB 反复多次启动多次,缓存重建完毕,DB 才稳定运行. 

或者,是由于缓存周期性的失效,比如每 8小时失效一次,那么每 8小时,将有一个请求”峰值”, 

严重者甚至会令 DB 崩溃,例如取模算法,挂掉一个节点,遇到数据洪峰,可能面临雪崩境况。

八、缓存无底洞现象:

该问题由facebook的工作人员提出的,facebook在2010年左右,memcached节点就已经达

3000个.缓存数千G内容.

他们发现了一个问题---memcached连接频率,效率下降了,于是加memcached节点,

添加了后,发现因为连接频率导致的问题,仍然存在,并没有好转,称之为”无底洞现象”.

无底洞问题带来的危害:

(1) 客户端一次批量操作会涉及多次网络操作,也就意味着批量操作会随着实例的增多,耗时会不断增大。

(2) 服务端网络连接次数变多,对实例的性能也有一定影响。

结论:

用一句通俗的话总结:更多的机器不代表更多的性能,所谓“无底洞”就是说投入越多不一定产出越多

分布式又是不可以避免的,因为我们的网站访问量和数据量越来越大,一个实例根本坑不住,所以如何高效的在分布式缓存和存储批量获取数据是一个难点。



 

 

九、分布式方法

1)取模算法

简单来说,就是“根据服务器台数的余数进行分散”。 求得键的整数哈希值,再除以服务器台数,根据其余数来选择服务器。余数计算的方法简单,数据的分散性也相当优秀,但也有其缺点。 那就是当添加或移除服务器时,缓存重组的代价相当巨大。 添加服务器后,余数就会产生巨变,这样就无法获取与保存时相同的服务器, 从而影响缓存的命中率。分布式常常用取模算法来分布数据,当数据节点不变化时是非常好的,但当数据节点有增加或减少时,由于需要调整取模算法里的模,导致所有数据得重新按照新的模分布到各个节点中去。如果数据量庞大,这样的工作常常是很难完成的。

原理类似所有数据分布在假设三个节点上,自行车轮子由三股钢丝组成,崩掉一股,方圆120度的范围没有支撑,你的轮子就作废了

2)Paxos算法

Paxos算法的各个步骤和约束,其实它就是一个分布式的选举算法,其目的就是要在一堆消息中通过选举,使得消息的接收者或者执行者能达成一致,按照一致的消息顺序来执行。其实,以最简单的想法来看,为了达到大伙执行相同序列的指令,完全可以通过串行来做,比如在分布式环境前加上一个FIFO队列来接收所有指令,然后所有服务节点按照队列里的顺序来执行。这个方法当然可以解决一致性问题,但它不符合分布式特性,如果这个队列down掉或是不堪重负这么办?而Paxos的高明之处就在于允许各个client互不影响地向服务端发指令,大伙按照选举的方式达成一致,这种方式具有分布式特性,容错性更好。

3)一致性Hash算法

一致性Hash算法是基于取模算法的优化,通过一些映射规则解决以上问题 

一致性hash实际就是把以前点映射改为区段映射,使得数据节点变更后其他数据节点变动尽可能小。这个思路在操作系统对于存储问题上体现很多,比如操作系统为了更优化地利用存储空间,区分了段、页等不同纬度,加了很多映射规则,目的就是要通过灵活的规则避免物理变动的代价 

一致性Hash算法本身比较简单,不过可以根据实际情况有很多改进的版本,其目的无非是两点: 

节点变动后其他节点受影响尽可能小 

节点变动后数据重新分配尽可能均衡 

实现这个算法就技术本身来说没多少难度和工作量,需要做的是建立起你所设计的映射关系,无需借助什么框架或工具

原理类似:虚拟出很多个节点来映射三个节点,比如虚拟出63个节点,你崩掉一个还有42个节点在环上排列,轮子依然可以使用



 

4)令牌环

当环初始化时,进程0得到一个令牌token。该令牌绕着环运行,用点对点发送消息的方式把它从进程k传递到进程k+1(以环大小为模)。进程从它邻近的进程得到令牌后,检查自己是否要进入临界区。如果自己要进入临界区,那么它就进入临界区,做它要做的工作,然后离开临界区。在该进程退出临界区后,它沿着环继续传递令牌。不允许使用同一个令牌进入另一个临界区。如果一个进程得到了邻近进程传来的令牌,但是它并不想进入临界区,那么它只是将令牌沿环往下传递。

优点:不会发生饿死现象,最差情况是等待其他所有进程都进入这个临界区然后再从中退出后它再进去。

缺点:如果令牌丢失了,那么它必须重新生成令牌,检测令牌丢失是很困难的;如果有进程崩溃,该算法也会出现麻烦,但是恢复起来比其他算法容易。

原理类似:小时候玩过的丢手帕游戏,N多个人围成一个圈,令牌手帕由一个人绕着环带它绕行,手帕丢给谁,谁就有权利表演节目,开始带着下一轮运行。

猜你喜欢

转载自gaojingsong.iteye.com/blog/2339869
今日推荐