Kafka 核心技术与实战
胡夕
Apache Kafka Committer,老虎证券技术总监
52815 人已学习
新⼈⾸单¥68
登录后,你可以任选4讲全文学习
课程目录
已完结/共 47 讲
开篇词 (1讲)
结束语 (1讲)
Kafka 核心技术与实战
15
15
1.0x
00:00/00:00
登录|注册

10 | 生产者压缩算法面面观

开放讨论
最佳实践
压缩算法对比
解压缩时机
压缩时机
压缩方法
消息格式
Kafka消息压缩算法

该思维导图由 AI 生成,仅供参考

你好,我是胡夕。今天我要和你分享的内容是:生产者压缩算法面面观。
说起压缩(compression),我相信你一定不会感到陌生。它秉承了用时间去换空间的经典 trade-off 思想,具体来说就是用 CPU 时间去换磁盘空间或网络 I/O 传输量,希望以较小的 CPU 开销带来更少的磁盘占用或更少的网络 I/O 传输。在 Kafka 中,压缩也是用来做这件事的。今天我就来跟你分享一下 Kafka 中压缩的那些事儿。

怎么压缩?

Kafka 是如何压缩消息的呢?要弄清楚这个问题,就要从 Kafka 的消息格式说起了。目前 Kafka 共有两大类消息格式,社区分别称之为 V1 版本和 V2 版本。V2 版本是 Kafka 0.11.0.0 中正式引入的。
不论是哪个版本,Kafka 的消息层次都分为两层:消息集合(message set)以及消息(message)。一个消息集合中包含若干条日志项(record item),而日志项才是真正封装消息的地方。Kafka 底层的消息日志由一系列消息集合日志项组成。Kafka 通常不会直接操作具体的一条条消息,它总是在消息集合这个层面上进行写入操作。
那么社区引入 V2 版本的目的是什么呢?V2 版本主要是针对 V1 版本的一些弊端做了修正,和我们今天讨论的主题相关的修正有哪些呢?先介绍一个,就是把消息的公共部分抽取出来放到外层消息集合里面,这样就不用每条消息都保存这些信息了。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

Kafka消息压缩是通过在生产者端和Broker端进行压缩和解压缩来实现的。V2版本相比V1版本在消息压缩方面有了一些改进,如将整个消息集合进行压缩,节省了磁盘空间。在生产者端,可以通过配置compression.type参数来启用指定类型的压缩算法,而在Broker端也可能进行重新压缩消息,例如在消息格式转换或使用不同压缩算法时。解压缩通常发生在消费者程序中,但在Broker端写入时也会进行解压缩操作以执行各种验证。文章强调了消息校验的重要性,尽管去掉解压缩可以降低Broker端的CPU使用率,但在做对的基础上考虑如何做好做快更为重要。Kafka的消息压缩机制涉及生产者端压缩、Broker端保持和消费者端解压缩,而不同压缩算法和消息格式转换可能会对压缩和解压缩过程产生影响。 Kafka支持多种压缩算法,包括GZIP、Snappy、LZ4和Zstandard(zstd)。这些算法在压缩比和吞吐量上各有优劣,因此在实际使用中需要根据实际情况选择合适的压缩算法。对于Kafka而言,在吞吐量方面,LZ4 > Snappy > zstd和GZIP;而在压缩比方面,zstd > LZ4 > GZIP > Snappy。根据环境的CPU和带宽资源情况,可以有针对性地选择合适的压缩算法,以实现最大的资源利用率。 最佳实践方面,建议在Producer端CPU资源充足且带宽资源有限时启用压缩,而在解压缩方面则需要规避意外情况,尽量避免消息格式转换。总的来说,文章分享了Kafka压缩的各个方面,包括压缩实现、压缩算法对比和最佳实践,旨在帮助读者根据实际情况选择合适的Kafka压缩算法,以实现最大的资源利用率。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《Kafka 核心技术与实战》
新⼈⾸单¥68
立即购买
登录 后留言

