• zookeeper,kafka,redis等分布式框架的主从同步策略


    1 zookeeper选主机制

    1.1 LeaderElection选举算法

    选举线程由当前Server发起选举的线程担任,他主要的功能对投票结果进行统计,并选出推荐的Server。选举线程首先向所有Server发起一次询问(包括自己),被询问方,根据自己当前的状态作相应的回复,选举线程收到回复后,验证是否是自己发起的询问(验证xid 是否一致),然后获取对方的id(myid),并存储到当前询问对象列表中,最后获取对方提议 的

    leader 相关信息(id,zxid),并将这些 信息存储到当次选举的投票记录表中,当向所有Serve r

    都询问完以后,对统计结果进行筛选并进行统计,计算出当次询问后获胜的是哪一个Server,并将当前zxid最大的Server 设置为当前Server要推荐的Server(有可能是自己,也有可以是其它的Server,根据投票结果而定,但是每一个Server在第一次投票时都会投自己),如果此时获胜的Server获得n/2 + 1的Server票数,设置当前推荐的leader为获胜的Server。根据获胜的Server相关信息设置自己的状态。每一个Server都重复以上流程直到选举出Leader。

     

    初始化选票(第一张选票): 每个quorum节点一开始都投给自己;

    收集选票: 使用UDP协议尽量收集所有quorum节点当前的选票(单线程/同步方式),超时设置200ms;

    统计选票: 1).每个quorum节点的票数;

             2).为自己产生一张新选票(zxid、myid均最大);

    选举成功: 某一个quorum节点的票数超过半数;

    更新选票: 在本轮选举失败的情况下,当前quorum节点会从收集的选票中选取合适的选票(zxid、myid均最大)作为自己下一轮选举的投票;

    异常问题的处理

    1). 选举过程中,Server的加入

    当一个Server启动时它都会发起一次选举,此时由选举线程发起相关流程,那么每个 Serve r都会获得当前zxi d最大的哪个Serve r是谁,如果当次最大的Serve r没有获得n/2+1 个票数,那么下一次投票时,他将向zxid最大的Server投票,重复以上流程,最后一定能选举出一个Leader。

    2). 选举过程中,Server的退出

    只要保证n/2+1个Server存活就没有任何问题,如果少于n/2+1个Server 存活就没办法选出Leader。

    3). 选举过程中,Leader死亡

    当选举出Leader以后,此时每个Server应该是什么状态(FLLOWING)都已经确定,此时由于Leader已经死亡我们就不管它,其它的Fllower按正常的流程继续下去,当完成这个流程以后,所有的Fllower都会向Leader发送Ping消息,如果无法ping通,就改变自己的状为(FLLOWING ==> LOOKING),发起新的一轮选举。

    4). 选举完成以后,Leader死亡

    处理过程同上。

    5). 双主问题

    Leader的选举是保证只产生一个公认的Leader的,而且Follower重新选举与旧Leader恢复并退出基本上是同时发生的,当Follower无法ping同Leader是就认为Leader已经出问题开始重新选举,Leader收到Follower的ping没有达到半数以上则要退出Leader重新选举。

    1.2 FastLeaderElection选举算法

    FastLeaderElection是标准的fast paxos的实现,它首先向所有Server提议自己要成为leader,当其它Server收到提议以后,解决 epoch 和 zxid 的冲突,并接受对方的提议,然后向对方发送接受提议完成的消息。

    FastLeaderElection算法通过异步的通信方式来收集其它节点的选票,同时在分析选票时又根据投票者的当前状态来作不同的处理,以加快Leader的选举进程。

    每个Server都一个接收线程池和一个发送线程池, 在没有发起选举时,这两个线程池处于阻塞状态,直到有消息到来时才解除阻塞并处理消息,同时每个Serve r都有一个选举线程(可以发起选举的线程担任)。

    1). 主动发起选举端(选举线程)的处理

    首先自己的 logicalclock加1,然后生成notification消息,并将消息放入发送队列中, 系统中配置有几个Server就生成几条消息,保证每个Server都能收到此消息,如果当前Server 的状态是LOOKING就一直循环检查接收队列是否有消息,如果有消息,根据消息中对方的状态进行相应的处理。

    2).主动发送消息端(发送线程池)的处理

    将要发送的消息由Notification消息转换成ToSend消息,然后发送对方,并等待对方的回复。

    3). 被动接收消息端(接收线程池)的处理

    将收到的消息转换成Notification消息放入接收队列中,如果对方Server的epoch小于logicalclock则向其发送一个消息(让其更新epoch);如果对方Server处于Looking状态,自己则处于Following或Leading状态,则也发送一个消息(当前Leader已产生,让其尽快收敛)。

    2.kafka分区的选主机制

    kafka如何解决以上选举机制的
    kafka的leader election方案解决了上述问题,它在所有的broker中选出一个controller,所有的partition的leader选举都有controller决定。controller会将leader的改变直接通过RPC的方式(比zookeeper Queue的方式更高效)通知需要为此作为响应的broker。

    原因:
    1、不用zk选举,使用controller(Controller会将leader的改变通过rpc方式通知给follower),没有zk负载过重问题
    2、也没有注册watch不会触发任何事件-惊群效应
    3、leader失败是由一个Controller进行选举并不会产生任何通信,所以不会有脑裂的情况

    问题:
    (1)Controller是如何选举出来的
    每一个broker都会在Controller path(/controller)上注册一个watch。当前controller失败时,对应的Controller path会自动消失(临时节点)。此时该watch被触发,所有活着的broker都会去竞选成为新的Controller(创建新的controller path),但是只有一个会竞选成功。竞选成功者成为新的leader。竞选失败则重新在新的Controller path上注册watch,因为zk的watch是一次性的,被触发一次之后即失效,所以需要重新注册。
    (2)如何使用Controller进行partition选举
    a、从zk中读取当前分区的所有ISR(in-sync-replicas)集合
    b、调用配置的分区算法选择分区的leader
    kafka选择分区算法:
    i、NoOpLeaderSelector–偏爱分区(SR中的第一个),并将leader发送给为此做出改变的broker,
    ii、offlinePartitionLeader–也是选择偏爱分区作为leader
    iii、reassignedPartitionLeader
    iii、preferredReplicaPartitionLeader
    iiii、ControlledShutdownLeader
    上面五中算法都使用偏爱分区作为leader,区别是选择leader之后所做的操作不同。

    4.数据同步机制

    Kafka的主从同步ISR

    kafka的主从同步,主要是针对它的broker来说。

    在kafka的broker中,同一个topic可以被分配成多个Partition,每个Partition的可以有一个或者多个replicas(备份),即会有一个leader以及0到多个Follower,在consumer读取数据的时候,只会从Leader上读取数据,Follower只是在Leader宕机的时候来替代Leader,主从同步有两种方式:同步复制和异步复制,Kafka采用的是中间策略ISR(In Sync Replicas)。

    Kafka的ISR策略
    在有数据写上Leader的时候,Leader会查看Follower组成的ISR列表,并且符合以下两点才算是属于ISR列表:

    1、broker可以维护和zookeeper的连接,zookeeper通过心跳机制检查每个节点的连接

    2、如果节点是个follow它必须能及时同步Leader的写操作,不能延时太久。

    当有写消息的时候,我们可以根据配置做如下配置:

    request.required.acks参数的设置来进行调整:
    0 ,相当于异步发送,消息发送完毕即offset增加,继续生产;相当于At most once
    1,leader收到leader replica 对一个消息的接受ack才增加offset,然后继续生产;
    -1,leader收到所有replica 对一个消息的接受ack才增加offset,然后继续生产
    Zookeeper的主从同步ZAB
    Zookeeper的zab策略脱胎于Paxos算法,默认情况下,zk中写数据时,要有一半以上的从节点写入成功,才算是写入成功。

    Redis的主从同步
    redis因为是要提升性能,所以直接采用的异步复制,当在Master上写入数据后直接返回,然后把数据快照广播给Slave,让所有的Slaves去执行操作

  • 相关阅读:
    jquery实现下拉框多选
    最好的Angular2表格控件
    CSS3阴影 box-shadow的使用和技巧总结
    存档2
    Python的编码注释# -*- coding:utf-8 -*-
    路由器与交换机区别
    TCP的流量控制
    TCP的拥塞控制
    存储管理之页式、段式、段页式存储
    什么是死锁?其条件是什么?怎样避免死锁?
  • 原文地址:https://www.cnblogs.com/wzj4858/p/11418500.html
Copyright © 2020-2023  润新知