Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/apache-spark/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Apache spark 在Amazon EMR中将JSON转换为拼花地板_Apache Spark_Emr - Fatal编程技术网

Apache spark 在Amazon EMR中将JSON转换为拼花地板

Apache spark 在Amazon EMR中将JSON转换为拼花地板,apache-spark,emr,Apache Spark,Emr,我需要实现以下目标,但由于缺乏Spark方面的经验,我很难找到实现目标的方法: 从存储在S3中的.json.gz文件读取数据。 每个文件都包含一部分Google Analytics数据,其模式如中所述 文件名的格式为ga_sessions_20170101_Part000000000000_TX.json.gz,其中20170101是一个YYYYMMDD日期规范,000000000000是一个增量计数器,当一天有多个文件时(通常情况下) 因此,一整天的数据由多个文件组成,这些文件具有递增的“

我需要实现以下目标,但由于缺乏Spark方面的经验,我很难找到实现目标的方法:

  • 从存储在S3中的.json.gz文件读取数据。
    • 每个文件都包含一部分Google Analytics数据,其模式如中所述
    • 文件名的格式为ga_sessions_20170101_Part000000000000_TX.json.gz,其中20170101是一个YYYYMMDD日期规范,000000000000是一个增量计数器,当一天有多个文件时(通常情况下)
    • 因此,一整天的数据由多个文件组成,这些文件具有递增的“零件号”
    • 通常每天有3到5个文件
    • JSON文件中的所有字段都使用qoute(“)分隔符存储,而与上述模式文档中指定的数据类型无关。因此,读取文件(通过sqlContext.read.JSON)产生的数据帧将每个字段类型化为字符串,即使其中一些字段实际上是整型、布尔型或其他数据类型
  • 根据架构规范将所有字符串数据框转换为正确类型的数据框。
    • 我的目标是正确地键入数据帧,以便以拼花格式保存时数据类型是正确的
    • 并非架构规范中的所有字段都存在于每个输入文件中,甚至每天的输入文件中(架构可能随时间而改变)。因此,转换需要是动态的,只转换数据框中实际存在的字段的数据类型
  • 将正确键入的数据框中的数据以拼花格式写回S3。
    • 数据应按天进行分区,每个分区存储在名为“partition_date=yyyyymmdd”的单独文件夹中,其中“YYYYMMDD”是与数据关联的实际日期(来自原始输入文件名)
    • 我认为每天文件的数量无关紧要,目标只是得到分区拼花地板格式的数据,我可以指向这些数据
我能够成功地读取和写入数据,但在整个任务的几个方面没有成功:

  • 我不知道如何解决这个问题,以确保我有效地利用AWS EMR集群的全部并行/分布式处理潜力,无论是在读取、转换还是写入数据。我想根据需要调整集群的大小,以便在我选择的任何时间范围内(在合理范围内)完成任务
  • 我不知道如何最好地完成数据类型转换。不知道在任何特定批输入文件中会出现或不会出现哪些字段需要动态代码来重新键入数据帧。我还想确保有效地分发此任务,而不是低效地完成此任务(我关心的是在重新键入每个字段时创建一个新的数据框)
  • 我不明白如何适当地管理数据分区

如果您的输入JSON有固定模式,您可以手动指定DF模式,并将字段声明为可选字段。请参阅官方网站。 如果所有值都在“”中,则可以将它们作为字符串读取,然后转换为所需的类型

我不知道如何处理这个问题,以确保我有效地

使用Dataframe API读取输入,很可能默认值适用于此任务。如果遇到性能问题,请附加Spark作业时间线

我不知道如何最好地完成数据类型转换

使用cast
column.cast(数据类型)
方法

例如,您有两个JSON:

{“foo”:“firstVal”}{“foo”:“val”,“bar”:“1”}

如果你想把“foo”读作字符串,把bar读作整数,你可以这样写:

  val schema = StructType(
    StructField("foo", StringType, true) ::
      StructField("bar", StringType, true) :: Nil
  )
  val df = session.read
    .format("json").option("path", s"${yourPath}")
    .schema(schema)
    .load()

  val withCast = df.select('foo, 'bar cast IntegerType)
  withCast.show()
  withCast.write.format("parquet").save(s"${outputPath}")

谢谢你的建议。你已经解决了我文章的几个方面,并帮助我取得了一些进展。不过,我确实在一个问题上投入了太多,所以我将针对我剩余的问题发布单独的问题。