上一篇对Kafka做了简单介绍,还没看的朋友可以点击下方链接。

Kafka从入门到放弃(一) —— 初识别Kafka

消息中间件必须与生产者和消费者一起存在才有意义,这次先来聊聊Kafka的生产者。

在开始之前,先了解一下消息在Kafka中是如何存储的,如下图所示,一般我们称那些数字为offset(偏移量)一般来说,消息在持久化后应该是有序的,这里的有序是针对分区的,而不是针对 Topic 的。

而且,生产者写入消息时,是往 Leader 写入,Follower 从 Leader 进行复制。

别看生产者只是发消息,调用 API 也是几行代码,但它的学问多着呢。为更好地理解后面的内容,请带着以下问题阅读:

  • 生产者发送消息前会做什么准备?
  • 生产者发送消息怎么保证数据不丢失?
  • 生产者发送消息如何保证消息有序性?
  • 生产者发送的消息是怎么分区的?

生产者设计了一个缓冲池,可以通过修改 buffer.memory 参数设置其大小;缓冲池内又有多个 Batch,当有多个消息需要写入同一个分区时,消息会先往 Batch 里面写入,等消息达到 batch.size 的时候开始发送,如果 batch.size 设置太小,生产者会频繁发送消息,带来更多的网络开销;

有些读者可能有这个疑问,如果有时候生产者生产的消息很少很小,一直达不到批次的大小,而消费者对时效性要求比较高,这种情况怎么办?其实,默认情况下,只要有线程,即使批次里只有一条消息,也会直接发送出去。但是,可以设置参数 linger.ms 来指定等待消息加入批次的时间,只要当批次消息达到 batch.size 或者等待时间达到 linger.ms 的时候,消息就会发送。

除此之外,生产者可以对消息进行压缩,以降低网络开销以及存储开销,通过设置参数 compression.type 设置相应的压缩算法。

先抛开 Kafka 现有确认机制,假如一条消息发到对应分区后,没有任何确认就紧接着发送第二条,很难不造成数据丢失。

于是我们让分区在收到消息后返回确认消息给生产者,生产者收到后发送下一条。

就这样,消息很顺利地发着,正好在 Leader 拿到最新的消息并返回确认给生产者的时候,Leader 挂了,此时,Follower 还没同步最新的消息,而生产者已经接收到了分区返回的确认,这时候还是丢了数据。

因此我们让 Leader 以及参与复制的 Follower 都收到消息后返回确认,这样就能最大程度保证消息不丢失,不过延迟较高。

针对上述的情况,Kafka 设置了一个 acks 参数,指定了必须有几个副本收到消息生产者才认为是写入成功了。

  • acks=0,生产者只管写入,不会等待 Broker 返回响应,默认成功。这种情况最容易造成数据丢失,不过吞吐量最高;
  • acks=1,Leader 收到消息后响应,生产者才认为写成功,这种也会造成丢失;
  • acks=all,Kafka 集群内部会维护一个副本清单 ISR(后续会写,再此不做描述),当 ISR 里的所有副本都收到消息,才认为写入成功,最大程度保证消息不丢失,不过可能会造成延迟较高。

另外,Kafka 还有一个参数 retries,表示当消息发送失败后,生产者重试的次数,默认为0,如果对丢失消息零容忍,那就不能设置为0.

事实上,生产者在收到分区返回的确认消息前,还是可以持续发送消息的,这个可以通过设置 max.in.flight.requests.per.connection 参数进行修改,这个参数指定了生产者在收到响应前可以发送多少个消息。

这里需要注意的是,如果这个参数不为1,而 retries 参数也不为 0 的时候,当发生重试的时候,有可能造成分区数据顺序错乱。在有些场景下,顺序是很重要的,比如分析交易流水的过程,某个第一次存款的客户先存1块钱再取1块钱是正常的,但反过来可能就有点奇怪了。

所以,如果要保证数据不丢失,同时要保证数据有序性,就需要将 retries 设置为非 0 整数,max.in.flight.requests.per.connection 设置为 1,注意不是 0.

生产者可以指定键作为分区键,如果不指定,生产者会使用轮询算法将消息均匀的发到各个分区上

但如果指定了分区键,Kafka 会使用自己的 hash 算法获得 hash 值,然后根据 hash 值发到相应的分区。

到这,回顾一下前面的几个问题,是不是有点豁然开朗了?

如果觉得写得不错,对你有帮助,麻烦点个小小的赞,谢谢!

转载请注明出处:工众号“大数据的奇妙冒险”,博客园 Lyu_zt

