Scala 火花整个纺织品-许多小文件

Scala 火花整个纺织品-许多小文件,scala,apache-spark,optimization,geotools,Scala,Apache Spark,Optimization,Geotools,我想通过spark接收许多小文本文件到拼花地板。目前,我使用wholeTextFiles并执行一些额外的解析 更准确地说,这些小文本文件是ESRi ASCII网格文件,每个文件的最大大小约为400kb。GeoTools用于解析它们,如下所述 您是否看到任何优化的可能性?也许是为了避免创建不必要的对象?或者更好地处理小文件的东西。我想知道只获取文件路径并手动读取它们是否比使用String->ByteArrayInputStream更好 case class RawRecords(path: Str

我想通过spark接收许多小文本文件到拼花地板。目前,我使用
wholeTextFiles
并执行一些额外的解析

更准确地说,这些小文本文件是ESRi ASCII网格文件,每个文件的最大大小约为400kb。GeoTools用于解析它们,如下所述

您是否看到任何优化的可能性?也许是为了避免创建不必要的对象?或者更好地处理小文件的东西。我想知道只获取文件路径并手动读取它们是否比使用
String->ByteArrayInputStream
更好

case class RawRecords(path: String, content: String)
case class GeometryId(idPath: String, value: Double, geo: String)
@transient lazy val extractor = new PolygonExtractionProcess()
@transient lazy val writer = new WKTWriter()

def readRawFiles(path: String, parallelism: Int, spark: SparkSession) = {
    import spark.implicits._
    spark.sparkContext
      .wholeTextFiles(path, parallelism)
      .toDF("path", "content")
      .as[RawRecords]
      .mapPartitions(mapToSimpleTypes)
  }

def mapToSimpleTypes(iterator: Iterator[RawRecords]): Iterator[GeometryId] = iterator.flatMap(r => {
    val extractor = new PolygonExtractionProcess()

    // http://docs.geotools.org/latest/userguide/library/coverage/arcgrid.html
    val readRaster = new ArcGridReader(new ByteArrayInputStream(r.content.getBytes(StandardCharsets.UTF_8))).read(null)

    // TODO maybe consider optimization of known size instead of using growable data structure
    val vectorizedFeatures = extractor.execute(readRaster, 0, true, null, null, null, null).features
    val result: collection.Seq[GeometryId] with Growable[GeometryId] = mutable.Buffer[GeometryId]()

    while (vectorizedFeatures.hasNext) {
      val vectorizedFeature = vectorizedFeatures.next()
      val geomWKTLineString = vectorizedFeature.getDefaultGeometry match {
        case g: Geometry => writer.write(g)
      }
      val geomUserdata = vectorizedFeature.getAttribute(1).asInstanceOf[Double]
      result += GeometryId(r.path, geomUserdata, geomWKTLineString)
    }
    result
  })
我有以下建议:

  • 使用
    wholeTextFile
    ->
    mapPartitions
    ->转换为数据集。为什么?如果对数据集进行
    mapPartitions
    ,则所有行都将从内部格式转换为对象-这会导致额外的序列化
  • 运行Java任务控制并对应用程序进行采样。它将显示方法的所有编译和执行时间
  • 也许您可以使用
    二进制文件
    ,它将为您提供
    ,这样您就可以在
    mapPartitions

  • 钨丝压缩不应该弥补所有的物体问题吗?是否有类似于
    wholeBinaryFiles
    的东西可以为我提供路径和整个文件?@GeorgHeiler您可以使用
    SparkContext.binaryFiles
    ,它返回pair FilePath,datastream什么类型的流是
    PortableDataStream
    ?使用'new ArcGridReader(r._2).read(null)`时,我得到一个
    错误arcgrid:Unsupported input type
    。Edit应该支持任何常规输入流:它工作正常,我错过了对
    PortableDataStream
    上的
    open
    的调用。我现在要做一些分析。我最终希望有一个数据帧转储到拼花地板。正在使用
    spark.read.text
    。你认为用这个替代会更好吗?但这同样会导致许多
    字符串
    对象。如果有帮助,请参阅我的答案,但这同样适用于dataframe: