Spark 2.0.0 读取具有可变模式的 json 数据

Posted

技术标签:

【中文标题】Spark 2.0.0 读取具有可变模式的 json 数据【英文标题】:Spark 2.0.0 reading json data with variable schema 【发布时间】:2016-12-29 06:16:00 【问题描述】:

我正在尝试处理一个月的网站流量,该流量以 json 格式存储在 S3 存储桶中(每条线路/网站流量命中一个 json 对象)。数据量足够大,我无法要求 Spark 推断架构(OOM 错误)。如果我指定模式,它显然加载得很好。但是,问题在于每个 json 对象中包含的字段不同,因此即使我使用一天的流量构建架构,每月架构也会不同(更多字段),因此我的 Spark 作业失败。

所以我很想了解其他人如何处理这个问题。例如,我可以使用传统的 RDD mapreduce 作业来提取我感兴趣的字段,导出然后将所有内容加载到数据框中。但这很慢,似乎有点弄巧成拙。

我找到了similar question here,但没有适合我的相关信息。

谢谢。

【问题讨论】:

这些文档是如何生成的? @zero323 ELB --> Dropwizard --> Kafka --> S3 【参考方案1】:

如果您知道自己感兴趣的字段,只需提供架构的一个子集。 JSON 阅读器可以优雅地忽略意外字段。假设您的数据如下所示:

import json
import tempfile

object = "foo": "bar": "x": 1, "y": 1, "baz": [1, 2, 3]

_, f = tempfile.mkstemp()
with open(f, "w") as fw:
    json.dump(object, fw)

而您只对foo.bar.xfoo.bar.z 感兴趣(不存在):

from pyspark.sql.types import StructType

schema = StructType.fromJson('fields': ['metadata': ,
   'name': 'foo',
   'nullable': True,
   'type': 'fields': [
       'metadata': , 'name': 'bar', 'nullable': True, 'type': 'fields': [
           'metadata': , 'name': 'x', 'nullable': True, 'type': 'long',
           'metadata': , 'name': 'z', 'nullable': True, 'type': 'double'],
       'type': 'struct'],
    'type': 'struct'],
 'type': 'struct')

df = spark.read.schema(schema).json(f)
df.show()

## +----------+
## |       foo|
## +----------+
## |[[1,null]]|
## +----------+

df.printSchema()
## root
##  |-- foo: struct (nullable = true)
##  |    |-- bar: struct (nullable = true)
##  |    |    |-- x: long (nullable = true)
##  |    |    |-- z: double (nullable = true)

您还可以降低架构推断的采样率以提高整体性能。

【讨论】:

非常感谢您的回答,您帮我解决了一个大问题!

以上是关于Spark 2.0.0 读取具有可变模式的 json 数据的主要内容,如果未能解决你的问题,请参考以下文章

Spark 读取带有部分模式的 json

在 spark 中读取单行 json,其中列键是可变的

Spark基础编程学习03

当函数在具有自动检测模式的 spark 数据帧中不起作用时

Spark parquet 模式演变

SparkSQL