如何实现分布式数据存储一致
ZAB协议
主要特征:
崩溃恢复模式
消息广播模式
如何利用zookeeper进行选举,画图说明
master 选举-为其他集群机器服务
leader选举-集群启动时期、运行时期
为什么会存在zookeeper,它可以用在哪里
zookeeper 任务分配(以分布式日志收集任务为例)
ZAB如何避免写入阻塞(写锁,排他锁,分布式队列——FIFO,Barrier)
Zookeeper 避免脑裂
简述zookeeper部署的时候以多少个实例部署,为什么?
Zookeeper可以做横向扩展吗?可以通过增加机器可以增加集群的性能吗?
一致性hash 大数据日知录p15
简述paxos算法
paxos算法的应用
2PC
2pc何时出问题
如何实现分布式数据存储一致
有哪些一致性协议
ZAB协议、paxos协议、一致性哈希、两阶段提交协议2PC,3PC, raft
理论支撑:BASE = 基本可用,软状态,最终一致性
一致性模型分类
副本更新策略:同时更新,主从式更新,任意节点更新
~
zk如何保证数据一致性
具有原子性
sysc主动同步数据
ZAB协议
ZAB协议是为 分布式协调服务zk设计的 支持崩溃恢复的原子消息广播协议
主备模式:zk使用单一的主进程(leader)接受处理 客户端的事务请求,并采用ZAB(原子广播)协议,将服务器的数据变更以事务提议(proposal)的形式,广播到副本进程(follower)
主要特征:
(提交的,就被所有提交;没提交的,就丢弃)
实现方式:两种基本模式(情况)----崩溃恢复模式、消息广播模式
崩溃恢复模式
消息广播模式
具体过程
特点:
如何利用zookeeper进行选举,画图说明
master的作用
master 选举-为其他集群机器服务 利用其在高并发情况下zk节点创建的全局唯一性
leader选举-集群启动时期、运行时期
数据格式
(服务器id,事务zxid,当前服务器选举轮次electionEpoch,被选举服务器的选举轮次peerEpoch,服务器状态state)
默认的选举策略:fastleaderelection
集群启动时期:3台服务器为例,挂掉一台,还剩两台参与选举
运行时期 :3台服务器为例, 挂掉一台,还剩两台参与选举 zxid != 0
为什么会存在zookeeper,它可以用在哪里
zk是开源的分布式协调服务,是google chubby[tʃʌbi]的开源实现
设计目标:将复杂和易错的分布式一致性服务封装,提供分布式协调服务,高可用服务,具有严格顺序访问控制能力
应用场景:数据发布与订阅,负载均衡,命名服务,分布式协调/通知,集群管理,master选举,分布式锁,分布式队列,商品购买的顺序性
特点1:
简单的数据类型 znode,全量数据存储在内存中
顺序访问 全局递增编号zxid
高性能,尤其是读
幂等性:反复执行同一个操作与只正确执行一次操作效果相同;对系统来讲,同一操作反复调用其状态不变
可构建集群,集群间 TCP连接
特点2:A I D
I顺序一致性,事务请求按顺序处理
A原子性,要么所有节点成功处理了某事务,要么全部没有(保证了数据的一致性)
单一视图:无论连接着哪个节点,客户端看到的服务端数据类型全部一样
D可靠(持久)性:一旦成功处理了某事务。其对服务端状态的更改是永久的
伪实时性:保证一定时间段内,客户端最终能读到最新的数据
zookeeper 任务分配(以分布式日志收集任务为例)
作用:任务自动负载均衡,汇报任务负载情况,高可用
ZAB如何避免写入阻塞(写锁,排他锁,分布式锁、队列——FIFO,Barrier)
分布式锁实现方式:
以上方式容易造成羊群效应
基于ZooKeeper分布式锁的流程
Zookeeper 避免脑裂
Split-Brain:集群由于网络故障,分成了多个独立部分,多个master,相互之间不知道对方存活
zk集群 leader脑裂
ZooKeeper集群中必须超过半数节点(Majority)可用,整个集群才能对外可用
其他集群 master 脑裂 master假死造成
原因:单机“假死”:由于网络闪断,或是其自身由于负载过高(GC占用时间,CPU负载),无法及时对外响应
分布式脑裂:RM1假死后,RM2成为Active,此时RM1回恢复正常,则出现了分布式脑裂
Fencing机制:YARN引入fencing机制,借助zk数据节点的ACL权限控制实现不同RM的隔离,即创建的根节点必须携带ACL信息,以独占根节点。
过程:RM1恢复之后,会试图去更新*zk的相关数据,但发现没有权限,则自动切换为Standby
简述zookeeper部署的时候以多少个实例部署,为什么?
奇数台部署,zk选举时,只要半数拥护的机器就会成为leader,偶数台在容灾能力上没有优势(3,4台都只能挂1台)
Zookeeper可以做横向扩展吗?可以通过增加机器可以增加集群的性能吗?
可以设置多台observer,不参与投票(事务、leader选举),只负责读和事务转移
leader向observer发送INFORM(通知)——已被Commit的proposal
A(原子性,全部执行或放弃)C(一致性,完整性)I(事务独立,序列化)D(持久性,更新永久) 关系数据库采纳的规则
BASE 基本可用(允许偶尔失败) 软状态(不要求任意时刻保持同步)最终一致性(一定时间窗口内一致)
原则:全局BASE,局部ACID == 新的CAP
一致性hash 大数据日知录p15
最简单的原理:将数据key使用相同的函数Hash计算出哈希值,并确定此数据在环上的位置,从此位置沿环顺时针“行走”,第一台遇到的服务器就是其应该定位到的服务器。根据一致性哈希算法,数据A会被定为到Node A上,B被定为到Node B上,C被定为到Node C上,D被定为到Node D上
使用一致性哈希的好处在于,增减集群的缓存服务器时,只有少量的缓存会失效,回源量较小。
假设哈希空间长度(bit位) = 5,表达的数值范围是0-31,大圆表示机器节点(Ni),这台节点负责主键哈希值落在一定范围内的数据,H(key) = j
1.路由算法:如何根据数据key及哈希函数H定位记录内容
方法一,根据 j 遍历所有机器节点,找到Nx ,x >= j ; 效率太低
方法二,配置路由表,存储m条路由信息,第 i 项表示距离当前节点 2^i 哈希空间数值所在的机器节点
N14的路由表为: 假设 j = 18,18-14 = 4 ,根据路由表直接可找到数据在 N20
距离 1 2 4 8 16
机器节点 N20 N20 N20 N25 N5
路由算法: 类似于二分查找,代查距离不会原距离的超过一半(距离间都是*2的)
输入:向 Ni 发送初始查询请求,查询主键为key,H(key) = j = 27
输出:Ni 给出value,或返回不存在
算法:
1.Ni 检查是否在后继节点上: i < j
2.否则,查找路由表,找到小于 j 的最大编号 Nh (N25)(14+8 < 27 < 14+16)
3.Ni请求 Nh 代查,重复步骤1,2(递归)
虚拟节点 数据倾斜问题
同时数据定位算法不变,只是多了一步虚拟节点到实际节点的映射,例如定位到“Node A#1”、“Node A#2”、“Node A#3”三个虚拟节点的数据均定位到Node A上。这样就解决了服务节点少时数据倾斜的问题。在实际应用中,通常将虚拟节点数设置为32甚至更大,因此即使很少的服务节点也能做到相对均匀的数据分布
2.加入新节点
先通过路由算法查询H(Nnew) = new, 找到Nnew的后继节点Ns,Ns前继节点Np
改变三个节点的前继,后继节点记录
数据重新分片和分布,即将Ns节点存储的数据,按照架构迁移到Nnew
并发环境下一次性加入多个新节点时
将Nnew后继节点指向Ns,前继节点置 null
稳定性检测:P2P网络中每个节点定期执行
稳定性检测算法:略
3.节点离开:
正常:通知相应节点更改前后继节点,数据迁移至后继节点
异常:同一份数据备份副本 zk
特点:
一致性hash算法思路是将整个哈希值空间组织成一个虚拟的圆环,并通过hash算法加入对应服务节点(通过ip计算hash)组成服务节点圆环。(假设有我们要做5个物理节点,每个节点做5个虚拟节点,通过hash算法将物理节点的ip+虚拟节点标识,将转换成25个hash值,这些值就是服务节点在虚拟圆环的对应位置。)
附录:
良好的一致性hash算法,需要满足一下几点要求:平衡性(Balance)、单调性(Monotonicity)、分散性(Spread)、负载(Load)、平滑性(Smoothness)
平衡性(Balance)
平衡性是指哈希的结果能够尽可能分布到所有的缓冲中去,这样可以使得所有的缓冲空间都得到利用。很多哈希算法都能够满足这一条件。
单调性(Monotonicity)
单调性是指如果已经有一些内容通过哈希分派到了相应的缓冲中,又有新的缓冲区加入到系统中,那么哈希的结果应能够保证原有已分配的内容可以被映射到新的缓冲区中去,而不会被映射到旧的缓冲集合中的其他缓冲区。简单的哈希算法往往不能满足单调性的要求,如最简单的线性哈希:x = (ax + b) mod (P),在上式中,P表示全部缓冲的大小。不难看出,当缓冲大小发生变化时(从P1到P2),原来所有的哈希结果均会发生变化,从而不满足单调性的要求。哈希结果的变化意味着当缓冲空间发生变化时,所有的映射关系需要在系统内全部更新。而在P2P系统内,缓冲的变化等价于Peer加入或退出系统,这一情况在P2P系统中会频繁发生,因此会带来极大计算和传输负荷。单调性就是要求哈希算法能够应对这种情况。
分散性(Spread)
在分布式环境中,终端有可能看不到所有的缓冲,而是只能看到其中的一部分。当终端希望通过哈希过程将内容映射到缓冲上时,由于不同终端所见的缓冲范围有可能不同,从而导致哈希的结果不一致,最终的结果是相同的内容被不同的终端映射到不同的缓冲区中。这种情况显然是应该避免的,因为它导致相同内容被存储到不同缓冲中去,降低了系统存储的效率。分散性的定义就是上述情况发生的严重程度。好的哈希算法应能够尽量避免不一致的情况发生,也就是尽量降低分散性。
负载(Load)
负载问题实际上是从另一个角度看待分散性问题。既然不同的终端可能将相同的内容映射到不同的缓冲区中,那么对于一个特定的缓冲区而言,也可能被不同的用户映射为不同的内容。与分散性一样,这种情况也是应当避免的,因此好的哈希算法应能够尽量降低缓冲的负荷。
平滑性(Smoothness)
平滑性是指缓存服务器的数目平滑改变和缓存对象的平滑改变是一致的。
简述paxos算法
paxos算法的应用
2PC
作用:保证在分布式事务中,要么所有进程都提交事务,要么都取消事务,即实现 原子性
唯一的 协调者、多个 参与者
表决阶段:协调者 向所有参与者 发送 vote-request,参与者回复 vote-commit or vote-abort
提交阶段:协调者搜集参与者的表决信息
若全部收到comit,则发送global-commit, 参与者全部提交事务
若有一个是abort,则发送global-abort, 参与者全部取消事务
存在3个阻塞状态:协调者wait(request之后),参与者init(等待request),ready(收到request)
引入超时判断机制和参与者互询机制
协调者wait,超时后发送global-abort
参与者init,超时后中止本地事务,发送vote-abort
参与者ready,询问另外的参与者Q,若Q是COMMIT,则COMMIT;abort,init -> abort
2pc何时出问题:若Q是ready,则询问其他参与者,若其他参与者都处于ready状态,这是2PC无法解决的,所有参与者进入阻塞