Java读取Snappy压缩Parquet文件本地正常Docker运行报错求助
问题根因定位
你遇到的报错核心是Alpine基础镜像与Snappy压缩原生库不兼容导致的解压失败:
- 你用的
openjdk:8-jdk-alpine镜像基于musl libc实现,而parquet依赖的org.xerial.snappy原生库默认是针对glibc编译的,无法在musl libc环境下正常运行,调用解压方法时就会抛出Buffer参数非法的异常。 - 本地IDE/运行环境用的是Windows/macOS/标准Linux发行版,默认都是glibc环境,所以运行正常。
解决方案(按优先级排序)
方案1:更换glibc系基础镜像(最简便,改一行即可)
将Dockerfile的基础镜像替换为基于Debian的openjdk slim镜像,完全兼容原生Snappy库:
# 替换原来的openjdk:8-jdk-alpine FROM openjdk:8-jdk-slim RUN mkdir /app RUN mkdir /app/files/ COPY testDir /app/files/ COPY normal /app/files/ WORKDIR /app COPY target/appname-0.0.1-SNAPSHOT.jar /app/app.jar ENTRYPOINT ["java","-jar","app.jar"]
改完重新构建镜像即可解决问题。
方案2:Alpine镜像安装glibc兼容层(必须保留Alpine时使用)
如果一定要用Alpine镜像缩小体积,可在Dockerfile中添加glibc安装步骤:
FROM openjdk:8-jdk-alpine # 安装glibc兼容层 RUN apk add --no-cache wget ca-certificates && \ wget -q -O /etc/apk/keys/sgerrand.rsa.pub https://alpine-pkgs.sgerrand.com/sgerrand.rsa.pub && \ wget -q https://github.com/sgerrand/alpine-pkg-glibc/releases/download/2.35-r0/glibc-2.35-r0.apk && \ apk add glibc-2.35-r0.apk && \ rm glibc-2.35-r0.apk /etc/apk/keys/sgerrand.rsa.pub && \ apk del wget ca-certificates RUN mkdir /app RUN mkdir /app/files/ COPY testDir /app/files/ COPY normal /app/files/ WORKDIR /app COPY target/appname-0.0.1-SNAPSHOT.jar /app/app.jar ENTRYPOINT ["java","-jar","app.jar"]
方案3:强制使用纯Java实现的Snappy解压(无需改镜像)
在初始化Hadoop Configuration对象时,添加配置强制关闭原生Snappy库,使用纯Java实现解压:
// 在你的readTest方法初始化conf的位置添加以下配置 conf.set("io.compression.codec.snappy.native", "false"); // 也可以额外添加配置指定SnappyCodec实现 conf.set("io.compression.codec.snappy", "org.apache.hadoop.io.compress.SnappyCodec");
该方案不需要修改Docker镜像,调整代码配置即可生效。
内容的提问来源于stack exchange,提问作者Sugyan sahu
相关产品推荐
相关产品推荐

