zoukankan      html  css  js  c++  java
  • Kafka核心技术与实战——14 | 幂等生产者和事务生产者是一回事吗?

    • Kafka 消息交付可靠性保障以及精确处理一次语义的实现
      • 所谓的消息交付可靠性保障,是指 Kafka 对 Producer 和 Consumer 要处理的消息提供什么样的承诺。常见的承诺有以下三种:
        • 最多一次(at most once):消息可能会丢失,但绝不会被重复发送。
        • 至少一次(at least once):消息不会丢失,但有可能被重复发送。
        • 精确一次(exactly once):消息不会丢失,也不会被重复发送。
      • Kafka 默认提供的交付可靠性保障是第二种,即至少一次
        • 消息“已提交”的含义,即只有 Broker 成功“提交”消息且 Producer 接到 Broker 的应答才会认为该消息成功发送
        • 不过倘若消息成功“提交”,但 Broker 的应答没有成功发送回 Producer 端(比如网络出现瞬时抖动),那么 Producer 就无法确定消息是否真的提交成功了
        • 因此,它只能选择重试,也就是再次发送相同的消息
        • 这就是 Kafka 默认提供至少一次可靠性保障的原因,不过这会导致消息重复发送
      • Kafka 也可以提供最多一次交付保障
        • 只需要让 Producer 禁止重试即可
        • 这样一来,消息要么写入成功,要么写入失败,但绝不会重复发送
      • 精确一次来得有吸引力
        • 大部分用户还是希望消息只会被交付一次,这样的话,消息既不会丢失,也不会被重复处理
        • 或者说,即使 Producer 端重复发送了相同的消息,Broker 端也能做到自动去重
        • 在下游 Consumer 看来,消息依然只有一条
    • 什么是幂等性(Idempotence)?
      • “幂等”这个词原是数学领域中的概念,指的是某些操作或函数能够被执行多次,但每次得到的结果都是不变的
      • 幂等性有很多好处,其最大的优势在于我们可以安全地重试任何幂等性操作,反正它们也不会破坏我们的系统状态
    • 幂等性 Producer
      • 指定 Producer 幂等性的方法很简单,仅需要设置一个参数即可
        • props.put(“enable.idempotence”, ture)
        • 或 props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG, true)
      • Kafka 自动帮你做消息的重复去重
        • 底层具体的原理很简单,就是经典的用空间去换时间的优化思路,即在 Broker 端多保存一些字段
        • 当 Producer 发送了具有相同字段值的消息后,Broker 能够自动知晓这些消息已经重复了,于是可以在后台默默地把它们“丢弃”掉
      • 我们必须要了解幂等性 Producer 的作用范围。
        • 首先,它只能保证单分区上的幂等性,即一个幂等性 Producer 能够保证某个主题的一个分区上不出现重复消息,它无法实现多个分区的幂等性
        • 其次,它只能实现单会话上的幂等性,不能实现跨会话的幂等性
        • 这里的会话,你可以理解为 Producer 进程的一次运行。当你重启了 Producer 进程之后,这种幂等性保证就丧失了。
      • 如果我想实现多分区以及多会话上的消息无重复,应该怎么做呢?
        • 答案就是事务(transaction)或者依赖事务型 Producer
        • 这也是幂等性 Producer 和事务型 Producer 的最大区别
    • 事务
      • 隔离性表明并发执行的事务彼此相互隔离,互不影响
        • 经典的数据库教科书把隔离性称为可串行化 (serializability),即每个事务都假装它是整个数据库中唯一的事务
      • Kafka 自 0.11 版本开始也提供了对事务的支持
        • 目前主要是在 read committed 隔离级别上做事情
        • 它能保证多条消息原子性地写入到目标分区,同时也能保证 Consumer 只能看到事务成功提交的消息
    • 事务型 Producer
      • 事务型 Producer 能够保证将消息原子性地写入到多个分区中
        • 这批消息要么全部写入成功,要么全部失败
        • 另外,事务型 Producer 也不惧进程的重启
        • Producer 重启回来后,Kafka 依然保证它们发送消息的精确一次处理
      • 设置事务型 Producer 的方法也很简单,满足两个要求即可:
        • 和幂等性 Producer 一样,开启 enable.idempotence = true。
        • 设置 Producer 端参数 transctional. id。最好为其设置一个有意义的名字。
        • 此外,你还需要在 Producer 代码中做一些调整
      • 在 Consumer 端,读取事务型 Producer 发送的消息也是需要一些变更的。修改起来也很简单,设置 isolation.level 参数的值即可。当前这个参数有两个取值:
        • read_uncommitted:这是默认值,表明 Consumer 能够读取到 Kafka 写入的任何消息,不论事务型 Producer 提交事务还是终止事务,其写入的消息都可以读取。很显然,如果你用了事务型 Producer,那么对应的 Consumer 就不要使用这个值。
        • read_committed:表明 Consumer 只会读取事务型 Producer 成功提交事务写入的消息。当然了,它也能看到非事务型 Producer 写入的所有消息
    • 小结
      • 简单来说,幂等性 Producer 和事务型 Producer 都是 Kafka 社区力图为 Kafka 实现精确一次处理语义所提供的工具,只是它们的作用范围是不同的
        • 幂等性 Producer 只能保证单分区、单会话上的消息幂等性
        • 而事务能够保证跨分区、跨会话间的幂等性
        • 从交付语义上来看,自然是事务型 Producer 能做的更多。
        • 不过,切记天下没有免费的午餐。比起幂等性 Producer,事务型 Producer 的性能要更差
        • 在实际使用过程中,我们需要仔细评估引入事务的开销,切不可无脑地启用事务
  • 相关阅读:
    [AX2012 R3]在SSRS报表中使用QR二维码
    [AX2012 R3]关于Alerts
    [AX2012 R3]关于Named user license report
    [AX2012]Report data provider调试
    [AX2012]Claims user
    [AX2012]发送广播邮件
    [AX 2012] Woker user request
    AX2012 R3升级CU8的一些错误
    消失的银行 读后感
    Openstack实践(1)部署使用实例及neutron网络
  • 原文地址:https://www.cnblogs.com/minimalist/p/12898876.html
Copyright © 2011-2022 走看看