消息

  • Kafka 逻辑上消息层次都分为两层:
    • 外层是消息批次 RecordBatch(或消息集合 message set);
    • 里层是消息 (Record)(或日志项 record item)。
    • 日志项才是真正封装消息的地方。
  • Kafka 底层的消息日志由一系列消息集合日志项组成。Kafka 通常不会直接操作具体的一条条消息,它总是在消息集合这个层面上进行写入操作(Producer以 recordbatch 为单位发送消息,对于V2版本一个batch中通常包含多条消息)
    • 和Log,Log Segments 有啥区别?


新老版本消息的区别

  1. 新版本改进将每个消息公共部分取出放在外层消息集合,例如消息的 CRC 值
  2. 新老版本的保存压缩消息的方法变化,新版本是对整个消息集合进行压缩

压缩

  • compression.type

    生产端压缩

    1. Properties props = new Properties();
    2. props.put("bootstrap.servers", "localhost:9092");
    3. props.put("acks", "all");
    4. props.put("key.serializer", "org.apache.kafka.common.serialization.StringSerializer");
    5. props.put("value.serializer", "org.apache.kafka.common.serialization.StringSerializer");
    6. // 开启 GZIP 压缩
    7. props.put("compression.type", "gzip");
    8. Producer<String, String> producer = new KafkaProducer<>(props);

Broker 端压缩

  1. Broker 端的compression.type 自行修改了值,那么会导致重新压缩
    1. 默认为 producer, 即使用和 producer 一样的压缩算法
  2. Broker 端的消息重新格式化
    1. 将新版本的消息格式转化为旧版本的消息格式,需要解压缩再重新压缩,丧失零拷贝的好处

解压缩

Comsumer 解压缩

  • 压缩算法信息会保存在消息集合中
  • 消费者消费到信息,自然会知道采用了哪种压缩算法

Broker 解压缩

  • 为了对压缩后的消息执行验证,broker 端肯定要进行解压缩

压缩算法

  • 在 Kafka 2.1.0 版本之前,Kafka 支持 3 种压缩算法:GZIP、Snappy 和 LZ4
  • 从 2.1.0 开始,Kafka 正式支持 Zstandard 算法(简写为 zstd)

效率

  • 吞吐量方面:LZ4 > Snappy > zstd 和 GZIP
  • 而在压缩比方面,zstd > LZ4 > GZIP > Snappy
  • 具体到物理资源
    • 带宽:
      • 使用 Snappy 算法占用最多
      • zstd 最少
    • 在 CPU 使用率
      • 各个算法表现得差不多
      • 只是在压缩时 Snappy 算法使用的较多一些
      • 而在解压缩时 GZIP 算法则可能使用更多