分布式+zookeeper八股文

1、zookeeper:

        zookeeper的节点组织结构:与标准文件系统的名称空间非常相似        

 

        zookeeper的节点包括三种类型:      

  • 「持久节点」(persistent node)节点会被持久
  • 「临时节点」(ephemeral node),客户端断开连接后,ZooKeeper 会自动删除临时节点
  • 「顺序节点」(sequential node),每次创建顺序节点时,ZooKeeper 都会在路径后面自动添加上10位的数字,从1开始,最大是2147483647 (2^32-1)

         zookeeper的系统架构

        Zookeeper 集群中「Server有三种角色」,Leader、Follower 和 Observer

  • 「Leader」:负责投投票的发起与决议,更新系统状态,写数据
  • 「Follower」:用于接收客户端请求并用来返回结果,在选主过程中参与投票
  • 「Observer」:可以接受客户端连接,将「写请求转发给leader」节点,但是不参与投票过程,只「同步leader状态」,主要存在目的就是「为了提高读取效率」

        将 server 分为三种是为了「避免太多的从节点参与过半写」的过程,导致影响性能,这样 Zookeeper 只要使用一个几台机器的小集群就可以实现高性能了,如果要横向扩展的话,只需要增加 Observer 节点即可。

        Zookeeper 建议集群节点个数为奇数,只要「超过一半的机器」能够正常提供服务,那么整个集群都是可用的状态。

        ZooKeeper 启动时,将从实例中选举一个 leader,「Leader 负责处理数据更新」等操作,一个更新操作成功的标志是当且仅当大多数 Server 在内存中成功修改数据。每个 Server 在内存中存储了一份数据。

 

        zookeeper的leader如果挂了怎么办

  • 1.「变更状态」。Leader 挂后,余下的非 Observer 服务器都会讲自己的服务器状态变更为 LOOKING,然后开始进入 Leader 选举过程。

  • 2.每个「非 Observer」 的 Server 会「发出一个投票」。和启动过程一致。

  • 3.「接收」来自各个服务器的「投票」。与启动时过程相同。

  • 4.「处理投票」。与启动时过程相同。

  • 5.「统计投票」。与启动时过程相同。

  • 6.「改变服务器的状态」。与启动时过程相同。

        

        Zookeeper 会有数据不一致的情况发生吗

        还是会有的,因为 Zookeeper 采用的是「过半写」机制,意味着「3台服务器只要有两台写成功就代表整个集群写成功」,如果刚好有请求打在这台还「未写的服务器」上就查询不到该数据,就会有数据不一致的情况产生。

        zookeeper核心功能是

        1、服务注册发现

        2、近似与服务注册发现的配置管理功能

        3、稳定实现分布式锁

        1、服务注册发现

                服务提供方:

                        a、上线后要通知zookeeper,在"/XXX服务/"下创建临时节点。

                        b、周期性的不停注册自己,也就是保持和zookeeper的心跳,alive

                服务使用方:

                        a、也需要告诉zookeeper,自己是一个使用方

                        b、从"/XXX服务/"下创建的临时节点,作为自己使用的服务端

         2、其他近似与服务注册发现的配置管理功能:

        以管理主从型系统为例:slave注册一个临时节点,master被通知,过一段时间slave挂了,master知道了。

        3、稳定实现分布式锁

        利用zookeeper的临时顺序节点,每个需求抢占分布式锁的客户端们,都创建自己的临时顺序节点,创建id=1的客户端首先抢到锁,创建id=2的客户端则watch这个id=1的节点的销毁事件,然后以此类推,创建id=n的客户端监听id=n-1节点的销毁事件。

        扩展:分布式读写锁

        对于需要读的:拉取目录下全部节点,只要自己前边没有写节点,那么就可以读

                                                                     如果前边有写节点,watch最近的写节点的销毁事件

        对于需要写的:拉取目录下全部节点,如果自己是第一个节点(id=1),那么就可以写

                                                                     否则,watch最近的读或写节点的销毁事件

        

