Kafka Snappy 压缩异常分析与解决方案

1. 问题描述

在使用 Kafka 进行消息发送时,遇到了以下异常:

Crystal 复制代码
org.apache.kafka.common.KafkaException: java.lang.UnsatisfiedLinkError: /tmp/snappy-1.1.7-ee0a2284-1d05-4116-9ddc-a0d5d4b3f8cd-libsnappyjava.so: Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /tmp/snappy-1.1.7-ee0a2284-1d05-4116-9ddc-a0d5d4b3f8cd-libsnappyjava.so)
	at org.apache.kafka.common.record.CompressionType$3.wrapForOutput(CompressionType.java:83)
	at org.apache.kafka.common.record.MemoryRecordsBuilder.<init>(MemoryRecordsBuilder.java:131)
	at org.apache.kafka.common.record.MemoryRecordsBuilder.<init>(MemoryRecordsBuilder.java:167)
	at org.apache.kafka.common.record.MemoryRecords.builder(MemoryRecords.java:507)
	at org.apache.kafka.common.record.MemoryRecords.builder(MemoryRecords.java:489)
	at org.apache.kafka.common.record.MemoryRecords.builder(MemoryRecords.java:437)
	at org.apache.kafka.clients.producer.internals.RecordAccumulator.recordsBuilder(RecordAccumulator.java:253)
	at org.apache.kafka.clients.producer.internals.RecordAccumulator.append(RecordAccumulator.java:229)
	at org.apache.kafka.clients.producer.KafkaProducer.doSend(KafkaProducer.java:949)
	at org.apache.kafka.clients.producer.KafkaProducer.send(KafkaProducer.java:870)
	at org.springframework.kafka.core.DefaultKafkaProducerFactory$CloseSafeProducer.send(DefaultKafkaProducerFactory.java:848)
	at org.springframework.kafka.core.KafkaTemplate.doSend(KafkaTemplate.java:563)
	at org.springframework.kafka.core.KafkaTemplate.send(KafkaTemplate.java:363)
	... (此处省略部分日志)
	at java.lang.Thread.run(Thread.java:748)
Caused by: java.lang.UnsatisfiedLinkError: /tmp/snappy-1.1.7-ee0a2284-1d05-4116-9ddc-a0d5d4b3f8cd-libsnappyjava.so: Error loading shared library ld-linux-x86-64.so.2: No such file or directory (needed by /tmp/snappy-1.1.7-ee0a2284-1d05-4116-9ddc-a0d5d4b3f8cd-libsnappyjava.so)
	at java.lang.ClassLoader$NativeLibrary.load(Native Method)
	at java.lang.ClassLoader.loadLibrary0(ClassLoader.java:1941)
	at java.lang.ClassLoader.loadLibrary(ClassLoader.java:1824)
	at java.lang.Runtime.load0(Runtime.java:809)
	at java.lang.System.load(System.java:1086)
	at org.xerial.snappy.SnappyLoader.loadNativeLibrary(SnappyLoader.java:179)
	at org.xerial.snappy.SnappyLoader.loadSnappyApi(SnappyLoader.java:154)
	at org.xerial.snappy.Snappy.<clinit>(Snappy.java:47)
	at org.xerial.snappy.SnappyOutputStream.<init>(SnappyOutputStream.java:99)
	at org.xerial.snappy.SnappyOutputStream.<init>(SnappyOutputStream.java:91)
	at org.xerial.snappy.SnappyOutputStream.<init>(SnappyOutputStream.java:81)
	at org.apache.kafka.common.record.CompressionType$3.wrapForOutput(CompressionType.java:81)
	... 128 more

该异常表明 Kafka 在尝试加载 libsnappyjava.so 共享库时失败,原因是缺少依赖的动态链接库 ld-linux-x86-64.so.2。

2. 异常原因分析

2.1. Snappy 压缩依赖

Kafka 默认支持多种压缩方式(如 gzip、snappy、lz4 等),其中 snappy 是一种高效的压缩算法。如果 Kafka 配置了 snappy 压缩,但运行环境中缺少 snappy 的本地库支持,就会抛出上述异常。

2.2. 动态链接库缺失

ld-linux-x86-64.so.2 是 Linux 系统中用于加载共享库的动态链接器。某些轻量级容器环境(如 Alpine Linux)可能未预装该文件,导致无法正确加载 snappy 的本地库。

2.3. 运行环境不匹配

如果 Kafka 客户端运行在非标准的 Linux 发行版上(如基于 musl 的 Alpine Linux),而 snappy 的本地库是针对 glibc 编译的,则可能会出现兼容性问题。

3. 解决方案

3.1. 方法一:禁用 Snappy 压缩

如果项目对压缩方式没有特殊要求,可以通过禁用 snappy 压缩来快速解决问题。

3.1.1. 配置步骤

1. 修改 Kafka 配置

在 Kafka Producer 或 Consumer 的配置中,将 compression.type 设置为其他值(如 gzip 或 none):

以SpringBoot 的 application.yaml 为例:

