zoukankan      html  css  js  c++  java
  • kafka的数据可靠性保证

    一、ACK机制

      为保证 producer 发送的数据,能可靠的发送到指定的 topic,topic 的每个 partition 收到 producer 发
    送的数据后,都需要向 producer 发送 ack(acknowledgement 确认收到),如果 producer 收到
    ack,就会进行下一轮的发送,否则重新发送数据。

    二、副本同步策略

      方案一:半数以上完成同步,就发送ACK
      优点:低延迟
      缺点:选举新的leader时,容忍N台节点的故障,需要2N+1台副本
     
      方案二:全部完成同步,才发送ACK
      优点:选举新的leader时,容忍N台节点的故障,需要N+1台副本
      缺点:延迟高
     
    Kafka 选择了第二种方案,原因如下:
    1. 同样为了容忍 n 台节点的故障,第一种方案需要 2n+1 个副本,而第二种方案只需要 n+1个副本,
    第一种方案会造成大量数据的冗余。
    2.虽然第二种方案的网络延迟会比较高,但网络延迟对kafka的影响较小

    三、ISR机制

      采用第二种方案之后,设想以下情景:leader 收到数据,所有 follower 都开始同步数据, 假如有一个follower因为某种故障,迟迟不能与 leader 进行同步,那 leader就要一直等下去,直到它完成同步才能发送 ack。如何破解这个问题呢?
    Leader 维护了一个动态的 in-sync replica set (ISR),意为和 leader 保持同步的 follower 集合。当 ISR中的 follower 完成数据的同步之后,leader 就会给客户端发送 ack。如果 follower长时间未向leader同步数据,则该follower将被踢出ISR,该时间 阈值由replica.lag.time.max.ms参数设定。Leader 发生故障之后,就会从 ISR 中选举新的 leader。

    四、可靠级别

      并不是所有场景都需要数据完全可靠,例如某些日志都是一些数据是可以容忍少量数据丢失的,所以没
    有必要等待ISR中的 follower 全部接收成功在发送ACK。
    因此Kafka为用户提供了三种可靠性级别,用户根据对可靠性和延迟的要求进行权衡,自行选择级别。
    acks:
      0:producer不等待broker的ack,提供了最低延迟,broker一接收到还没有写入磁盘就已经返回,当broker故障时可能丢失数据
      1:producer等待broker的ack,partition的leader落盘成功后返回ack,如果在follower同步成功之前leader故障,那么就会丢失数据
      -1 or all:producer等待broker的ack,partition的leader和follower全部落盘成功后才返回ack,但是如果在follower同步成功后,broker发送ack之前,leader发生故障,那么会造成数据重复

    五、故障处理

      1、follower故障

      follower发生故障后会被临时踢出ISR,待该follower恢复后,follower会读取本地磁盘记录的上次HW,并将log文件高于HW的部分截取掉,从HW开始向leader进行同步。等待follower的LED大于等于该partition的HW,即Follower追上leader之后,就可以重新加入ISR

      2、leader故障

      leader发生故障之后,会从ISR中选出一个新的leader,之后为保证多副本之间的数据一致性,其余的follower会先将各自的log文件高于HW的部分截掉,然后从新的leader同步数据。注意:这只能保证副本的之间的数据一致性,并不能保证数据不丢失和不重复

    六、Exactly Once语义

    将服务器的 ACK 级别设置为-1,可以保证 Producer 到 Server 之间不会丢失数据,即 At Least Once语义。相对的,将服务器 ACK 级别设置为 0,可以保证生产者每条消息只会被 发送一次,即 At MostOnce 语义。
    即:
      ack=-1:At Least Once 不丢数据可能重复
      ack=0:At Most Once 会丢数据,但不会重复
      如何实现Exactly Once呢?

      1、0.11版本之前

        At Least Once + 下游系统自己处理幂等性=Exactly Once

      2、0.11版本及以后

        0.11版本引入了一项重大特性:幂等性。所谓的幂等性就是指 Producer 不论 向 Server 发送多少次重
      复数据,Server 端都只会持久化一条。幂等性结合 At Least Once 语 义,就构成了 Kafka 的 Exactly
      Once 语义。即:
      At Least Once + 幂等性 = Exactly Once
      要启用幂等性,只需要将 Producer 的参数中 enable.idompotence 设置为 true 即可。当true,acks默认all

      3、幂等性的实现

        Kafka 的幂等性实现其实就是将原来下游业务需要做的去重放在了数据上游。开启幂等性的 Producer
      在 初始化的时候会被分配一个 PID,发往同一 Partition 的消息会附带 Sequence Number。而 Broker
      端会对<PID, Partition, SeqNumber>做缓存,当具有相同主键的消息提交时,Broker 只 会持久化一条
      但是 PID 重启就会变化,同时不同的 Partition 也具有不同主键,所以幂等性无法保证跨分区跨会话的
      Exactly Once。
     
      特别注意:所谓Exactly Once就是生产者发给Kafka多少数据,Kafka刚刚不多不少的存储多少数据。
        至于Kafka能不能保证Exactly Once都根消费者没关系。
        基于At Least Once + 幂等性(下游或者kafka自己实现)无法实现跨会话的Exactly Once
     
     

  • 相关阅读:
    JS复制内容到剪切板
    mysql root密码的重设方法(转)
    php生成excel文件示例代码(转)
    php读取文件内容的三种方式(转)
    使用火蜘蛛采集器Firespider采集天猫商品数据并上传到微店
    Mac Android8.0源码编译笔记
    开源 高性能 高可用 可扩展
    开源 模式
    开源 算法 数据结构
    mdb
  • 原文地址:https://www.cnblogs.com/lrxvx/p/13833923.html
Copyright © 2011-2022 走看看