全部留言(97)

  • 最新
  • 精选
  • 胡夕
    置顶
    刚刚看到4天前京东提的那个jira已经修复了,看来规避了broker端为执行校验而做的解压缩操作,代码也merge进了2.4版本。有兴趣的同学可以看一下:https://issues.apache.org/jira/browse/KAFKA-8106
    2019-06-26
    5
    115
  • Geek_8441fd
    broker端校验可以分两步走。 第1步,message set 层面,增加一个 crc,这样可以不用解压缩,直接校验压缩后的数据。 如果校验不成功,说明message set 中有损坏的message; 这时,再做解压操作,挨个校验message,找出损坏的那一个。 这样的话,绝大部分情况下,是不用做解压操作的;只有在确实发生错误时,才需要解压。 请指正。

    作者回复: 嗯嗯,挺好的。我自己也学到了一些。另外校验不仅仅是CRC校验,还有消息级别的检查。

    2019-06-25
    6
    57
  • Li Shunduo
    假如一个消息集合里有10条消息,并且被压缩,但是消费端配置每次只poll 5条消息。这种情况下,消费端怎么解压缩?矛盾点是 如果只取5条消息,需要broker帮助解压缩;如果取整个消息集合10条消息,会有贷款等资源的浪费?

    作者回复: 目前java consumer的设计是一次取出一批,缓存在客户端内存中,然后再过滤出max.poll.records条消息返给你,也不算太浪费吧,毕竟下次可以直接从缓存中取,不用再发请求了。

    2019-06-25
    5
    27
  • 衣申人
    老师,我看源码,broker在接收producer消息并落盘这块貌似没有用零拷贝啊!只有传输给consumer时用了,求解答

    作者回复: 是的,就是你理解的那样。Kafka使用Zero Copy优化将页缓存中的数据直接传输到Socket——这的确是发生在broker到consumer的链路上。这种优化能成行的前提是consumer端能够识别磁盘上的消息格式。

    2019-12-11
    3
    24
  • 风中花
    胡老师您好! 我们已经学历10多节课了! 针对我们得留言和反馈,不知道您有没有给我们一些后续得课程得学习建议和方法?我目前得学习就是您告诉我们得,我必须学会记住。但是看同学们得评论和反馈,我觉得貌似还有很多很多知识啊且不知也不懂,故有此一问!希望老师能给与一点一点学习建议? 感谢老师

    作者回复: 个人觉得学一个东西最重要的还是要用,如果只是参加一些培训课程很难全面的理解。您这么多的留言我一直坚持回复。我也一直是这个观点:用起来,自然问题就来了。 我学机器学习的经历和您现在学Kafka很像。没有实际使用场景怎么学都觉得深入不了。 我给您的建议是:把Kafka官网通读几遍然后再实现一个实时日志收集系统(比如把服务器日志实时放入Kafka)。事实上,能把官网全面理解的话已经比很多Kafka使用者要强了。

    2019-06-26
    2
    21
  • 星期八
    老师那再问一下,如果多条消息组成消息集合发送,那是什么条件控制消息发送,如果是一条又是什么条件控制触发发送的呢

    作者回复: 主要是这两个参数:batch.size和linger.ms。如果是生产了一条消息且linger.ms=0,通常producer就会立即发送者一条消息了。

    2019-07-12
    2
    16
  • 南辕北辙
    老师有一点不是很明白,在正常情况下broker端会原样保存起来,但是为了检验需要解压缩。该怎么去理解这个过程呢,broker端解压缩以后还会压缩还原吗? 这个过程是在用户态执行的吗,总感觉怪怪的

    作者回复: 它只是解压缩读取而已,不会将解压缩之后的数据回写到磁盘。另外就像我置顶的留言那样,目前社区已经接纳了京东小伙伴的修改,貌似可以绕过这部分解压缩了,。

    2019-06-27
    3
    15
  • dream
    老师,我对消息层次、消息集合、消息、日志项这些概念与它们之间的关系感觉很懵, 消息层次都分消息集合以及消息,消息集合中包含日志项,日志项中封装消息, 那么日志项中封装的是producer发送的消息吗? 一个日志项中会包含多条消息吗? 消息集合中消息项封装的的消息与消息层次包含的消息有什么关系呢? 这两个消息与producer发送的消息有什么关系呢? 一个消息集合对应是producer发送的一条消息还是多条消息呢? 最后,老师能不能详细说一下CRC校验,谢谢!

    作者回复: 消息批次RecordBatch里面包含若干条消息(record)。 你可以认为消息批次和消息集合是等价的,消息和日志项是等价的。 这样消息层次有两层:外层是消息批次(或消息集合);里层是消息(或日志项)。 Producer以recordbatch为单位发送消息,对于V2版本一个batch中通常包含多条消息。 在V2版本中,在batch层面计算CRC值;在V1版本中,每条消息都要计算CRC值。

    2019-06-25
    6
    13
  • 曾轼麟
    不认同,因为网络传输也会造成丢失,但是我建议可以在消息里面使用一种消耗较小的签名方式sign,比如多使用位移等方式,broke端也这么操纵,如果签名不一致证明有数据丢失,同时签名的方式可以避免CPU大量消耗

    作者回复: 有一定道理。有机会我向社区反馈下:)

    2019-06-25
    4
    11
  • 南辕北辙
    老师有一点有点迷惑,broker为了多版本消息兼容,意思是一份消息有多个版本存在吗,是这个意思吗?

    作者回复: 同一台broker上可能存在多个版本的消息,但每条消息只会以1个版本的形式保存。

    2019-07-01
    3
    9
收起评论
显示
设置
留言
97
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部