云服务器价格_云数据库_云主机【优惠】最新活动-搜集站云资讯

分布式存储_海康云存储价格_

小七 141 0

三个apachespark api的故事:RDDs与数据帧和数据集

在数据库里试试这个笔记本在所有开发人员的喜悦中,最吸引人的莫过于一组让开发人员高效、易于使用、直观和表达的api。apachespark对开发人员的吸引力之一是它易于使用的api,可以跨语言(Scala、Java、Python和R)操作大型数据集。在这个博客中,我探讨了apachespark2.2及更高版本中可用的三组api、rdd、DataFrames和dataset;为什么以及何时应该使用每一组;概述它们的性能和优化优势;并列举使用数据帧和数据集而不是rdd的场景。我主要关注数据帧和数据集,因为在ApacheSpark2.0中,这两个API是统一的。我们在这一统一背后的主要动机是通过限制您必须学习的概念数量和提供处理结构化数据的方法来简化Spark。通过结构,Spark可以提供更高层次的抽象和api作为领域特定的语言构造。弹性分布式数据集(RDD)RDD是Spark中面向用户的主要API。从核心上讲,RDD是数据元素的不可变的分布式集合,在集群中的节点之间进行分区,可以与提供转换和操作的低级API并行操作。何时使用RDDs?在以下情况下,请考虑使用RDD的以下场景或常见用例:您需要对数据集进行低级转换、操作和控制;你的数据是非结构化的,比如媒体流或文本流;你想用函数式编程构造而不是特定于域的表达式来操作数据;在按名称或列处理或访问数据属性时,您不关心强制使用模式(如列格式);以及对于结构化和半结构化数据,您可以放弃数据帧和数据集的一些优化和性能优势。apachespark2.0中的RDDs会发生什么变化?你可能会问:RDD被降级为二等公民吗?他们被弃用了吗?答案是响亮的不!此外,正如您将在下面指出的,您可以通过简单的API方法调用在DataFrame或Dataset和rdd之间无缝地移动,并且DataFrames和Dataset构建在rdd之上。数据帧像RDD一样,数据帧是不可变的分布式数据集合。与RDD不同,数据被组织成命名列,就像关系数据库中的表一样。DataFrame旨在使大型数据集的处理更加容易,它允许开发人员将一个结构强加到分布式数据集合上,从而允许更高级别的抽象;它提供了一个特定于域的语言API来操作分布式数据;并使Spark更容易被专业数据工程师以外的受众访问。在ApacheSpark2.0网络研讨会和后续博客的预览中,我们提到在Spark 2.0中,数据帧API将与数据集API合并,统一跨库的数据处理能力。由于这种统一性,开发人员现在需要学习或记住的概念更少了,只需要使用一个称为Dataset的高级和类型安全API。数据集集合从Spark 2.0开始,Dataset具有两个截然不同的API特性:强类型API和非类型API,如下表所示。从概念上讲,将DataFrame看作是一组通用对象Dataset[Row]的别名,其中一行是通用的非类型化JVM对象。相反,Dataset是强类型JVM对象的集合,由Scala中定义的case类或Java中的类决定。类型化和非类型化API语言主要抽象斯卡拉Dataset[T]和DataFrame(Dataset[Row]的别名)Java数据集蟒蛇*数据帧R*数据帧注意:由于Python和R没有编译时类型安全性,我们只有非类型化的api,即数据帧。数据集API的好处作为Spark开发人员,您可以从许多方面受益于Spark 2.0中的DataFrame和Dataset统一API。1静态类型和运行时类型安全将静态类型和运行时安全视为一个范围,SQL限制最少,而Dataset限制最大。例如,在Spark SQL字符串查询中,直到运行时才知道语法错误(这可能代价高昂),而在数据帧和数据集中,您可以在编译时捕获错误(这可以节省开发人员的时间和成本)。也就是说,如果在DataFrame中调用一个不属于API的函数,编译器将捕捉到它。但是,直到运行时它才会检测到不存在的列名。在光谱的另一端是数据集,这是最严格的。由于数据集api都表示为lambda函数和JVM类型化对象,因此在编译时将检测到类型化参数的任何不匹配。此外,在使用数据集时,也可以在编译时检测到分析错误,从而节省开发人员的时间和成本。所有这些都转化为Spark代码中的语法和分析错误的类型安全谱,对于开发人员来说,数据集是最具限制性但也是最有效的。2结构化和半结构化数据的高级抽象和自定义视图DataFrames作为数据集的集合[Row]将结构化自定义视图呈现到半结构化数据中。例如,假设您有一个巨大的物联网设备事件数据集,用JSON表示。由于JSON是一种半结构化格式,它很适合将Dataset用作强类型特定数据集[DeviceIoTData]的集合。{"device_id":198164,"device_name":"sensor-pad-198164owomcJZ","ip":"80.55.20.25","cca2":"PL","cca3":"POL","cn":"POL","latitude":53.080000,"longitude":18.620000,"scale":"Celsius","temp":21,"湿度":65,"电池电量:8","c02_电平":1408,"lcd":"red","时间戳":1458081226051}您可以用Scala case类将每个JSON条目表示为一个自定义对象DeviceIoTData。case类DeviceIoTData(电池_电平:Long,c02_电平:Long,cca2:String,cca3:String,cn:String,device_id:Long,设备名:String,湿度:Long,ip:String,纬度:Double,lcd:String,经度:Double,刻度:字符串,温度:长,时间戳:长)接下来,我们可以从JSON文件读取数据。//读取json文件并从//案例类设备数据//ds现在是jvmscala对象DeviceIoTData的集合值ds=spark.read.json("/databricks公共数据集/data/iot/iot_设备.json")。作为[DeviceIoTData]在上面的代码中,下面发生了三件事:Spark读取JSON,推断模式,并创建一个数据帧集合。此时,Spark将您的数据转换为DataFrame=Dataset[Row],一个泛型Row对象的集合,因为它不知道确切的类型。现在,Spark转换Dataset[Row]->Dataset[DeviceIoTData]类型特定的scalajvm对象,如类DeviceIoTData所示。我们大多数处理结构化数据的人都习惯于以列的方式查看和处理数据,或者访问对象中的特定属性。使用Dataset作为Dataset[ElementType]类型对象的集合,您可以无缝地获得强类型JVM对象的编译时安全性和自定义视图。从上面的代码得到的强类型数据集[T]可以很容易地用高级方法显示或处理。三。易于使用的API结构尽管结构可能会限制Spark程序对数据的控制,但它引入了丰富的语义和一组简单的特定于域的操作,这些操作可以表示为高级构造。然而,大多数计算都可以使用Dataset的高级API完成。例如,通过访问数据集类型化对象的DeviceIoTData来执行agg、select、sum、avg、map、filter或groupBy操作要比使用RDD行的数据字段简单得多。在特定于域的API中表示计算要比使用关系代数类型表达式(在RDDs中)简单得多。例如,下面的代码将filter()和map()创建另一个不可变的数据集。//使用filter()、map()、groupBy()country和compute avg()//温度和湿度。此操作将导致//另一个不可变的数据集。查询更容易阅读,//表现力强值dsAvgTmp=ds.过滤器(d=>{d.temp>25})地图(d=>(d.temp,d.hummy,d.cca3)).groupBy($"_3").avg()//显示结果数据集显示(dsAvgTmp)4性能和优化除了以上所有优点之外,您不能忽视使用数据帧和数据集API时的空间效率和性能提高,原因有两个。首先,由于DataFrame和Dataset api构建在sparksql引擎之上,它使用Catalyst生成优化的逻辑和物理查询计划。在R、Java、Scala或Python数据帧/数据集api中,所有关系类型查询都经过相同的代码优化器,从而提供了空间和速度效率。虽然Dataset[T]类型的API针对数据工程任务进行了优化,但非类型化的Dataset[Row](DataFrame的别名)甚至更快,适合于交互式分析。其次,由于Spark作为编译器理解数据集类型的JVM对象,因此它使用编码器将特定于类型的JVM对象映射到tungton的内部内存表示。因此,钨丝编码器可以高效地序列化/反序列化JVM对象,并生成可以以更高速度执行的紧凑字节码。何时应该使用数据帧或数据集?如果您想要丰富的语义、高级抽象和特定于域的api,请使用DataFrame或Dataset。如果您的处理需要高级表达式、过滤器、映射、聚合、平均值、求和、SQL查询、列访问以及对半结构化数据使用lambda函数,请使用DataFrame或Dataset。如果您希望在编译时获得更高程度的类型安全性,想要类型化的JVM对象,利用Catalyst优化,并从钨极高效的代码生成中获益,那么就使用Dataset。如果您希望跨Spark库统一和简化API,请使用DataFrame或Dataset。如果您是R用户,请使用DataFrames。如果您是Python用户,请使用DataFrames,如果您需要更多的控制,可以使用RDDs。注意y