M1芯片MacBook Pro解決snappy-java的FAILED_TO_LOAD_NATIVE_LIBRARY問題


太長不看版

直接找到引入該依賴的xml文件(本人是spark-core的xml文件),將其中的snappy-java的version改為1.1.8.4。重新加載即可。

    <dependency>
      <groupId>org.xerial.snappy</groupId>
      <artifactId>snappy-java</artifactId>
      <version>1.1.8.4</version>
      <scope>compile</scope>
    </dependency>

詳細探索過程

日前新M1 pro芯片的MacBook Pro到手了,迫不及待的試了試。因為該芯片使用的ARM指令集,之前Intel芯片的電腦使用的是X86指令集,故此難免會有一些問題。不過經過一年的適配基本上沒有什么大問題了,所以在經過幾天的嘗試后,果斷將該機器用於工作生產中。

本人是大數據開發工程師,必然要安裝Java,剛開始使用的是傳統的Intel版本jdk(因為主要使用的是jdk1.8,而Oracle只對jdk17做了arm版的適配),開發中感覺會有一些程序執行的沒有那么速度(和18款MacBook Pro執行速度差不多),因為畢竟要經過Rosetta2轉譯。故此在使用幾天后,將Intel版本的jdk替換為ARM版本的jdk。詳情可以參考該文檔https://www.winsonlo.com/it/howto/zulu-jdk8-on-m1/。但是文檔中有一個坑,文檔中給的直接下載鏈接,並不是arm版的,我在安裝后發現執行的時候一直使用的是intel版java,后來才發現是下載鏈接錯誤,需要自己到官網手動下載真正的arm版jdk(該網址打開速度比較慢,如果不能自己下載的話,可以給我私信)。

安裝好arm版jdk后,編譯速度果然有很大提升,但是在本地執行spark程序時,遇到了這樣一個問題,詳細日志如下:

Caused by: org.xerial.snappy.SnappyError: [FAILED_TO_LOAD_NATIVE_LIBRARY] no native library is found for os.name=Mac and os.arch=aarch64
	at org.xerial.snappy.SnappyLoader.findNativeLibrary(SnappyLoader.java:331)
	at org.xerial.snappy.SnappyLoader.loadNativeLibrary(SnappyLoader.java:171)
	at org.xerial.snappy.SnappyLoader.load(SnappyLoader.java:152)
	at org.xerial.snappy.Snappy.<clinit>(Snappy.java:47)
	at org.apache.parquet.hadoop.codec.SnappyDecompressor.decompress(SnappyDecompressor.java:62)
	at org.apache.parquet.hadoop.codec.NonBlockedDecompressorStream.read(NonBlockedDecompressorStream.java:51)
	at java.io.DataInputStream.readFully(DataInputStream.java:195)
	at java.io.DataInputStream.readFully(DataInputStream.java:169)
	at org.apache.parquet.bytes.BytesInput$StreamBytesInput.toByteArray(BytesInput.java:205)
	at org.apache.parquet.column.values.dictionary.PlainValuesDictionary$PlainBinaryDictionary.<init>(PlainValuesDictionary.java:89)
	at org.apache.parquet.column.values.dictionary.PlainValuesDictionary$PlainBinaryDictionary.<init>(PlainValuesDictionary.java:72)
	at org.apache.parquet.column.Encoding$1.initDictionary(Encoding.java:90)
	at org.apache.parquet.column.Encoding$4.initDictionary(Encoding.java:149)
	at org.apache.spark.sql.execution.datasources.parquet.VectorizedColumnReader.<init>(VectorizedColumnReader.java:103)
	at org.apache.spark.sql.execution.datasources.parquet.VectorizedParquetRecordReader.checkEndOfRowGroup(VectorizedParquetRecordReader.java:280)
	at org.apache.spark.sql.execution.datasources.parquet.VectorizedParquetRecordReader.nextBatch(VectorizedParquetRecordReader.java:225)
	at org.apache.spark.sql.execution.datasources.parquet.VectorizedParquetRecordReader.nextKeyValue(VectorizedParquetRecordReader.java:137)
	at org.apache.spark.sql.execution.datasources.RecordReaderIterator.hasNext(RecordReaderIterator.scala:39)
	at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon$1.hasNext(FileScanRDD.scala:105)
	at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon$1.nextIterator(FileScanRDD.scala:177)
	at org.apache.spark.sql.execution.datasources.FileScanRDD$$anon$1.hasNext(FileScanRDD.scala:105)
	at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIterator.scan_nextBatch$(Unknown Source)
	at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIterator.processNext(Unknown Source)
	at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
	at org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8$$anon$1.hasNext(WholeStageCodegenExec.scala:395)
	at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIterator.agg_doAggregateWithKeys$(Unknown Source)
	at org.apache.spark.sql.catalyst.expressions.GeneratedClass$GeneratedIterator.processNext(Unknown Source)
	at org.apache.spark.sql.execution.BufferedRowIterator.hasNext(BufferedRowIterator.java:43)
	at org.apache.spark.sql.execution.WholeStageCodegenExec$$anonfun$8$$anon$1.hasNext(WholeStageCodegenExec.scala:395)
	at scala.collection.Iterator$$anon$11.hasNext(Iterator.scala:408)
	at org.apache.spark.shuffle.sort.BypassMergeSortShuffleWriter.write(BypassMergeSortShuffleWriter.java:125)
	at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:96)
	at org.apache.spark.scheduler.ShuffleMapTask.runTask(ShuffleMapTask.scala:53)
	at org.apache.spark.scheduler.Task.run(Task.scala:108)
	at org.apache.spark.executor.Executor$TaskRunner.run(Executor.scala:335)
	... 3 more

org.xerial.snappy為一個壓縮/解壓庫,我使用的是spark版本是2.2.0,該版本依賴的snappy是1.1.2.6。該版本內容如下:

image

可以看到,該版本的snappy只支持Mac系統的x86和x86_64,並不支持arm64版本。因為該庫是開源庫,故此我試着在github中搜索了一下該項目,果然找到了該項目的源碼源碼地址我試着看了一下master分支的代碼,發現已經做了對arm版的mac系統的支持了。這樣一來問題就簡單了,只要找到引入snappy-java的依賴,直接將其版本升級到最新版即可。

通過IDEA的依賴圖,搜索到是spark-core導入的該庫,我的spark-core版本是2.2.0,引入的snappy-java是1.1.2.6。如圖所示:

image

在mvnrepository中查詢最新版的snappy-java的版本是1.1.8.4,故此直接在spark-core的xml文件中替換掉原來的版本,如圖

image

重新加載依賴再次執行,代碼執行順利,問題搞定。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM