最近接到一個需求,需要對spark的結果分目錄輸出,百度之后找到了解決方案,大多都是spark 按照key分目錄輸出,
但是在文件當中,會把key也輸出出來,在這里以key作為目錄是想建hive表時把 01,02當做分區的,結果文件中不需要保存key值。其實在mr中也有類似需求,我的輸出只要key-value對中的value,不要key,在mr中是怎么解決的呢,將輸出設置為NullWritable,spark里也是這樣的,上代碼
多目錄輸出,首先要創建一個繼承MultipleTextOutputFormat的新類,重寫其generateFileNameForKeyValue 方法,方法的返回值就是動態生成的目錄的名稱,這里的返回值是用value計算的,
class RDDMultipleTextOutputFormat[K, V]() extends MultipleTextOutputFormat[K, V]() { //private val output:TextOutputFormat[String, String] = null override def generateFileNameForKeyValue(key: K, value: V, name: String) : String = { val dt = Utils.getDt(value.toString.split("\t",-1)(2)) s"$dt/$name" } }
定義好RDDMultipleTextOutputFormat后,就可以保存rdd結果了
lines.saveAsHadoopFile( outPath, classOf[NullWritable], //這里定義的是NullWritable,那么pairRdd 就應該是RDD[NullWritable,String]類型的 classOf[String], classOf[RDDMultipleTextOutputFormat[_, _]],classOf[GzipCodec])
這樣輸出結果就會按照自己的要求分目錄輸出了,classOf[GzipCodec] 指定輸出結果的壓縮方式