介绍Spark SQL的JSON支持,这是我们在Databricks中开发的一个功能,可以在Spark中更容易查询和创建JSON数据。随着网络和移动应用程序的普及,JSON已经成为Web服务API以及长期存储的常用的交换格式。使用现有的工具,用户通常会使用复杂的管道来在分析系统中读取和写入JSON数据集。在Apache Spark 1.1中发布Spark SQL的JSON支持,在Apache Spark 1.2中增强,极大地简化了使用JSON数据的端到端体验。

现有做法

实际上,用户经常面临使用现代分析系统处理JSON数据的困难。要将数据集写入JSON格式,用户首先需要编写逻辑将其数据转换为JSON。要阅读和查询JSON数据集,通常的做法是使用ETL流水线将JSON记录转换为预定义的结构。在这种情况下,用户必须等待该进程完成才能使用其数据。对于写作和阅读,定义和维护模式定义通常会使ETL任务更加繁重,并消除了半结构化JSON格式的许多优点。如果用户想要使用新的数据,则他们在创建外部表时必须费力定义模式,然后使用自定义的JSON序列化/反序列化库,或者使用JSON UDF的组合来查询数据。

例如,考虑具有以下JSON模式的数据集:

{"name":"Yin", "address":{"city":"Columbus","state":"Ohio"}}
{"name":"Michael", "address":{"city":null, "state":"California"}}

在像Hive这样的系统中,JSON对象通常存储为单列的值。要访问此数据,将使用UDF提取和展平JSON对象中的字段。在下面显示的SQL查询中,提取外部字段(名称和地址),然后进一步提取嵌套地址字段。

在下面的示例中,假设上面显示的JSON数据集存储在名为people的表中,JSON对象存储在名为jsonObject的列中:

SELECT
v1.name, v2.city, v2.state
FROM people
LATERAL VIEW json_tuple(people.jsonObject, 'name', 'address') v1
as name, address
LATERAL VIEW json_tuple(v1.address, 'city', 'state') v2
as city, state;

JSON support in Spark SQL

Spark SQL提供了一种用于查询JSON数据的自然语法,以及用于读取和写入数据的JSON模式的自动推断。Spark SQL了解JSON数据中的嵌套字段,并允许用户直接访问这些字段,而无需任何明确的转换。Spark SQL中的上述查询如下所示:

SELECT name, age, address.city, address.state FROM people

在Spark SQL中加载和保存JSON数据集

要查询Spark SQL中的JSON数据集,只需要将Spark SQL指向数据的位置。在没有任何用户规范的情况下,自动进行数据集格式推断。在编程API中,可以通过SQLContext提供的jsonFile和jsonRDD方法来完成。使用这两种方法,您可以为给定的JSON数据集创建一个SchemaRDD,然后可以将SchemaRDD注册为表格。这是一个例子:

// Create a SQLContext (sc is an existing SparkContext)
val sqlContext = new org.apache.spark.sql.SQLContext(sc)
// Suppose that you have a text file called people with the following content:
// {"name":"Yin", "address":{"city":"Columbus","state":"Ohio"}}
// {"name":"Michael", "address":{"city":null, "state":"California"}}
// Create a SchemaRDD for the JSON dataset.
val people = sqlContext.jsonFile("[the path to file people]")
// Register the created SchemaRDD as a temporary table.
people.registerTempTable("people")

也可以使用纯SQL API创建JSON数据集。例如,对于通过JDBC服务器连接到Spark SQL的用户,他们可以使用:

CREATE TEMPORARY TABLE people
USING org.apache.spark.sql.json
OPTIONS (path '[the path to the JSON dataset]')

在上述示例中,由于未提供数据结构,Spark SQL将通过扫描JSON数据集自动推断模式。当一个字段是JSON对象或数组时,Spark SQL将使用STRUCT类型和ARRAY类型来表示此字段的类型。由于JSON是半结构化的,不同的元素可能具有不同的模式,Spark SQL也将解决字段数据类型的冲突。要了解JSON数据集的架构是什么,用户可以使用编程API中返回的SchemaRDD提供的printSchema()方法或SQL中使用DESCRIBE [table name]来显示模式。例如,通过people.printSchema()可视化的人的模式将是:

root
|-- address: struct (nullable = true)
| |-- city: string (nullable = true)
| |-- state: string (nullable = true)
|-- name: string (nullable = true)

或者,当使用jsonFile和jsonRDD创建表时,用户可以将模式应用于JSON数据集。在这种情况下,Spark SQL将将提供的模式绑定到JSON数据集,并且不会推断模式。用户不需要知道JSON数据集中出现的所有字段。指定的模式可以是出现在数据集中的字段的子集,也可以是不存在的字段。

创建表示JSON数据集的表后,用户可以轻松地在JSON数据集上编写SQL查询,就像常规表一样。与Spark SQL中的所有查询一样,查询的结果由另一个SchemaRDD表示。例如:

val nameAndAddress = sqlContext.sql("SELECT name, address.city, address.state FROM people")
nameAndAddress.collect.foreach(println)

SQL查询的结果可以由其他数据分析任务直接和立即使用,例如机器学习管道。此外,JSON数据集可以轻松地缓存在Spark SQL内置的内存列存储中,并以其他格式保存,如Parquet或Avro。

将SchemaRDD保存为JSON文件

