压缩具体来说就是用 CPU 时间去换磁盘空间或网络 I/O 传输量,希望以较多的 CPU 开销带来更少的磁盘占用或更少的网络 I/O 传输。在 Kafka 中,压缩也是用来做这件事的。

怎么压缩?

说起压缩消息,就要从 Kafka 的消息格式说起了。目前 Kafka 目前共有三大类消息格式v0、v1、v2,详细内容请参考文章:https://blog.csdn.net/yangyijun1990/article/details/109189470

不论是哪个版本,Kafka 的消息层次都分为两层:消息集合(message set)以及消息(message)。一个消息集合中包含若干条日志项(record item),而日志项才是真正封装消息的地方。Kafka 底层的消息日志由一系列消息集合日志项组成。Kafka 通常不会直接操作具体的一条条消息,它总是在消息集合这个层面上进行写入操作。

那么社区引入 V2 版本的目的是什么呢?V2 版本主要是针对 V1 版本的一些弊端做了修正,和我们今天讨论的主题相关的修正有哪些呢?先介绍一个,就是把消息的公共部分抽取出来放到外层消息集合里面,这样就不用每条消息都保存这些信息了。

我来举个例子。原来在 V1 版本中,每条消息都需要执行 CRC 校验,但有些情况下消息的 CRC 值是会发生变化的。比如在 Broker 端可能会对消息时间戳字段进行更新,那么重新计算之后的 CRC 值也会相应更新;再比如 Broker 端在执行消息格式转换时(主要是为了兼容老版本客户端程序),也会带来 CRC 值的变化。鉴于这些情况,再对每条消息都执行 CRC 校验就有点没必要了,不仅浪费空间还耽误 CPU 时间,因此在 V2 版本中,消息的 CRC 校验工作就被移到了消息集合这一层。

V2 版本还有一个和压缩息息相关的改进,就是保存压缩消息的方法发生了变化。之前 V1 版本中保存压缩消息的方法是把多条消息进行压缩然后保存到外层消息的消息体字段中;而 V2 版本的做法是对整个消息集合进行压缩。显然后者应该比前者有更好的压缩效果。

我对两个版本分别做了一个简单的测试,结果显示,在相同条件下,不论是否启用压缩,V2 版本都比 V1 版本节省磁盘空间。当启用压缩时,这种节省空间的效果更加明显。

何时压缩?

在 Kafka 中,压缩可能发生在两个地方:生产者端和 Broker 端

生产者程序中配置 compression.type 参数即表示启用指定类型的压缩算法。比如下面这段程序代码展示了如何构建一个开启 lz4 的 Producer 对象:

Properties props = new Properties();props.put("bootstrap.servers", "localhost:9092");props.put("acks", "all");props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");// 开启 lz4 压缩props.put("compression.type", "lz4");Producer<String, String> producer = new KafkaProducer<>(props);

这里比较关键的代码行是 props.put(“compression.type”, “lz4”),它表明该 Producer 的压缩算法使用的是 lz4。这样 Producer 启动后生产的每个消息集合都是经 lz4 压缩过的,故而能很好地节省网络传输带宽以及 Kafka Broker 端的磁盘占用。

在生产者端启用压缩是很自然的想法,那为什么我说在 Broker 端也可能进行压缩呢?其实大部分情况下 Broker 从 Producer 端接收到消息后仅仅是原封不动地保存而不会对其进行任何修改,但这里的“大部分情况”也是要满足一定条件的。有两种例外情况就可能让 Broker 重新压缩消息。

- Broker 端指定了和 Producer 端不同的压缩算法,比如producer端指定了Snappy,而broker端指定的是lz4;
你看,这种情况下 Broker 接收到 Snappy 压缩消息后,只能解压缩然后使用 lz4 重新压缩一遍。如果你翻开 Kafka 官网,你会发现 Broker 端也有一个参数叫 compression.type,和上面那个例子中的同名。但是这个参数的默认值是 producer,这表示 Broker 端会“尊重”Producer 端使用的压缩算法。可一旦你在 Broker 端设置了不同的 compression.type 值,就一定要小心了,因为可能会发生预料之外的压缩 / 解压缩操作,通常表现为 Broker 端 CPU 使用率飙升。

- Broker 端发生了消息格式转换。
所谓的消息格式转换主要是为了兼容老版本的消费者程序。还记得之前说过的 V1、V2 版本吧?在一个生产环境中,Kafka 集群中同时保存多种版本的消息格式非常常见。为了兼容老版本的格式,Broker 端会对新版本消息执行向老版本格式的转换。这个过程中会涉及消息的解压缩和重新压缩。一般情况下这种消息格式转换对性能是有很大影响的,除了这里的压缩之外,它还让 Kafka 丧失了引以为豪的 Zero Copy 特性。

有压缩必有解压缩!通常来说解压缩发生在消费者程序中,也就是说 Producer 发送压缩消息到 Broker 后,Broker 照单全收并原样保存起来。当 Consumer 程序请求这部分消息时,Broker 依然原样发送出去,当消息到达 Consumer 端后,由 Consumer 自行解压缩还原成之前的消息。

