凌云时刻 · 技术

导读:通过上一章节,我们知道了Kafka的Message是如何持久化的,知道了保证高可用性、稳定性的策略。这一节来看看Kafka中如何生产Message以及相关的策略。

作者 | 计缘

来源 | 凌云时刻(微信号:linuxpk)

Producer

简而言之,Producer就负责往Topic里发送数据,或者说写入数据。换言之,就是往组成这个Topic的一至多个Partition里写入数据。这里有三点需要注意:

  • 我们只需要通过Producer产生数据,往Topic里塞既可。Producer会自动去选择正确的、合适的Broker和Partition持久化数据。

  • Producer默认采用轮询的机制选择Broker往Partition里持久化数据的。

  • 如果其中有一个Broker挂了,当它再恢复时,Producer会自动接纳它。

Message Keys

Producer默认采用轮询的机制选择Broker往Partition里持久化数据。但当我们需要根据数据中的某个字段按Partition进行分组或者排序时,就需要在每条Message里添加Key,这个Key可以是数字,也可以是字符串等等。然后相同Key的Message永远会持久化到同一个Partition。

Acks

Producer在发送生产出的数据给Broker时,可以选择三种模式,称为acks,它是Acknowledgment的缩写。意思是Broker对Producer即将发送来的数据采用何种确认方式。

acks=0

在该模式下,Producer不会等待Broker的确认反馈,即不关心Broker是否正确的将发送来的数据持久化,所以在这种模式下,很有可能会丢失数据。因为如果Broker挂了,Producer不会被通知到,所以还会不停的发送数据导致数据丢失。在对数据完整性需求不强烈的场景下,这种模式可以提高性能。

acks=1

默认采用的模式,该模式下Producer会等待Leader Broker的确认反馈,当Broker确实将数据持久化到至少一个Partition中后,给予Producer确认反馈,Producer才会继续发送数据。该模式下有几点需要注意:

  • 不保证Replicas也持久化了数据。

  • 当Producer没有收到Broker的确认反馈时,Producer会尝试重新发送数据。

  • 当Leader Broker挂了,但是Replicas又没有持久化数据时,还是会丢失数据。

  • 该模式只能说是可以有效防止数据丢失。

acks=all

该模式下,Producer同样需要等待Broker的确认,但是确认更为严格,需要所有的Partition(Leader + Replicas)都持久化数据后才返回确认信息。这种模式下,只要Replicas足够多,数据基本不会丢失。

在该模式下,还有一个重要的参数min.insync.replicas需要配置。该参数的意思是当acks=all时,至少有多少个Replicas需要确认已成功持久化数据,这个Replicas数量也包括Leader。

举个例子,假设有三个Broker,参数为min.insync.replicas=2replication.factor=3acks=all,那么Producer每次发送Message时,都需要至少2个Broker给予确认反馈,换句话说,在这个Kafka集群中,只能允许一个Broker挂掉。如果min.insync.replicas=3,那么一个Broker都不能挂,否则Producer在发送Message时会收到NOT_ENOUGH_REPLICAS的异常。

Retry

有时候Producer发送Message失败可能并不是因为Broker挂了,可能是因为网络问题,没有连接到Broker等等。这种问题可能在很短暂的时间内就会自动修复,那么在这种情况下,我们希望Producer在发送失败后能重新尝试发送。这里就需要设置retries这个参数,意思就是重试的次数,默认是0次,可以根据实际业务情况设置。

但是当设置了retries参数大于0后,有可能会带来新的问题。假如我们需要相同Key的Message进入特定的Partition,并且是要严格按照Producer生产Message的顺序排序。那么此时如果第一条Message发送失败,第二条Message发送成功了,第一条通过重试发送成功了,那Message的顺序就发生了变化。

这里又会引出一个参数max.in.flight.requests.per.connection,这个参数默认是5,意思是在被Broker阻止前,未通过acks确认的发送请求最大数,也就是在Broker处排队等待acks确认的Message数量。所以刚才那个场景,第一条和第二条Message都在Broker那排队等待确认放行,这时第一条失败了,等重试的第一条Message再来排队时,第二条早都通过进去了,所以排序就乱了。

如果想在设置了retries还要严格控制Message顺序,可以把max.in.flight.requests.per.connection设置为1。让Broker处永远只有一条Message在排队,就可以严格控制顺序了。但是这样做会严重影响性能(接收Message的吞吐量)。

Indempotent Producer