在Spark SQL中,SchemaRDD可以通过toJSON方法以JSON格式输出。由于SchemaRDD始终包含模式(包括对嵌套和复杂类型的支持),Spark SQL可以自动将数据集转换为JSON,而不需要用户定义的格式。SchemaRDD本身可以从许多类型的数据源创建,包括Apache Hive表,Parquet文件,JDBC,Avro文件,或者是对现有SchemaRDD的查询结果。这种组合意味着无论数据源的来源如何,用户都可以以最小的努力将数据迁移到JSON格式。

What’s next?

处理具有大量字段的JSON数据集

JSON数据通常是半结构化、非固定结构的。将来,我们将扩展Spark SQL对JSON支持,以处理数据集中的每个对象可能具有相当不同的结构的情况。例如,考虑使用JSON字段来保存表示HTTP标头的键/值对的数据集。每个记录可能会引入新的标题类型,并为每个记录使用一个不同的列将产生一个非常宽的模式。我们计划支持自动检测这种情况,而是使用map类型。因此,每行可以包含Map,使得能够查询其键/值对。这样,Spark SQL将处理具有更少结构的JSON数据集,推动了基于SQL的系统可以处理的那种查询的边界。

Spark sql ---JSON的更多相关文章

  1. Spark SQL JSON数据处理

    背景   这一篇可以说是“Hive JSON数据处理的一点探索”的兄弟篇.   平台为了加速即席查询的分析效率,在我们的Hadoop集群上安装部署了Spark Server,并且与我们的Hive数据仓 ...

  2. 【转载】Spark SQL之External DataSource外部数据源

    http://blog.csdn.net/oopsoom/article/details/42061077 一.Spark SQL External DataSource简介 随着Spark1.2的发 ...

  3. Spark SQL External DataSource简介

    随着Spark1.2的发布,Spark SQL开始正式支持外部数据源.这使得Spark SQL支持了更多的类型数据源,如json, parquet, avro, csv格式.只要我们愿意,我们可以开发 ...

  4. 第十一篇:Spark SQL 源码分析之 External DataSource外部数据源

    上周Spark1.2刚发布,周末在家没事,把这个特性给了解一下,顺便分析下源码,看一看这个特性是如何设计及实现的. /** Spark SQL源码分析系列文章*/ (Ps: External Data ...

  5. spark sql 导出数据

    如果用户希望在spark sql 中,执行某个sql 后,将其结果集保存到本地,并且指定csv 或者 json 格式,在 beeline 中,实现起来很麻烦.通常的做法是将其create table ...

  6. Spark SQL之External DataSource外部数据源(二)源代码分析

    上周Spark1.2刚公布,周末在家没事,把这个特性给了解一下,顺便分析下源代码,看一看这个特性是怎样设计及实现的. /** Spark SQL源代码分析系列文章*/ (Ps: External Da ...

  7. Spark SQL,如何将 DataFrame 转为 json 格式

    今天主要介绍一下如何将 Spark dataframe 的数据转成 json 数据.用到的是 scala 提供的 json 处理的 api. 用过 Spark SQL 应该知道,Spark dataf ...

  8. spark SQL学习(数据源之json)

    准备工作 数据文件students.json {"id":1, "name":"leo", "age":18} {&qu ...

  9. Spark SQL 之 Data Sources

    #Spark SQL 之 Data Sources 转载请注明出处:http://www.cnblogs.com/BYRans/ 数据源(Data Source) Spark SQL的DataFram ...

随机推荐

  1. JavaScript笔记之第一天

    JavaScript 1.JavaScript 显示数据 JavaScript 可以通过不同的方式来输出数据: 使用 window.alert() 弹出警告框. 使用 document.write() ...

  2. jQuery方法输出有几个checkbox框被选中

    每选中一个多选框,输出有多少个选中 <!DOCTYPE html> <html lang="en"> <head> <meta chars ...

  3. Linux虚拟机之间实现密钥登陆

    Server1与Server2在同一虚拟网络当中,在Server2中使用Server1的Hostname连接Server1,并且无需密码认证. Server1,  Hostname:  hlmvmea ...

  4. 源码编译安装bind

    author:JevonWei 版权声明:原创作品 编译bind 准备阶段: 下载bind软件包,然后传输到系统中 https://www.isc.org/downloads/ 安装开发包组 yum ...

  5. 一起来学linux:shell script(一)关于变量

    p { margin-bottom: 0.25cm; line-height: 120% } (一)首先来看什么是变量,在shell中打印出变量采用的是echo $path或者echo ${path} ...

  6. css中使用变量

    2017年3月,微软宣布 Edge 浏览器将支持 CSS 变量.这个重要的 CSS 新功能,所有主要浏览器已经都支持了. 声明css变量的时候,变量名前面要加两根连词线(--).变量名大小写敏感,-- ...

  7. vue2+swiper(用户操作swiper后,不能autoplay了)

    将autoplayDisableOnInteraction设置为false

  8. poj 2553 强连通

    题意:给出一个有向图,定义:若节点v所有能到达的点{wi},都能反过来到达v,那么称节点v是sink.题目要求所有的sink点. 思路:强连通缩点找出出度为零的点,输出即可. 这题主要问题是读题,了解 ...

  9. 使用github出了些问题?fatal: unable to access;Failed connect to github.com:8087;

    使用github出了些问题?fatal: unable to access;Failed connect to github.com:8087; No error 我今天使用git push orig ...

  10. bootstrap 表单+按钮+对话框

    <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content ...