那么现在问题来了,Consumer 怎么知道这些消息是用何种压缩算法压缩的呢?其实答案就在消息中。Kafka 会将启用了哪种压缩算法封装进消息集合中,这样当 Consumer 读取到消息集合时,它自然就知道了这些消息使用的是哪种压缩算法。

Kafka消息压缩与解压相关推荐

  1. 【kafka】Kafka消息压缩与解压与相关实验

    本文为博主九师兄(QQ:541711153 欢迎来探讨技术)原创文章,未经允许博主不允许转载. 文章目录 1.概述 2.Kafka消息压缩与解压 2.1 怎么压缩? 2.2 何时压缩? 3.案例 3. ...

  2. Kafka 3.x的解压安装 - Linux

    写在前面:博主是一只经过实战开发历练后投身培训事业的"小山猪",昵称取自动画片<狮子王>中的"彭彭",总是以乐观.积极的心态对待周边的事物.本人的技 ...

  3. 浅谈Kafka消息压缩

    概述 Kafka目前支持GZIP.Snappy.LZ4.zstd.不压缩这几种压缩算法.在开启压缩时,Kafka会选择一个batch的消息一起压缩,这样的一批消息就是一个压缩分段,我们也可以通过参数来 ...

  4. kafka实战教程(python操作kafka),kafka配置文件详解

    全栈工程师开发手册 (作者:栾鹏) 架构系列文章 应用往Kafka写数据的原因有很多:用户行为分析.日志存储.异步通信等.多样化的使用场景带来了多样化的需求:消息是否能丢失?是否容忍重复?消息的吞吐量 ...

  5. java zip 字符串_java字符串的压缩解压

    packagecom.example.base.other;importjava.io.ByteArrayOutputStream;importjava.io.IOException;importja ...

  6. android架构师解压密码,咕泡Java架构师第三期完整版

    课程目录:咕泡三Java架构师VIP培训班 2019年3月开班 [138.G] ┣━━第1部分:架构师内功心法 [16.9G] ┃ ┣━━01-为什么要从设计模式开始及工厂模式详解 [561.2M] ...

  7. Kafka 安装详解

    注意:确保有JDK1.8版本及以上 官方文档:https://kafka.apache.org/quickstart 清华镜像下载:https://mirrors.tuna.tsinghua.edu. ...

  8. zip压缩多个文件,解压时不包含目录层级

    假设我们有个目录叫 dev,dev中有很多文件,我们想要将dev中的文件打包,名字可能叫dev.zip,但当我们解压的时候,不想要解压生成一个dev目录,想要直接解压在当前目录,这样如何压缩呢? # ...

  9. MySQL解压版安装

    MySQL解压版安装 1.下载对应版本的MySQL压缩包. 2.把压缩包解压在指定的位置. 3.在安装目录里面建一个文件,文件名字是指定的 my.ini 文件 4.在配置文件中写入如下的配置代码: [ ...

最新文章

  1. github一些常见命令
  2. vue插槽样式_Vue为什么要有插槽
  3. 2020下半年新机最新消息_2020年下半年即将发布的手机,你们期待吗
  4. 【django】创建django项目工程
  5. 【GVA】gorm多对多many2many删除数据的同时级联删除关联中间表中的关联数据
  6. Tomcat和IntelliJ –在webapps文件夹之外部署war文件
  7. 自己写的android apk反编译,获取Android自己写好了的apk以及反编译
  8. 《活法》中一个故事--令托尔斯泰也折服的人性寓言
  9. fastdfs java token_fastdfs 开启 token 防盗链
  10. 【BZOJ1196】公路修建问题,二分+最小生成树
  11. Codeigniter夸应用调用model
  12. 第四期coding_group笔记_用CRF实现分词-词性标注
  13. logo语言是计算机语言吗,LOGO语言的编程
  14. 不吹不黑,这5款浏览器安全无广告无弹窗,亲测好用
  15. 双目测量空间中两点距离
  16. Ubuntu安装cuda
  17. 软件测试方法_边界值分析法
  18. grafana 画拓扑图 能不能_画网络拓扑图的软件除了visio外还有什么软件啊?
  19. (银行案例)智能营销赋能大零售转型
  20. 怎么判断自己是否适合转行软件测试

热门文章

  1. 【面试题22】栈的压入、弹出序列
  2. JavaScript 电话手机号码正则表达式
  3. 提高 Google 搜索效率的基本语法
  4. matlab练习程序(TV模型图像修复)
  5. C++ 使用VS2010创建MFC ActiveX工程项目
  6. idea怎么导入jxl.jar库
  7. concat mysql sql注入_Mysql中用concat函数执行SQL注入查询的方法
  8. C语言-数据结构-可变长顺序表的查找操作
  9. 辗转相除法(欧几里得算法)求解最大公约数、最小公倍数
  10. 东华理工大学arm试卷_ARM东华理工大学2015-2016试卷A