要求:按日志文件的指定字段分类,输出到多个文件(夹)。
思路:关键在于自定义类继承 MultipleTextOutputFormat 类,使用 saveAsHadoopFile。
def main(args: Array[String]): Unit = {
…………
val input = sc.textFile("data/access.log")
input.map(x => {
val splits = x.split("\t")
(splits(1), x) //这里写成<k,v>型,将指定字段作为key,使用partitionBy按key分类
}).partitionBy(new HashPartitioner(3)) // 这里必须自定义分区器,否则每个类别会输出并行度个数个文件,且分区数需大于等于指定字段的分类结果数,小于会造成空文件夹
.saveAsHadoopFile(output, classOf[String], classOf[String], classOf[RuozedataMultipleTextOutputFormat], classOf[GzipCodec])
sc.stop()
}
class RuozedataMultipleTextOutputFormat extends MultipleTextOutputFormat[Any, Any] {
override def generateFileNameForKeyValue(key: Any, value: Any, name: String): String = {
s"$key/$key" // key即是指定字段,可用来做文件夹名,name也表示文件名(就是part*,没用)
}
override def generateActualKey(key: Any, value: Any): AnyRef = {
NullWritable.get() //直接写null也行
}
}