You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Databricks 10.4 LTS+Spark3读取Snappy压缩PB文件遇UnsatisfiedLinkError

问题:Databricks 10.4 LTS读取Snappy压缩Protocol Buffer文件报UnsatisfiedLinkError

环境与代码

运行环境:Databricks 10.4 LTS(Spark 3)
读取并解析文件的Scala代码:

sc.sequenceFile[NullWritable, BytesWritable](concatUris)
        .map(b => {
          val msg: Array[Byte] = b._2.copyBytes()
          val feed: a_feed = a_feed.parseFrom(msg)
          val properties = feed.toPMessage.value
            .map { case (key, value) =>
              key.name -> (value match {
                case i: PInt        => i.value
                case l: PLong       => l.value
                case s: PString     => s.value
                case d: PDouble     => d.value
                case f: PFloat      => f.value
                case b: PByteString => b.value
                case c: PBoolean    => c.value
                case e: PEnum       => e.value.name
                case other          => other.toString()
              })
            }

          (uid, properties + ("user_id" -> uid))
        })

错误堆栈

Caused by: UnsatisfiedLinkError: org.apache.hadoop.shaded.org.xerial.snappy.SnappyNative.rawUncompress(Ljava/nio/ByteBuffer;IILjava/nio/ByteBuffer;I)I
    at org.apache.hadoop.shaded.org.xerial.snappy.SnappyNative.rawUncompress(Native Method)
    at org.apache.hadoop.shaded.org.xerial.snappy.Snappy.uncompress(Snappy.java:551)
    at org.apache.hadoop.io.compress.snappy.SnappyDecompressor.decompressDirectBuf(SnappyDecompressor.java:267)
    at org.apache.hadoop.io.compress.snappy.SnappyDecompressor.decompress(SnappyDecompressor.java:217)
    at org.apache.hadoop.io.compress.BlockDecompressorStream.decompress(BlockDecompressorStream.java:88)
    at org.apache.hadoop.io.compress.DecompressorStream.read(DecompressorStream.java:105)
    at org.apache.hadoop.io.compress.DecompressorStream.read(DecompressorStream.java:92)

已尝试操作

  • 安装不同版本的org.xerial.snappy:snappy-java:<version>:jar库
  • 通过Databricks的Compute>Libraries标签上传安装库,但不确定是否部署到Driver和Executor所有节点

解决方案

1. 移除手动引入的snappy-java库

Databricks Runtime已内置适配Hadoop的Snappy库,手动引入外部snappy-java会与Hadoop shaded版本冲突,导致Native方法找不到。直接删除集群中手动添加的snappy-java库。

2. 确保集群库部署范围正确

通过Compute>Libraries添加的库默认会部署到Driver和Executor节点,但如果是Notebook级别临时安装(如%scala libraryDependencies += ...),仅Driver生效。需在集群级别添加依赖。

3. 配置Hadoop Snappy参数(可选)

读取文件前设置Hadoop配置,确保使用正确的解压器:

sc.hadoopConfiguration.set("io.compression.codecs", "org.apache.hadoop.io.compress.SnappyCodec")
sc.hadoopConfiguration.set("io.compression.codec.snappy.native", "true")

4. 区分Hadoop Snappy与标准Snappy格式

如果文件是标准Snappy而非Hadoop Snappy压缩,需手动读取二进制文件后解压缩:

import org.xerial.snappy.Snappy
sc.binaryFiles(concatUris)
  .map{ case (path, bytes) => Snappy.uncompress(bytes.toArray) }
  .map(msg => a_feed.parseFrom(msg))
  // 后续处理逻辑...

此时需使用与Databricks 10.4 LTS兼容的snappy-java版本(推荐1.1.8.4),并确保库部署到所有节点。

内容的提问来源于stack exchange,提问作者Niko

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.18 02:10:39