2、分布式

        2.0、分布式的本质:

        什么叫去中心化,去中心化不是没有中心了,而是说每个节点都可能可以成为中心。目的是不希望因为某个节点出现问题导致整个系统出现问题,也就是保证高可用。

        

        2.1、分片的方式

                一致性hash:

                        原始的简单一致性hash:

                                比如我们有三台机器,使用IP地址哈希后在环空间的位置如图:

                                现在有ObjectA,ObjectB,ObjectC三个数据对象,经过哈希计算后,在环空间上的位置如下:

                                根据一致性算法,Object A-> NodeA,ObjectB -> NodeB, ObjectC -> NodeC 

                                具体的就是,通过二分查找,找到第一个比object的hash值大的node的hash值。

                                 

                                假设我们的Node C宕机了,我们从图中可以看到,A、B不会受到影响,只有Object C对象被重新定位到Node A。所以我们发现,在一致性Hash算法中,如果一台服务器不可用,受影响的数据仅仅是此服务器到其环空间前一台服务器之间的数据

                                另外一种情况,现在我们系统增加了一台服务器Node X :

                                 ObjectA、ObjectB没有受到影响,只有Object C重新定位到了新的节点X上

                        高级一致性hash:

                                如果服务节点没有那么多,那么会造成大量的请求,去往下一个节点处理,造成下一个节点负载暴增。

                                解决:引入虚拟节点概念:

                                图中的A1、A2、B1、B2、C1、C2、D1、D2都是虚拟节点,机器A负载存储A1、A2的数据,机器B负载存储B1、B2的数据,机器C负载存储C1、C2的数据。由于这些虚拟节点数量很多,均匀分布,因此不会造成“雪崩”现象 。

                                因为当某真实节点崩溃,其原先负载处理的请求,会散列在不同真实节点。

                hash槽:

                        固定的槽位区间和机器节点的关系。Redis cluster的方式。

         2.2、raft

                Raft是一个用于管理日志一致性的协议。它将分布式一致性分解为多个子问题:Leader选举(Leader election)、日志复制(Log replication)、安全性(Safety)、日志压缩(Log compaction)等。同时,Raft算法使用了更强的假设来减少了需要考虑的状态,使之变的易于理解和实现。Raft将系统中的角色分为领导者(Leader)、跟从者(Follower)和候选者(Candidate):

  • Leader:接受客户端请求,并向Follower同步请求日志,当日志同步到大多数节点上后告诉Follower提交日志。

  • Follower:接受并持久化Leader同步的日志,在Leader告之日志可以提交之后,提交日志。

  • Candidate:Leader选举过程中的临时角色

                leader选举完成后,只有leader和follower两种角色了。

                重点是日志复制(保证数据一致性):

                Leader选出后,就开始接收客户端的请求。Leader把请求作为日志条目(Log entries)加入到它的日志中,然后并行的向其他服务器发起 AppendEntries RPC复制日志条目。当这条日志被复制到大多数服务器上,Leader将这条日志应用到它的状态机并向客户端返回执行结果。

                日志由有序编号(log index)的日志条目组成,每个日志条目包含它被创建时的任期号(term)和用于状态机执行的命令。

  • 客户端的每一个请求都包含被复制状态机执行的指令。

  • leader把这个指令作为一条新的日志条目添加到日志中,然后并行发起 RPC 给其他的服务器,让他们复制这条信息。

  • 假如这条日志被安全的复制,领导人就应用这条日志到自己的状态机中,并返回给客户端。

  • 如果 follower 宕机或者运行缓慢或者丢包,leader会不断的重试,直到所有的 follower 最终都复制了所有的日志条目。

        

                Raft数据一致性如何实现:

                主要是通过日志复制实现数据一致性,leader将请求指令作为一条新的日志条目添加到日志中,然后发起RPC 给所有的follower,进行日志复制,进而同步数据。

                最后的重点是:

  • 当leader挂掉后,时钟最先跑完的follower发起重新选举操作,选出一个新的leader。

  • 成员变更的时候会发起选举操作。(Rebalance)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值