太長不看版
直接找到引入該依賴的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。該版本內容如下:
可以看到,該版本的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。如圖所示:
在mvnrepository中查詢最新版的snappy-java的版本是1.1.8.4,故此直接在spark-core的xml文件中替換掉原來的版本,如圖
重新加載依賴再次執行,代碼執行順利,問題搞定。