Crystal 复制代码
spring:
  kafka:
      producer:
        compression-type: none # 对发送的数据进行压缩 支持压缩类型:none、gzip、snappy、lz4 和 zstd。

3.1.2. 优点

  • 快速解决兼容性问题。
  • 不需要额外安装依赖

3.1.3. 缺点

  • 快速解决兼容性
  • 如果数据量较大,禁用压缩可能导致网络传输效率降低。

3.2. 方法二:安装 Snappy 依赖

如果必须使用 snappy 压缩,可以确保运行环境中安装了 snappy 的所有依赖。

3.2.1. 配置步骤

以 Linux 系统为例:

1. 安装包下载:

下载 G++ 和 Gcc 安装包:

GitCode - 全球开发者的开源社区,开源代码托管平台GitCode是面向全球开发者的开源社区,包括原创博客,开源代码托管,代码协作,项目管理等。与开发者社区互动,提升您的研发效率和质量。https://gitcode.com/open-source-toolkit/2b513

下载 snappy 安装包:

Index of /repo/pkgs/snappyhttps://src.fedoraproject.org/repo/pkgs/snappy/

2. 以 /export/server 目录为例,将下载的安装包解压并上传到 /export/server 目录。

3. 安装 G++ 和 Gcc (如果有该环境则跳过此步骤)

进入解压后的目录并安装:

bash 复制代码
cd /export/server/gcc
rpm -ivh *rpm --nodeps --force
cd /export/server/gcc-c++
rpm -ivh *rpm --nodeps --force

4. 安装 snappy

bash 复制代码
cd /server/export
tar -zxvf snappy-1.1.7.tar.gz
cd snappy-1.1.7
./configure --with-snappy=/server/export/snappy

3.2.2. 优点

  • 保留 snappy 压缩的优势。
  • 适合对性能要求较高的场景。

3.2.3. 缺点

  • 需要修改运行环境,可能增加维护成本。

3.3. 方法三:使用纯 Java 实现的 Snappy

为了避免本地库依赖问题,可以选择使用纯 Java 实现的 snappy 库。

3.3.1. 配置步骤

1. 添加 Maven 依赖 (以1.1.8.4 版本为例):

XML 复制代码
<dependency>
    <groupId>org.xerial.snappy</groupId>
    <artifactId>snappy-java</artifactId>
    <version>1.1.8.4</version>
</dependency>

2. 确保 Kafka 使用纯 Java 版本的 snappy:

Kafka 默认会优先加载本地库,但如果本地库加载失败,会自动回退到纯 Java 实现。

3.3.2. 优点

  • 无需修改运行环境。
  • 兼容性更强。

3.3.3. 缺点

  • 纯 Java 实现的性能略低于本地库。

4. 总结

|----------|----------------|----------|
| 方法 | 优点 | 缺点 |
| 禁用压缩 | 快速解决,无需额外依赖 | 可能影响传输效率 |
| 安装依赖 | 保留 snappy 压缩优势 | 需要修改运行环境 |
| 使用纯 Java | 兼容性强,无需修改运行环境 | 性能略低 |

根据实际需求选择合适的解决方案。如果项目对压缩性能要求不高,推荐直接禁用 snappy 压缩;如果需要高性能压缩,建议安装 snappy 依赖或使用纯 Java 实现。

5. 参考资料

  1. Apache Kafka
  2. https://github.com/xerial/snappy-java
相关推荐
头发还在的女程序员9 小时前
医院陪诊管理系统怎么选择?——2026 年选型避坑与架构参考
java·开发语言·陪诊系统·陪诊app·医院陪诊陪护
CodeStats10 小时前
【Spring事务】Spring事务注解 @Transactional 完整体系:从 MySQL 隔离级别到 MyBatis 原理详解
java·spring·mybatis·事务·transactional
我命由我1234510 小时前
Android 开发问题:为 PDFView 设置一个带有黑色边框的背景 drawable,但边框没有生效
android·java·java-ee·android studio·android jetpack·android-studio·android runtime
都叫我大帅哥12 小时前
从Python到Java:为什么企业级Agent最终会选择Java?
java·ai编程
wanderist.13 小时前
Lambda表达式在算法竞赛中的应用
java·开发语言·算法
腻害兔14 小时前
【若依项目-产品经理视角】RuoYi-Vue-Pro 源码拆解:IM 即时通讯模块,一个被低估的「全功能聊天系统」
java·前端·vue.js·产品经理·ai编程
心念枕惊14 小时前
.NET CORE 授权进阶-角色、策略与动态权限实现
java·前端·.netcore
韩楚风16 小时前
【参天引擎】一次宕机后的数据恢复,让我把 Cantian 持久化与恢复的六大机制全搞明白了
服务器·网络·数据库·分布式·mysql·架构·cantian
景同学16 小时前
把 AI 用到线上运维:可行、有效,前提是喂足信息——一次 Full GC 排障实录
java·人工智能·后端
C++、Java和Python的菜鸟16 小时前
第7章 后端Web实战(Tlias系统)
java