Kafka从入门到放弃(三) —— 详说生产者的更多相关文章

  1. Kafka从入门到放弃(三)—— 详说消费者

    之前介绍了Kafka以及生产者,包括它的一些特性和参数,这回写一下消费者. 之前没看得可以点击链接阅读. Kafka从入门到放弃(一) -- 初识Kafka Kafka从入门到放弃(二) -- 详说生 ...

  2. kafka原理和实践(三)spring-kafka生产者源码

    系列目录 kafka原理和实践(一)原理:10分钟入门 kafka原理和实践(二)spring-kafka简单实践 kafka原理和实践(三)spring-kafka生产者源码 kafka原理和实践( ...

  3. hive从入门到放弃(三)——DML数据操作

    上一篇给大家介绍了 hive 的 DDL 数据定义语言,这篇来介绍一下 DML 数据操作语言. 没看过的可以点击跳转阅读: hive从入门到放弃(一)--初识hive hive从入门到放弃(二)--D ...

  4. storm从入门到放弃(三),放弃使用《StreamId》特性。

    序:StreamId是storm中实现DAG有向无环图的重要一个特性,但是从实际生产环境来看,这个功能其实蛮影响生产环境的稳定性的,我们系统在迭代时会带来整体服务的不可用. StreamId是stor ...

  5. storm从入门到放弃(三),放弃使用 StreamId 特性

    序:StreamId是storm中实现DAG有向无环图的重要一个特性,但是从实际生产环境来看,这个功能其实蛮影响生产环境的稳定性的,我们系统在迭代时会带来整体服务的不可用. StreamId是stor ...

  6. Kafka从入门到放弃(一) —— 初识Kafka

    消息中间件的使用已经越来越广泛,基本上具有一定规模的系统都会用到它,在大数据领域也是个必需品,但为什么使用它呢?一个技术的广泛使用必然有它的道理. 背景与问题 以前一些传统的系统,基本上都是" ...

  7. robotium从入门到放弃 三 基于apk的自动化测试

      1.apk重签名   在做基于APK的自动化测试的过程中,需要确保的一点是,被测试的APK必须跟测试项目具有相同的签名,那怎么做才能确保两者拥有相同的签名呢?下面将给出具体的实现方法. 首先将被测 ...

  8. Go语言从入门到放弃(三) 布尔/数字/格式化输出

    本章主要介绍Go语言的数据类型 布尔(bool) 布尔指对或者错,也就是说bool只有两个值, True 或 False 两个类型相同的值可以使用比较运算符来得出一个布尔值 当两个值是完全相同的情况下 ...

  9. MyBatis从入门到放弃三:一对一关联查询

    前言 简单来说在mybatis.xml中实现关联查询实在是有些麻烦,正是因为起框架本质是实现orm的半自动化. 那么mybatis实现一对一的关联查询则是使用association属性和resultM ...

随机推荐

  1. CVPR 之 老照片修复

    周末闲来无事,随手整理电脑里的照片,望着一张物是人非的老相片,勾起了斑驳的回忆.忽尔转念一想,何不 PS 下,但 PhotoShop 有些大且不免费自己懒得装,于是,转向免费的图像复原软件. 网上搜来 ...

  2. [atARC110F]Esoswap

    先构造使得$p_{i}$降序(即$p_{i}=n-1-i$),只需要从后往前,不断执行$i$操作直至合法即可 正确性的证明:首先保证了$[0,n-i)$这些数字都已经出现,因此操作不会破坏已确定的数字 ...

  3. Electron快速入门之debug

    view->toggleDevelpper Tools 本地桌面调试 浏览器debug "start": "electron --inspect=5858 .&qu ...

  4. 如何隐藏shell脚本内容

    从事 Linux 开发的同学,经常需要编写 shell 脚本,有时脚本中会涉及到一些敏感内容,比如一些 IP 地址,用户名以及密码等,或者脚本中有一些关键的代码, 所有这些内容你都不想别人阅读或者修改 ...

  5. 模数不超过 long long 范围时的快速乘

    笔者的话:使用前请确保评测系统的long double严格为16B ! 模数不在 int 范围内的乘法在 OI 中运用广泛,例如Millar-Rabin,Pollard-Rho等等.这样的乘法,直接乘 ...

  6. mount 挂载详解

    挂接命令(mount) 首先,介绍一下挂接(mount)命令的使用方法,mount命令参数非常多,这里主要讲一下今天我们要用到的. 命令格式:mount [-t vfstype] [-o option ...

  7. 【Linux】非root安装Python3及其包管理

    1. Python 3.8.1安装 源码安装常规操作: wget -c https://www.python.org/ftp/python/3.8.1/Python-3.8.1.tgz tar -xv ...

  8. 【讲座】朱正江——基于LC-MS的非靶向代谢组学

    本次课程主题为<基于LC-MS的非靶向代谢组学>,主要分为代谢组学简介.代谢组学技术简介.非靶向代谢组学方法和数据采集.非靶向代谢组学数据分析和代谢物结构鉴定几个方面. 一.代谢组简介 基 ...

  9. mac系统升级导致VirtualBox报Kernel driver not installed (rc=-1908)

    一.背景 最近将我的Mac升级成了Monterey版本,结果发现之前的安装的VirtualBox虚拟机无法启动,报了如下错误. Kernel driver not installed (rc=-190 ...

  10. UE4之Slate: SImage

    概述 距离上次记录<UE4之Slate:纯C++工程配置>后已经好长时间了: 这个随笔来记录并分享一下SImage控件的使用,以在屏幕上显示一张图片: 目标 通过SImage控件的展示,学 ...