Я новичок в Scala / Spark и надеюсь, что вы, ребята, можете мне помочь. Я хочу получить файлы, которые были созданы после определенной отметки времени, в каталоге hdfs для небольшого мониторинга в Zeppelin. Поэтому мне нужен столбец с именем файла, размером файла и датой модификации.

Я обнаружил, что это работает для меня, чтобы получить всю необходимую информацию:

val fs = FileSystem.get(new Configuration())
val dir: String = "some/hdfs/path"
val input_files = fs.listStatus(new Path(dir)).filter(_.getModificationTime> timeInEpoch)

В результате я хотел бы создать DataFrame в искре со строкой для каждого файла с его информацией (или, по крайней мере, информацией, упомянутой выше)

val data = sc.parallelize(input_files) 
val dfFromData2 = spark.createDataFrame(data).toDF()

Если я попробую так, то получу следующий ответ:

309: error: overloaded method value createDataFrame with alternatives:
  [A <: Product](data: Seq[A])(implicit evidence$3: reflect.runtime.universe.TypeTag[A])org.apache.spark.sql.DataFrame <and>
  [A <: Product](rdd: org.apache.spark.rdd.RDD[A])(implicit evidence$2: reflect.runtime.universe.TypeTag[A])org.apache.spark.sql.DataFrame
 cannot be applied to (org.apache.spark.rdd.RDD[org.apache.hadoop.fs.FileStatus])
       val dfFromData2 = spark.createDataFrame(data).toDF()

Надеюсь, ты сможешь мне помочь :)

Приветствия

1
Dandelon 9 Дек 2020 в 23:34

1 ответ

Лучший ответ

Как указано в сообщении об ошибке, тип Hadoop FileStatus не является подтипом Product, то есть кортежем. Spark DataFrames имеет собственную систему типов в стиле SQL, которая не допускает произвольных сложных типов, таких как FileStatus. Аналогичным образом, если вы попытаетесь выполнить операцию с созданным вами RDD, вы получите аналогичную ошибку, поскольку FileStatus не сериализуем. Лучше всего извлечь нужные данные в виде кортежа или класса case и создать из них DataFrame:

case class FileInfo(name : String, modifiedTime : Long, size : Long)

val df = input_files.map{x => 
           FileInfo(x.getPath.toString, x.getModificationTime, x.getLen)
        }.toSeq.toDF()
1
Charlie Flowers 9 Дек 2020 в 22:31