跳转到主要内容
工程的博客

介绍Apache火花数据集

分享这篇文章

开发人员总是喜欢Apache火花提供简单但功能强大的api,结合特征以最小的程序员努力使复杂的分析成为可能。在砖,我们继续推动火花的可用性和性能通过引入信封DataFrames火花SQL。这些都是高级的api来处理结构化数据(如数据库表,JSON文件),让火花自动优化存储和计算。这些api,背后催化剂优化器钨执行引擎优化应用程序的方式是不可能引发的面向对象(抽样)API,比如操作数据的原始二进制形式。

今天我们兴奋地宣布引发数据集,DataFrame API,它提供了一个的延伸类型安全的、面向对象的编程接口火花1.6包括一个API的预览数据集,他们将是未来的发展重点几个版本的火花。像DataFrames,数据集利用火花的催化剂优化器通过暴露表达式和数据字段查询计划。内存中数据集也利用钨的快速编码。数据集使用编译时类型安全扩展这些好处——这意味着生产应用程序可以检查错误之前运行。他们还允许直接操作在用户定义的类。

从长远来看,我们预计数据将成为一个强大的方式编写更高效引发应用程序。我们设计了他们一起工作现有的抽样API,但提高效率时,数据可以以结构化的形式来表示。火花1.6提供了第一个看到的数据集,我们希望提高他们在将来的版本中。

使用数据集

数据集是强类型的,不可变的对象集合映射到一个关系模式。数据集的核心API是一个新的概念叫做一个编码器,负责JVM之间的转换对象和表格表示。表格表示使用引发的内部钨二进制格式存储,允许操作序列化数据,提高内存利用率。火花1.6附带支持自动生成编码器为各种类型,包括原始类型(如字符串、整数、长),Scala case类,和Java bean。

抽样的用户会发现数据API相当熟悉,因为它提供了许多相同的功能转换(如地图、flatMap、过滤器)。考虑下面的代码,它读取一个文本文件和将他们分为单词:

抽样

val行= sc.textFile(维基百科“/”)
val语言=行
.flatMap (_。分割(" "))
.filter (_ ! = " ")

数据集

val行= sqlContext.read.text(维基百科“/”)。as [String]
val语言=行
.flatMap (_。分割(" "))
.filter (_ ! = " ")

这两种api很容易表达转换使用lambda函数。编译器和IDE理解所使用的类型,并可以提供有用的提示和错误消息当你构建你的数据管道。

虽然这个高级代码可能看起来类似的语法,数据集也有访问所有的力量全面关系执行引擎。例如,如果你现在想要执行一个聚合(如计算每个单词出现的次数),该操作可以简单有效地表达如下:

抽样

val数=单词
.groupBy (_.toLowerCase)
. map (w = > (w。_1,w._2.size))

数据集

val数=单词
.groupBy (_.toLowerCase)
.count ()

因为字数的数据集版本可以利用内置的聚合,这个计算不仅可以表达用更少的代码,但它也将执行更快。你可以看到在下面的图中,数据集的实现比天真的抽样实现跑快得多。相比之下,使用抽样得到相同的性能需要用户手动地考虑如何表达计算的方式对优化。

Distributed-Wordcount-Chart

这个新的数据集API的另一个好处是减少内存的使用。因为火花理解数据结构的数据集,它可以创建一个更优的布局时在内存中缓存数据集。在下面的例子中,我们比较缓存几百万字符串在内存中使用数据集与抽样。在这两种情况下,缓存数据对于后续的查询可能会导致显著的性能改进。然而,由于数据编码器提供更多的信息引发的数据存储,可以优化缓存表示使用4.5倍更少的空间。

Memory-Usage-when-Caching-Chart

闪电般的序列化与编码器

编码器是高度优化和使用运行时代码生成来构建自定义序列化和反序列化的字节码。结果,他们可以显著快于Java或Kryo序列化。

Serialization-Deserialization-Performance-Chart

