10 | 生产者压缩算法面面观
10 | 生产者压缩算法面面观
讲述:胡夕
时长12:17大小9.85M
怎么压缩?
何时压缩?
何时解压缩?
各种压缩算法对比
最佳实践
小结
开放讨论
赞 35
提建议
精选留言(93)
- 胡夕置顶2019-06-26刚刚看到4天前京东提的那个jira已经修复了,看来规避了broker端为执行校验而做的解压缩操作,代码也merge进了2.4版本。有兴趣的同学可以看一下:https://issues.apache.org/jira/browse/KAFKA-8106共 5 条评论108
- 常超2019-06-28文中对于消息结构的描述,确实引起了一些混乱,下面试图整理一下,希望对大家有帮助。 消息(v1叫message,v2叫record)是分批次(batch)读写的,batch是kafka读写(网络传输和文件读写)的基本单位,不同版本,对相同(或者叫相似)的概念,叫法不一样。 v1(kafka 0.11.0之前):message set, message v2(kafka 0.11.0以后):record batch,record 其中record batch对英语message set,record对应于message。 一个record batch(message set)可以包含多个record(message)。 对于每个版本的消息结构的细节,可以参考kafka官方文档的5.3 Message Format 章,里面对消息结构列得非常清楚。展开共 6 条评论113
- Geek_8441fd2019-06-25broker端校验可以分两步走。 第1步,message set 层面,增加一个 crc,这样可以不用解压缩,直接校验压缩后的数据。 如果校验不成功,说明message set 中有损坏的message; 这时,再做解压操作,挨个校验message,找出损坏的那一个。 这样的话,绝大部分情况下,是不用做解压操作的;只有在确实发生错误时,才需要解压。 请指正。展开
作者回复: 嗯嗯,挺好的。我自己也学到了一些。另外校验不仅仅是CRC校验,还有消息级别的检查。
共 5 条评论54 - 你好旅行者2019-06-25不行吧,校验操作应该也是为了防止在网络传输的过程中出现数据丢失的情况,在Producer端做完校验之后如果在传输的时候出现了错误,那这个校验就没有意义了。 我有一个问题想请教老师,如果每次传到Broker的消息都要做一次校验,那是不是都要把消息从内核态拷贝到用户态做校验?如果是这样的话那零拷贝机制不是就没有用武之地了?共 12 条评论46
- Li Shunduo2019-06-25假如一个消息集合里有10条消息,并且被压缩,但是消费端配置每次只poll 5条消息。这种情况下,消费端怎么解压缩?矛盾点是 如果只取5条消息,需要broker帮助解压缩;如果取整个消息集合10条消息,会有贷款等资源的浪费?
作者回复: 目前java consumer的设计是一次取出一批,缓存在客户端内存中,然后再过滤出max.poll.records条消息返给你,也不算太浪费吧,毕竟下次可以直接从缓存中取,不用再发请求了。
共 5 条评论26 - 风中花2019-06-26胡老师您好! 我们已经学历10多节课了! 针对我们得留言和反馈,不知道您有没有给我们一些后续得课程得学习建议和方法?我目前得学习就是您告诉我们得,我必须学会记住。但是看同学们得评论和反馈,我觉得貌似还有很多很多知识啊且不知也不懂,故有此一问!希望老师能给与一点一点学习建议? 感谢老师
作者回复: 个人觉得学一个东西最重要的还是要用,如果只是参加一些培训课程很难全面的理解。您这么多的留言我一直坚持回复。我也一直是这个观点:用起来,自然问题就来了。 我学机器学习的经历和您现在学Kafka很像。没有实际使用场景怎么学都觉得深入不了。 我给您的建议是:把Kafka官网通读几遍然后再实现一个实时日志收集系统(比如把服务器日志实时放入Kafka)。事实上,能把官网全面理解的话已经比很多Kafka使用者要强了。
共 2 条评论20 - Hello world2019-06-25做一个笔记 怎么压缩: 1、新版本改进将每个消息公共部分取出放在外层消息集合,例如消息的 CRC 值 2、新老版本的保存压缩消息的方法变化,新版本是对整个消息集合进行压缩 何时压缩: 1、正常情况下都是producer压缩,节省带宽,磁盘存储 2、例外情况 a、broker端和producer端使用的压缩方法不同 b、broker与client交互,消息版本不同 何时解压缩: 1、consumer端解压缩 2、broker端解压缩,用来对消息执行验证 优化:选择适合自己的压缩算法,是更看重吞吐量还是压缩率。其次尽量server和client保持一致,这样不会损失kafka的zero copy优势展开共 1 条评论20
- 衣申人2019-12-11老师,我看源码,broker在接收producer消息并落盘这块貌似没有用零拷贝啊!只有传输给consumer时用了,求解答
作者回复: 是的,就是你理解的那样。Kafka使用Zero Copy优化将页缓存中的数据直接传输到Socket——这的确是发生在broker到consumer的链路上。这种优化能成行的前提是consumer端能够识别磁盘上的消息格式。
共 3 条评论19 - 星期八2019-07-12老师那再问一下,如果多条消息组成消息集合发送,那是什么条件控制消息发送,如果是一条又是什么条件控制触发发送的呢
作者回复: 主要是这两个参数:batch.size和linger.ms。如果是生产了一条消息且linger.ms=0,通常producer就会立即发送者一条消息了。
共 2 条评论15 - cricket19812019-06-25校验的目的是防止因为网络传输出现问题导致broker端接收了受损的消息,所以应该放在作为serverr broker端进行,而不是在作为client端的producer。改进的方案可以是针对一次传输的整个message set进行CRC检验,而不是针对一条条消息,这能够大大提高校验效率,因为避免了解压缩。15
- 南辕北辙2019-06-27老师有一点不是很明白,在正常情况下broker端会原样保存起来,但是为了检验需要解压缩。该怎么去理解这个过程呢,broker端解压缩以后还会压缩还原吗? 这个过程是在用户态执行的吗,总感觉怪怪的
作者回复: 它只是解压缩读取而已,不会将解压缩之后的数据回写到磁盘。另外就像我置顶的留言那样,目前社区已经接纳了京东小伙伴的修改,貌似可以绕过这部分解压缩了,。
共 3 条评论12 - dream2019-06-25老师,我对消息层次、消息集合、消息、日志项这些概念与它们之间的关系感觉很懵, 消息层次都分消息集合以及消息,消息集合中包含日志项,日志项中封装消息, 那么日志项中封装的是producer发送的消息吗? 一个日志项中会包含多条消息吗? 消息集合中消息项封装的的消息与消息层次包含的消息有什么关系呢? 这两个消息与producer发送的消息有什么关系呢? 一个消息集合对应是producer发送的一条消息还是多条消息呢? 最后,老师能不能详细说一下CRC校验,谢谢!展开
作者回复: 消息批次RecordBatch里面包含若干条消息(record)。 你可以认为消息批次和消息集合是等价的,消息和日志项是等价的。 这样消息层次有两层:外层是消息批次(或消息集合);里层是消息(或日志项)。 Producer以recordbatch为单位发送消息,对于V2版本一个batch中通常包含多条消息。 在V2版本中,在batch层面计算CRC值;在V1版本中,每条消息都要计算CRC值。
共 6 条评论12 - dream2019-06-25老师,对于消息层次、消息集合、消息这三者的概念与关系我有点懵,能不能详细说一下?谢谢!共 2 条评论11
- 曾轼麟2019-06-25不认同,因为网络传输也会造成丢失,但是我建议可以在消息里面使用一种消耗较小的签名方式sign,比如多使用位移等方式,broke端也这么操纵,如果签名不一致证明有数据丢失,同时签名的方式可以避免CPU大量消耗
作者回复: 有一定道理。有机会我向社区反馈下:)
共 3 条评论10 - 南辕北辙2019-07-01老师有一点有点迷惑,broker为了多版本消息兼容,意思是一份消息有多个版本存在吗,是这个意思吗?
作者回复: 同一台broker上可能存在多个版本的消息,但每条消息只会以1个版本的形式保存。
共 3 条评论8 - 秋2019-06-25我看了三遍老师的课,得到了我要的答案: 1.如果生产者使用了压缩,broker为了crc校验,会启动解压,这个解压过程不可避免; 2.v2的broker为了低版本的消费者,会把消息再次解压并进行协议转换。 所以消费者的兼容成本较大,需要避免这个情况。共 2 条评论8
- 代码小生2019-09-18原来在 V1 版本中,每条消息都需要执行 CRC 校验,但是CRC在某些情况下会变化,所以crc拿到消息集和中更好,这个逻辑我没有明白呢,既然CRC会变,为了消息的正确性不更应该每条消息都校验吗?为什么说拿到消息集和中一次校验更好呢?
作者回复: V2依然是做CRC校验的,只不过是在record batch这个层级上做,而不是一条一条消息地做了。如果CRC校验失败,重传batch。也就是说不会以消息作为传输单位进行校验,这样效率太低
7 - What for2019-08-08老师您好,您的课程很棒,又很实用又有原理性的分析! 我想问一个问题,Producer 发送数据时以批次为单位,那么 batch 与 broker 端的消息集合又是怎么样的对应关系呢?每个消息集合的 record 数量是否固定呢? 就是说在 Producer 端即使消息并没有达到 batch.size 的数量,linger.ms 也可以让它发送一批数据,那 broker 在低峰期的时候收到一批数据之后是会写入缓存等凑够一定数量组成一个消息集合还是说会立即(或设置超时时间)组成一个消息集合写入磁盘? 谢谢!展开
作者回复: 不是固定数量。 “在 Producer 端即使消息并没有达到 batch.size 的数量,linger.ms 也可以让它发送一批数据” --- 是的 取决于linger.ms的值
共 4 条评论6 - juan2019-07-09如果在配置中不指定压缩算法,kafka有默认的压缩算法吗?
作者回复: 没有
共 2 条评论5 - 莫问流年2019-06-25我觉得消息检验放在producer端是不合理的。首先,检验应该是消息接收方broker的责任,每个发送方不应该承担这种公共的检验工作,也不利于扩展。其次,发送方producer检验影响了producer的性能,而且并不能保证消息到达broker后依然正确。 另外,想请教下老师,broker对消息进行的检验一般有哪些?
作者回复: 比如compact类型的topic要检查key是否存在等。有个好消息是我看最新的2.4已经接收了京东同学提的bug而且也修正了。尚不知道京东方面是怎么解决的,有兴趣的话可以看一下:https://issues.apache.org/jira/browse/KAFKA-8106
5