这几天很忙,但是我现在给我的要求是一周至少要出一篇文章,所以先拿这篇笔记来做开胃菜,源码分析估计明后两天应该能写一篇。给自己加油~,即使没什么人看。

可靠性

如何保证消息不丢失

Kafka只对“已提交”的消息(committed message)做有限度的持久化保证。

已提交的消息

当Kafka的若干个Broker成功地接收到一条消息并写入到日志文件后,它们会告诉生产者程序这条消息已成功提交。

有限度的持久化保证

假如一条消息保存在N个Kafka Broker上,那么至少这N个Broker至少有一个存活,才能保证消息不丢失。

丢失数据案例

生产者程序丢失数据

由于Kafka Producer是异步发送的,调用完producer.send(msg)并不能认为消息已经发送成功。

所以,在Producer永远要使用带有回调通知的发送API,使用producer.send(msg,callback)。一旦出现消息提交失败的情况,可以由针对性地进行处理。

消费者端丢失数据

消费者是先更新offset,再消费消息。如果这个时候消费者突然宕机了,那么这条消息就会丢失。

所以我们要先消费消息,再更新offset位置。但是这样会导致消息重复消费。

还有一种情况就是consumer获取到消息后开启了多个线程异步处理消息,而consumer自动地向前更新offset。假如其中某个线程运行失败了,那么消息就丢失了。

遇到这样的情况,consumer不要开启自动提交位移,而是要应用程序手动提交位移。

最佳实现

  1. 使用producer.send(msg,callback)。
  2. 设置acks = all。acks是Producer的参数,代表了所有副本Broker都要接收到消息,该消息才算是“已提交”。
  3. 设置retries为一个较大的值。是Producer的参数,对应Producer自动重试。如果出现网络抖动,那么可以自动重试消息发送,避免消息丢失。
  4. unclean.leader.election.enable = false。控制有哪些Broker有资格竞选分区的Leader。表示不允许落后太多的Broker竞选Leader。
  5. 设置replication.factor>=3。Broker参数,冗余Broker。
  6. 设置min.insync.replicas>1。Broker参数。控制消息至少要被写入到多少个副本才算是“已提交”。
  7. 确保replication.factor>min.insync.replicas。如果两个相等,那么只要有一个副本挂机,整个分区就无法正常工作了。推荐设置成replication.factor=min.insync.replicas+1.
  8. 确保消息消费完成在提交。Consumer端参数enbale.auto.commit,设置成false,手动提交位移。

解释第二条和第六条:

如果ISR中只有1个副本了,acks=all也就相当于acks=1了,引入min.insync.replicas的目的就是为了做一个下限的限制:不能只满足于ISR全部写入,还要保证ISR中的写入个数不少于min.insync.replicas。

幂等性

在0.11.0.0版本引入了创建幂等性Producer的功能。仅需要设置props.put(“enable.idempotence”,true),或props.put(ProducerConfig.ENABLE_IDEMPOTENCE_CONFIG,true)。

enable.idempotence设置成true后,Producer自动升级成幂等性Producer。Kafka会自动去重。Broker会多保存一些字段。当Producer发送了相同字段值的消息后,Broker能够自动知晓这些消息已经重复了。

作用范围:

  1. 只能保证单分区上的幂等性,即一个幂等性Producer能够保证某个主题的一个分区上不出现重复消息。
  2. 只能实现单回话上的幂等性,这里的会话指的是Producer进程的一次运行。当重启了Producer进程之后,幂等性不保证。

事务

Kafka在0.11版本开始提供对事务的支持,提供是read committed隔离级别的事务。保证多条消息原子性地写入到目标分区,同时也能保证Consumer只能看到事务成功提交的消息。

事务性Producer

保证多条消息原子性地写入到多个分区中。这批消息要么全部成功,要不全部失败。事务性Producer也不惧进程重启。

Producer端的设置:

  1. 开启enable.idempotence = true
  2. 设置Producer端参数 transactional.id

除此之外,还要加上调用事务API,如initTransaction、beginTransaction、commitTransaction和abortTransaction,分别应对事务的初始化、事务开始、事务提交以及事务终止。

如下:

producer.initTransactions();
try {
producer.beginTransaction();
producer.send(record1);
producer.send(record2);
producer.commitTransaction();
} catch (KafkaException e) {
producer.abortTransaction();
}

这段代码能保证record1和record2被当做一个事务同一提交到Kafka,要么全部成功,要么全部写入失败。

Consumer端的设置:

设置isolation.level参数,目前有两个取值:

  1. read_uncommitted:默认值表明Consumer端无论事务型Producer提交事务还是终止事务,其写入的消息都可以读取。
  2. read_committed:表明Consumer只会读取事务型Producer成功提交事务写入的消息。注意,非事务型Producer写入的所有消息都能看到。

Kafka笔记—可靠性、幂等性和事务的更多相关文章

  1. 可靠性、幂等性和事务 Kafka

    Kafka笔记—可靠性.幂等性和事务   分类: 消息队列 标签: kafka 这几天很忙,但是我现在给我的要求是一周至少要出一篇文章,所以先拿这篇笔记来做开胃菜,源码分析估计明后两天应该能写一篇.给 ...

  2. kafka 幂等生产者及事务(kafka0.11之后版本新特性)

    1. 幂等性设计1.1 引入目的生产者重复生产消息.生产者进行retry会产生重试时,会重复产生消息.有了幂等性之后,在进行retry重试时,只会生成一个消息. 1.2 幂等性实现1.2.1 PID ...

  3. Kafka数据可靠性深度解读

    原文链接:http://www.infoq.com/cn/articles/depth-interpretation-of-kafka-data-reliability Kafka起初是由Linked ...

  4. 【Kafka】Kafka数据可靠性深度解读

    转帖:http://www.infoq.com/cn/articles/depth-interpretation-of-kafka-data-reliability Kafka起初是由LinkedIn ...

  5. kafka数据可靠性深度解读【转】

    1 概述 Kakfa起初是由LinkedIn公司开发的一个分布式的消息系统,后成为Apache的一部分,它使用Scala编写,以可水平扩展和高吞吐率而被广泛使用.目前越来越多的开源分布式处理系统如Cl ...

  6. kafka笔记6

    我们讨论可靠性时,一般使用保证这个词,它是确保系统在各种不同的环境下能够发生一致的行为.Kafka可以在哪些方面作出保证呢? 1.Kafka可以保证分区消息的顺序 2.只有消息被写入分区的所有同步副本 ...

  7. 基于Kafka消息驱动最终一致事务(二)

    实现用例分析 上篇基于Kafka消息驱动最终一致事务(一)介绍BASE的理论,接着我们引入一个实例看如何实现BASE,我们会用图7显示的算法实现BASE.

  8. 基于Kafka消息驱动最终一致事务(一)

    基本可用软状态最终一致事务 本用例分两个数据库分别是用户库和交易库,不使用分布式事务,使用基于消息驱动实现基本可用软状态最终一致事务(BASE).现在说明下事务逻辑演化步骤,尊从CAP原则,即分布式系 ...

  9. Kafka笔记整理(三):消费形式验证与性能测试

    Kafka消费形式验证 前面的<Kafka笔记整理(一)>中有提到消费者的消费形式,说明如下: .每个consumer属于一个consumer group,可以指定组id.group.id ...

随机推荐

  1. restapi(3)- MongoDBEngine : MongoDB Scala编程工具库

    最近刚好有同事在学习MongoDB,我们讨论过MongoDB应该置于服务器端然后通过web-service为客户端提供数据的上传下载服务.我们可以用上节讨论的respapi框架来实现针对MongoDB ...

  2. 1关于如何用Navicat连接到xampp安装的mysql

    打开xampp,打开config打开my.ini. 检索bind-address,后面的数字是你的IP地址 检索 port,后面的数字是端口号 打开Navicat新建连接,选中mysql 连接名随便起 ...

  3. Java 8 Stream实践

    [**前面的话**]Java中的Stream于1.8版本析出,平时项目中也有用到,今天就系统的来实践一下.下面借用重庆力帆队伍中我个人比较喜欢的球员来操作一波,队员的年龄为了便于展示某些api做了调整 ...

  4. linux100day(day4)--文本处理三剑客

    在介绍三剑客之前,先来认识一下通配符和正则表达式 通配符 正则表达式 作用:通过一些特殊字符,来表示一类字符内容 1.字符匹配 .     任意一个字符 [ ]   范围内的任意一个字符 [^ ] 取 ...

  5. 本地VSCode编辑远程服务器文件

    前言 先说下我的场景:服务器搭设了一系列复杂环境,然后需要使用PHP实现某些功能 选这种远程编辑的原因: 首先PHP打死我也不想装(这个现在是出了VB外最惹人厌的语言了) 然后环境比较复杂,本地装下比 ...

  6. 2321. 【NOIP普及组T1】方程

    2321. [NOIP普及组T1]方程 时间限制: 1000 ms  空间限制: 262144 KB 题目描述

  7. 由于Microsoft\VisualStudio\14.0\Designer\ShadowCache导致的一个异常问题

    本文引用了一个DynamicDataDisplay和DynamicControl两个类库,本来使用的时候都时正常的,愉快的运行着. DynamicDataDisplay:这是一个用于动态数据可视化的W ...

  8. MongoDB的一些高级语法.md

      MongoDB的一些高级语法 AND 和 OR操作 AND操作 OR操作 嵌入式文档 插入 查询 数组(Array)字段 插入 查询 聚合(Aggregation) 筛选数据 修改字段 注意事项 ...

  9. springboot 项目的https的发布

    1.生成密钥证书 生成命令: keytool -genkey -alias tomcat -storetype PKCS12 -keyalg RSA -keysize -keystore keysto ...

  10. 【Python3爬虫】快就完事了--使用Celery加速你的爬虫

    一.写在前面 在上一篇博客中提到过对于网络爬虫这种包含大量网络请求的任务,是可以用Celery来做到加速爬取的,那么,这一篇博客就要具体说一下怎么用Celery来对我们的爬虫进行一个加速! 二.知识补 ...