除了速度,结果序列化编码的数据的大小也可以小得多(2 x),减少网络传输的成本。此外,序列化数据已经在钨二进制格式,这意味着许多操作可以一次完成,而不需要实现一个对象。火花内置支持自动生成编码器为原始类型(如字符串、整数、长),Scala case类,和Java bean。我们计划开放此功能,允许有效的自定义序列化类型在将来发布的版本中。

无缝支持半结构化数据

编码器的力量超越的性能。他们也作为一个强大的半结构化的格式(例如JSON)之间的桥梁和类型安全的语言,像Java和Scala。

例如,考虑以下关于大学数据集:

{" name ":“加州大学伯克利分校”,“yearFounded”: 1868年,numStudents: 37581}
{" name ":“麻省理工学院”,“yearFounded”: 1860年,numStudents: 11318}

代替手动提取字段和铸造他们所需的类型,您可以简单地定义一个类与预期结构和映射输入数据。列是自动排列的名字,并保存类型。

case类大学(名称:字符串,numStudents:长,yearFounded:长)
val学校= sqlContext.read.json (“/ schools.json”)。as[大学]
学校。地图(= >年代" $ {s.name} ${2015年代。yearFounded}岁”)

编码器急切地检查你的数据匹配预期的模式,提供有用的错误信息在你尝试错误的过程TBs的数据。举个例子,如果我们尝试使用一个数据类型,太小,这样转换为一个对象将导致截断(即numStudents大于一个字节,该基金持有的最大值255)分析器将发出一个AnalysisException。

case类大学(numStudents:字节)
val学校= sqlContext.read.json (“/ schools.json”)。as[大学]

org.apache.spark.sql。AnalysisException:不能向上的yearFounded从bigint smallint截断

当执行映射,编码器将自动处理复杂类型,包括嵌套类、数组和地图。

一个Java API和Scala

数据集的API的另一个目标是提供一个接口,可用在Scala和Java。这个统一为Java用户来说是个好消息,因为它确保他们不会落后于Scala api接口,可以很容易地使用一些代码示例从语言和库不再需要处理两种不同类型的输入。为Java用户唯一的区别是他们需要指定要使用的编码器,因为编译器不提供类型信息。例如,如果想要处理json数据使用Java可以做到如下:

公共大学实现了可序列化的{私人字符串名称;私人numStudents;私人yearFounded;公共无效setName(字符串名称){…}公共字符串getName(){…}公共无效setNumStudents(numStudents){…}公共getNumStudents(){…}公共无效setYearFounded(yearFounded){…}公共getYearFounded(){…}}BuildString实现了MapFunction<大学字符串=”“> {公共字符串调用大学(u)抛出异常{返回u.getName () +“是”+ (2015年——u.getYearFounded ()) +“岁”。;}}数据集<大学>学校= context.read () . json (“/ schools.json”)。as (Encoders.bean (University.class));数据集<字符串> = schools.map(字符串BuildString (), Encoders.STRING()); < /字符串> < /大学> < / >大学

期待

当数据集是一个新的API,我们让他们互操作很容易与抽样和现有火花项目。简单地调用抽样()数据集将给一个抽样方法。从长远来看,我们希望数据集可以成为常用方法处理结构化数据,进一步和我们可能收敛api。

2.0我们期待的火花,我们计划一些激动人心的数据集的改进,具体来说:

  • 性能优化,在很多情况下,数据集的当前实现API尚未利用的额外信息,可以低于抽样。接下来的几个版本中,我们将致力于改善性能的新API。
  • 定制的编码器,而我们目前autogenerate编码器为各种类型,我们想打开自定义对象的API。
  • Python支持。
  • 统一与数据集DataFrames——由于兼容性担保,DataFrames,目前数据不能共享一个共同的父类。火花2.0,我们将能够统一这些抽象有轻微改变API,使它容易与建库工作。

如果你想尝试自己的数据集,他们已经在砖。今天在砖火花1.6是可用的,注册一个免费14天的审判

免费试着砖

相关的帖子

看到所有工程的博客的帖子