在实际情况中,经常会遇到一个现象,那就是当Broker给Producer返回acks确认时,网络出异常了,导致Producer没有收到ack确认,于是,Producer进行重试。如果Consumer的Offset策略(在后续章节会介绍)是at least once或者是exactly once,那么第一次对Message就已经进行了处理,比如入库。那么第二次会对相同的Message再做一次处理,对相同数据进行重复处理,势必会引起业务上的错误。整个过程如下图所示:

所以这就需要幂等Producer来保证我们处理数据的唯一性。Kafka在0.11版本之后,就为我们提供了定义幂等Producer的能力,可以通过将enable.idempotence.config参数设置为true来定义幂等Producer。将Producer定义为幂等后,还要设置其他对应的参数:

  • retries=Integer.MAX_VALUE

  • max.in.flight.requests.per.connection=1 (Kafka >= v0.11 & < v1.1)

  • max.in.flight.requests.per.connection=5 (Kafka >= v1.1)

  • acks=all

如此设置后,可以有效防止重复消费Message,整个过程就会如下图所示:

Message Compression

消息压缩的作用不言而喻:

  • 加快网络传输速度,减少消息延迟。

  • 更有效的利用磁盘空间。

  • 加快消息吞吐率。

只需要设置compression.type参数,该参数默认是none,可选项有gziplz4snappy。建议使用lz4或者snappy

Message Batch

上面介绍了max.in.flight.requests.per.connection参数,默认会在Broker那排队5条Message,那么如果第六条来了怎么办呢?这时候Kafka会自动开启批量处理Message的模式,将这6条Message作为一个批次进行处理。这一个批次可以看作是一次Message处理请求。

开启批量模式后,会引出两个参数:

  • linger.ms:每次批量处理的间隔时间。如果设为5,那么就是每5毫秒对Message进行一次批量处理。

  • batch.size:每个批次的最大字节数,默认是16KB,可以设置为32KB或者64KB,可以提高性能。

过程如下图所示:

Producer Buffer

在大多数情况下,Consumer消费Message的速率是远不如Producer生产Message的速率的。所以Producer有一个缓存机制,将Broker还没来得及接收的Message缓存在内存中。缓存的大小可以通过buffer.memory配置,默认大小是32MB。默认存储时间为7天,这个时间可以通过设置Broker的offset.retention.minutes属性改变。

如果Producer的缓存被打满后,Producer会被阻塞,阻塞的最大时间可以通过max.block.ms配置,默认大小是60秒。

概括一下,就是当Producer生产Message的速率大于Broker接收Message(Consumer消费数据)的速率时,Producer会把Broker还没来得及接收的Message存在缓存里(内存),当存满设置的缓存大小后,Producer将不再发送Message给Broker,也就是进入阻塞状态,如果在设置的阻塞时间内,缓存还没有被释放出有用空间,那么Producer将抛出异常。

总结

这一章节我们了解了Kafka的Producer,介绍很重要的Acks机制、Retry机制、幂等机制以及消息批次机制等。这些和我们满足性能方面的需求息息相关,同时我们也进一步了解了Kafka是如何保证业务层面的高可用性的。希望能给小伙伴们带来帮助。

END

往期精彩文章回顾

Kafka从上手到实践 - 庖丁解牛:Partition

Kafka从上手到实践 - 庖丁解牛:Topic & Broker | 凌云时刻

Kafka从上手到实践 - 初步认知:MQ系统

进阶之路:深入解读 Java 堆外内存

干货:一文看懂Apache Ranger

吴翰清:有变革的需求,才有技术的诞生

云原生时代,消息中间件的演进路线

如何提升微服务的幸福感

长按扫描二维码关注凌云时刻

每日收获前沿技术与科技洞见

Kafka从上手到实践 - 庖丁解牛:Producer | 凌云时刻相关推荐

  1. Kafka+Storm+HDFS整合实践

    2019独角兽企业重金招聘Python工程师标准>>> 在基于Hadoop平台的很多应用场景中,我们需要对数据进行离线和实时分析,离线分析可以很容易地借助于Hive来实现统计分析,但 ...

  2. Kafka复习计划 - 客户端实践及原理(消费者组/位移/请求处理过程)

    Kafka复习计划 - 客户端实践及原理(消费者组/位移/请求处理过程) 前言 一. 消费组 1.1 Rebalance 重平衡 1.2 Coordinator 协调者 1.3 如何尽量避免消费者组重 ...

  3. 深入理解Kafka核心设计与实践原理_01

    深入理解Kafka核心设计与实践原理_01 01_初识Kafka 1.1 基本概念 1.2 安装与配置 1.3 生产与消费 1.4 服务端参数配置 01_初识Kafka 1.1 基本概念 一个典型的 ...

  4. Kafka深度解析(如何在producer中指定partition)(转)

    原文链接:Kafka深度解析 背景介绍 Kafka简介 Kafka是一种分布式的,基于发布/订阅的消息系统.主要设计目标如下: 以时间复杂度为O(1)的方式提供消息持久化能力,即使对TB级以上数据也能 ...

  5. 《深入理解Kafka:核心设计与实践原理》笔误及改进记录

    2019年2月下旬笔者的有一本新书--<深入理解Kafka:核心设计与实践原理>上架,延续上一本<RabbitMQ实战指南>的惯例,本篇博文用来记录现在发现的一些笔误,一是给购 ...

  6. 阿里云 VS AWS,谁能赢得上云战役 | 凌云时刻

    凌云时刻 · 洞见 导读:云计算是科技巨头必争的战场,那么上云战役的上半场结束了吗?在AWS领跑.IBM all in的赛道内,中国企业是否能够突围?未来的格局,会是三头鼎立.各分天下吗? 作者 | ...

  7. 独家:为了永不停机的计算服务 - 五月月刊 | 凌云时刻

    凌云时刻 · 极鲜速递 导读:伟大的事业非一日所能成就,不积小流,无以成江海.今日,带你看阿里云智能基础产品在五月所积"跬步". 作者 | 阿里云基础产品 来源 | 凌云时刻(微信 ...

  8. 乘风破浪的中国数据库 | 凌云时刻

    凌云时刻 · 洞见 导读:从80年代萨师煊教授的一行板书,到今天国产数据库的百花齐放,四十年科技自研,中国数据库都经历了什么? 作者 | 丹如 来源 | 杭派工程师 前言 "科技行业已经没有 ...

  9. 重磅发布!阿里云混合云:全栈建云、智能管云、极致用云 | 凌云时刻

    凌云时刻 · 极鲜速递 导读:6月9日, 2020阿里云峰会在云端召开,阿里云混合云产品总监谢宁出席峰会并发布阿里云混合云战略:全栈建云.智能管云.极致用云.阿里云混合云是国内首个大规模成熟商用的原生 ...

  10. 阿里云超算战纪 | 凌云时刻

    凌云时刻 · 故事 撰文| 卢晓明 编辑| 猛哥 图源| 受访者及unsplash 楔子 今人不见古时月,今月曾经照古人. 人生代代无穷,月下始终有一批批匠人.学者.工程师,举头而思,低头而作,奋斗无 ...

最新文章

  1. AutoML前沿技术与实践经验分享 | 免费报名
  2. Maxon Cinema 4D Studio S22.114中文版
  3. 彻底吃透Web服务器、容器、应用程序服务器与反向代理
  4. 纠正网上流传的SQL取某一时间的当月第一天和最后一天的时间写法
  5. 18款 非常实用 jquery幻灯片图片切换
  6. 赢在微点答案专区英语_2019年KPL秋季赛总决赛明日开启 线上观赛赢海量福利
  7. Python 检测系统时间,k8s版本,redis集群,etcd,mysql,ceph,kafka
  8. 【LeetCode】242. Valid Anagram
  9. svn删除文件出错的经验总结
  10. 用matlab的毕业设计,毕业设计课题: 用 MATLAB.ppt
  11. ubuntu20.04下QT安装
  12. 叮当管家显示服务器错误,叮当管家【制卡器故障】
  13. c语言中正确的常量表达式,C语言常量变量表达式
  14. bittorrent下载_面向初学者的BitTorrent:如何开始下载Torrent
  15. linux交互式脚本编写,谢烟客---------Linux之bash脚本编程---用户交互
  16. 常见笔顺错误的字_常用汉字中易写错笔顺的字有哪些?
  17. cp -rv linux,Linux基础知识(二)
  18. php图片输出特殊符号,php输出特殊符号
  19. css 隐藏滚动条 竖向y滚动,横向x不滚动
  20. /etc/init.d/sshd配置SSHD路径忘记修改导致启动失败

热门文章

  1. VMware下CentOS安裝完後認唔到網卡
  2. tensorflow图片预处理,随机亮度,旋转,剪切,翻转。
  3. 修改Apache配置文件开启gzip压缩传输
  4. 20200726每日一句
  5. Python3入门机器学习经典算法与应用 第3章 更多相关操作
  6. 传智播客 多继承以及MRO顺序 学习笔记
  7. pdf文档有时打开乱码的解决方案
  8. 找到驱动精灵屏幕保护图片
  9. leapmotion 控制面板的启动
  10. C#生成dll, VS或unity调用