一、Kafka 版本演进

Kafka 目前总共演进了 7 个大版本,分别是 0.7、0.8、0.9、0.10、0.11、1.0 和 2.0,其中的小版本和 Patch 版本很多。

  • 0.7 版本,是最早开源时的版本,这个版本只提供了最基础的消息队列功能,连副本机制都没有。
  • 0.8 版本正式引入了副本机制,至此 Kafka 成为了一个真正意义上完备的分布式高可靠消息队列解决方案。
  • 0.9 版本增加了基础的安全认证 / 权限功能,同时使用 Java 重写了新版本消费者 API,另外还引入了 Kafka Connect 组件用于实现高性能的数据抽取。
  • 0.10 是里程碑式的大版本,该版本引入了 Kafka Streams。从这个版本起,Kafka 正式升级成分布式流处理平台。
  • 0.11 版本,引入了两个重量级的功能变更:一个是提供幂等性 Producer API 以及事务(Transaction) API;另一个是对 Kafka 消息格式做了重构。
  • 1.0 和 2.0 版本,主要还是 Kafka Streams 的各种改进,在消息引擎方面并未引入太多的重大功能特性。

二、生产者消息分区机制原理

Kafka 的消息组织方式实际上是三级结构:主题 – 分区 – 消息。主题下的每条消息只会保存在某一个分区中,而不会在多个分区中被保存多份。

其实分区的作用就是提供负载均衡的能力,或者说对数据进行分区的主要原因,就是为了实现系统的高伸缩性(Scalability)。

值得注意的是,不同的分布式系统对分区的叫法也不尽相同。比如在 Kafka 中叫分区,在 MongoDB 和 Elasticsearch 中就叫分片 Shard,而在 HBase 中则叫 Region,在 Cassandra 中又被称作 vnode。从表面看起来它们实现原理可能不尽相同,但对底层分区(Partitioning)的整体思想却从未改变。

三、生产者压缩算法

1,怎么压缩

目前 Kafka 共有两大类消息格式,社区分别称之为 V1 版本和 V2 版本。V2 版本是 Kafka 0.11.0.0 中正式引入的。

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

2,何时压缩

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

有两种例外情况就可能让 Broker 重新压缩消息。

  • 情况一:Broker 端指定了和 Producer 端不同的压缩算法。
  • 情况二:Broker 端发生了消息格式转换。

所谓的消息格式转换主要是为了兼容老版本的消费者程序。

一般情况下这种消息格式转换对性能是有很大影响的,除了这里的压缩之外,它还让 Kafka 丧失了引以为豪的 Zero Copy 特性。

3,何时解压缩

每个压缩过的消息集合在 Broker 端写入时都要发生解压缩操作,目的就是为了对消息执行各种验证。我们必须承认这种解压缩对 Broker 端性能是有一定影响的,特别是对 CPU 的使用率而言。

4,各种压缩算法对比

在 Kafka 2.1.0 版本之前,Kafka 支持 3 种压缩算法:GZIP、Snappy 和 LZ4。从 2.1.0 开始,Kafka 正式支持 Zstandard 算法(简写为 zstd)。它是 Facebook 开源的一个压缩算法,能够提供超高的压缩比(compression ratio)。

看一个压缩算法的优劣,有两个重要的指标:一个指标是压缩比;另一个指标就是压缩 / 解压缩吞吐量。

在吞吐量方面:LZ4 > Snappy > zstd 和 GZIP;而在压缩比方面,zstd > LZ4 > GZIP > Snappy。

5,最佳实践

如果 Producer 运行机器本身 CPU 已经消耗殆尽了,那么启用消息压缩无疑是雪上加霜,只会适得其反。