最近研究了下Spark如何讀寫壓縮格式的文件,主要有如下三種方式,這裏以lzo方式壓縮爲例
/*******************old hadoop api*************************/ val confHadoop = new JobConf confHadoop.set("mapred.output.compress", "true") confHadoop.set("mapred.output.compression.codec", "com.hadoop.compression.lzo.LzopCodec") val textFile = sc.hadoopFile(args(0), classOf[DeprecatedLzoTextInputFormat],classOf[LongWritable], classOf[Text], 1) textFile.saveAsHadoopFile(args(1),classOf[LongWritable], classOf[Text], classOf[TextOutputFormat[LongWritable,Text]],confHadoop) /*******************new hadoop api*************************/ val job = new Job() job.setOutputFormatClass(classOf[TextOutputFormat[LongWritable,Text]]) job.getConfiguration().set("mapred.output.compress", "true") job.getConfiguration().set("mapred.output.compression.codec", "com.hadoop.compression.lzo.LzopCodec") val textFile = sc.newAPIHadoopFile(args(0), classOf[LzoTextInputFormat],classOf[LongWritable], classOf[Text],job.getConfiguration()) textFile.saveAsNewAPIHadoopFile(args(1), classOf[LongWritable], classOf[Text],classOf[TextOutputFormat[LongWritable,Text]],job.getConfiguration()) /*******************textFile*************************/ val textFile = sc.textFile(args(0), 1) textFile.saveAsTextFile(args(1), classOf[LzopCodec])
以上三種方式,基本上利用到了所有Spark提供的主流讀寫文件的API,第一個案例是針對Spark提供的舊版Hadoop API來編寫的,在JobConf中配置壓縮的屬性,讀寫的時候聲明InputFormat和OutputFormat即可。第二個案例是採用新版Hadoop API的方式來編寫的,步驟跟第一個案例類似。最後就是最簡單的一種寫法,在寫入的時候指定Codec即可。
爲了使Spark支持讀寫壓縮格式的文件,還需要做一些基本的配置使得Spark可以加載需要用到的壓縮格式相關的類庫和jar,具體配置如下
spark.executor.extraLibraryPath=/usr/lib/native/ spark.executor.extraClassPath=/usr/lib/hadoop/lib/hadoop-lzo.jar
Spark支持三種配置屬性的方式,優先級由低到高分別是:在conf/spark-defaults.conf中配置,使用spark-submit或spark-shell提交程序的時候配置參數,在Spark程序中通過System.setProperty方法或者通過設置SparkConf對象來配置參數。如果同一個參數配置了多次,以優先級最高的方式中配置的爲準。
上述有關壓縮的配置是針對Executor來說的,還需要在提交的時候針對Driver配置壓縮相關的屬性
--driver-class-path /usr/lib/hadoop/lib/hadoop-lzo.jar --driver-library-path /usr/lib/native
在使用Spark SQL的時候,配置Executor和Driver與壓縮相關的屬性就可以正常讀取Hive目錄下的壓縮文件(我測試的版本是CDH5.0.0和Spark1.0),如果想通過Hive計算後輸出壓縮格式的結果,則在hql()方法中設置壓縮相關的屬性即可,例如
hql("set io.compression.codecs=com.hadoop.compression.lzo.LzoCodec,com.hadoop.compression.lzo.LzopCodec") hql("set io.compression.codec.lzo.class=com.hadoop.compression.lzo.LzoCodec") hql("set mapred.output.compression.codec=com.hadoop.compression.lzo.LzopCodec")
如果NameNode配置了HA,則需要將hdfs-site.xml放入$SPARK_HOME/conf目錄下,否則將導致讀寫HDFS的時候,無法加載到配置文件中的HA provider類,報UnknownHostException異常