spark
-
翻译 Apache Spark is a fast and general-purpose cluster computing system. It provides high-level APIs in Java, Scala, Python and R, and an optimized engine that supports general execution graphs. It also supports a rich set of higher-level tools including Spark SQL for SQL and structured data processing, MLlib for machine learning, GraphX for graph processing, and Spark Streaming.
-
什么是spark?
Spark是一个基于内存的快速,通用,可扩展的大数据分析引擎
-
Spark使用Scala语言进行实现,它是一种面向对象、函数式编程语言,能够像操作本地集合对象一样轻松地操作分布式数据集,在Spark官网上介绍,它具有运行速度快、易用性好、通用性强和随处运行等特点。
-
-
spark生态:
-
spark core: spark 的核心计算
-
spark sql :对历史数据做交互式查询(即席查询:用户根据自己的需求 自定义查询)
-
spark Streaming : 近实时计算
-
spark ml :机器学习
-
spark graph :图计算(关注事物本身而且关注事物之间的联系)
-
-
什么是结构化和非结构化?
-
结构化:列固定,值不能随便写
-
非结构化:列不固定,内容随便写
-
-
实时计算框架Storm sparkString flink 区别?
-
有限数据集与无限数据集区别
-
Storm和Flink是属于无限数据集数据持续增长,用于流式处理
-
SparkString是属于有限数据集,处理数据大小有限,批量处理
-
-
Flink是原生的流处理系统,提供high level的API。Flink也提供 API来像Spark一样进行批处理,但两者处理的基础是完全不同的。Flink把批处理当作流处理中的一种特殊情况。在Flink中,所有 的数据都看作流,是一种很好的抽象,因为这更接近于现实世界
-
Storm是一个免费并开源的分布式实时计算系统。利用Storm可以很容易做到可靠地处理无限的数据流,像Hadoop批量处理大数据一样,Storm可以实时处理数据。
Storm 很简单,可用于任意编程语言。Apache Storm 采用 Clojure 开发。Storm 有很多应用场景,包括实时数据分析、联机学习、持续计算、分布式 RPC、ETL 等。
-
Spark流是对于Spark核心API的拓展,从而支持对于实时数据流的可拓展,高吞吐量和容错性流处理。数据可以由多个源取得,例如:Kafka,Flume,Twitter,ZeroMQ,Kinesis或者TCP接口,同时可以使用由如map,reduce,join和window这样的高层接口描述的复杂算法进行处理。最终,处理过的数据可以被推送到文件系统,数据库和HDFS。Spark Streaming是一个粗粒度的框架【也就是只能对一批数据指定处理方法】,核心是采用微批次(Mcro-batch)架构。和Storm采用的以条处理的不同
-
-
spark 的资源调度?
-
standalone yarn mesos
-
Spark中涉及的资源调度可以分为4层:
-
YARN对不同SparkApplication(SparkContext)的调度
-
同一个SparkAppliction内不同资源池(pool)之间的调度
-
同一个SparkAppliction内同一个资源池(pool)内不同TaskSetManager的调度
-
同一个SparkAppliction内同一个资源池(pool)内同一个TaskSetManager内的Task调度
-
-
-
什么是Rdd?
-
RDD(Resilient Distributed Dataset)叫做分布式数据集,是 Spark 中最基本的数据抽象。
代码中是一个抽象类,它代表一个不可变、可分区、里面的元素可并行计算的集合。
-
-
Rdd的属性?
-
一组分区(Partition),即数据集的基本组成单位;
-
一个计算每个分区的函数;
-
RDD 之间的依赖关系;
-
一个 Partitioner,即 RDD 的分片函数;
-
一个列表,存储存取每个 Partition 的优先位置(preferred location)。
-
-
Rdd的特点?
-
RDD 表示只读的分区的数据集,对 RDD 进行改动,只能通过 RDD 的转换操作,由一个 RDD 得到一个新的 RDD,新的 RDD 包含了从其他 RDD 衍生所必需的信息。RDDs 之间存在依赖,RDD 的执行是按照血缘关系延时计算的。如果血缘关系较长,可以通过持久化RDD 来切断血缘关系。
-
-
spark on hive 和 hive on spark?
-
spark on hive:hive作为数据源,spark计算
-
hive on spark:spark 作为hive 底层的计算引擎
-
-
spark 为什么比hadoop 的mr快?
-
基于内存
-
spark实现了DAG引擎
-
spark的容错
-
-
什么是DAG?
-
有向无环图,DAG(Directed Acyclic Graph)叫做有向无环图,原始的 RDD 通过一系列的转换就就形成了 DAG,根据 RDD 之间的依赖关系的不同将 DAG 划分成不同的 Stage,对于窄依赖, partition 的转换处理在 Stage 中完成计算。对于宽依赖,由于有 Shuffle 的存在,只能在 parent。
-
-
spark 的特点?
-
快
-
与Hadoop的MapReduce相比,Spark基于内存的运算要快100倍以上,基于硬盘的运算也要快10倍以上。Spark实现了高效的DAG执行引擎,可以通过基于内存来高效处理数据流。
-
-
易用
-
Spark支持Java、Python和Scala的API,还支持超过80种高级算法,使用户可以快速构建不同的应用。而且Spark支持交互式的Python和Scala的shell,可以非常方便地在这些shell中使用Spark集群来验证解决问题的方法。
-
-
通用
-
Spark提供了统一的解决方案。Spark可以用于批处理、交互式查询(Spark SQL)、实时流处理(Spark Streaming)、机器学习(Spark MLlib)和图计算(GraphX)。这些不同类型的处理都可以在同一个应用中无缝使用。Spark统一的解决方案非常具有吸引力,毕竟任何公司都想用统一的平台去处理遇到的问题,减少开发和维护的人力成本和部署平台的物力成本。
-
-
兼容性
-
Spark可以非常方便地与其他的开源产品进行融合。比如,Spark可以使用Hadoop的YARN和Apache Mesos作为它的资源管理和调度器,并且可以处理所有Hadoop支持的数据,包括HDFS、HBase和Cassandra等。这对于已经部署Hadoop集群的用户特别重要,因为不需要做任何数据迁移就可以使用Spark的强大处理能力。Spark也可以不依赖于第三方的资源管理和调度器,它实现了Standalone作为其内置的资源管理和调度框架,这样进一步降低了Spark的使用门槛,使得所有人都可以非常容易地部署和使用Spark。此外,Spark还提供了在EC2上部署Standalone的Spark集群的工具。
-
-
-
spark 能代替hadoop 吗?
-
不能,仅仅是mr的替代方案
-
spark会替代Hadoop的一部分,会替代Hadoop的计算框架,如mapReduce、Hive查询引擎,但spark本身不提供存储,所以spark不能完全替代Hadoop。
-
-
spark Rdd 的缓存?
-
cache / persist 内存中缓存 ,内部的优化机制。当Rdd 重复被使用了,不需要在重新计算,直接从内存中获取使用
-
-
driver 的作用?
-
运行应用程序的main函数
-
创建spark的上下文
-
划分RDD并生成有向无环图(DAGScheduler)
-
与spark中的其他组进行协调,协调资源等等(SchedulerBackend)
-
生成并发送task到executor(taskScheduler)
-
-
-
Excutor 的作用?
-
执行器进程有两大作用:
-
它们负责运行组成 Spark 应用的任务,并将结果返回给驱动器进程;
-
它们通过自身的块管理器(Block Manager)为用户程序中要求缓存的 RDD 提供内存式存储。RDD 是直接缓存在Executor进程内的,因此任务可以在运行时充分利用缓存数据加速运算。
执行器程序通常都运行在专用的进程中。
-
-
-
spark spark-submit脚本的参数有哪些?
https://blog.youkuaiyun.com/young_0609/article/details/102588093
-
spark 配置的方式?
-
代码 脚本 配置文件 , 优先级一次降低的
-
-
spark的资源调度方式?
-
standalone yarn mesos
-
-
spark 的提交方式有两种?
-
client:提交任务在本机
-
cluster:提交任务在yarn上
-
-
spark collect 算子的作用?
-
collect 相当于 toArray, toArray 已经过时不推荐使用, collect 将分布式的 RDD 返回为一个单机的 scala Array 数组。在这个数组上运用 scala 的函数式操作。
-
-
oom?
-
out of memory 内存溢出
-
-
spark yarn 的提交方式有:
--master yarn-client :资源调度yarn 提交方式 client
--master yarn-cluster :资源调度yarn 提交方式 cluster
-
spark client 和 cluster 提交方式的区别?
主要区别在于:Driver程序的运行节点
-
client:driver 在你当前提交的节点运行,driver 需要频繁的和集群通信占用大量的网络带宽,容易挂掉,好处是方便查看日志便于调试,多用于学习和测试
-
cluster :driver 在集群的节点。挂掉会自动重启
-
-
Rdd的并行度?
-
一个Rdd 可以有多个分片,一个分片对应一个task,分片的个数决定并行度 并行度并不是越高越好, 还要考虑资源的情况
-
-
spark的算子有两种?
转换算子:transformation 由一个Rdd 生成一个新的Rdd 不会被立即执行,记录的都是一系列的操作
动作算子:action 立即执行,返回都是结果
-
spark的容错:
lineage:血缘关系,根据血缘关系从新计算 进行容错
checkpoint:设置检查点,一般都是文件系统,磁盘io
-
spark的持久化?
-
Rdd 多次被复用的情况,可以提高效率,是spark常用的一种优化方式
-
cache RDD 通过 persist 方法或 cache 方法可以将前面的计算结果缓存,默认情况下 persist() 会把数据以序列化的形式缓存在 JVM 的堆空间中
-
persist
-
-
什么是宽依赖,窄依赖?
-
父Rdd 的partition对应一个子Rdd 的partiton 称为窄依赖
-
窄依赖指的是每一个父 RDD 的 Partition 最多被子 RDD 的一个 Partition 使用,窄依赖我
们形象的比喻为独生子女。
-
宽依赖指的是多个子 RDD 的 Partition 会依赖同一个父 RDD 的 Partition,会引起 shuffle,
总结:宽依赖我们形象的比喻为超生。
-
-
总结Rdd 的算子(30个以上)
-
算子 类型 说明 ++ 合并两个RDD aggregate 执行算子 根据初始化值进行对rdd种的元素进行聚合,结束之后每个分区会有一个结果,后面会根据这个分区结果再进行一次聚合 aggregateByKey 执行算子 和aggregate类似,但是操作的是RDD是Pair类型 cache() 控制操作 当第一次遇到Action算子时才会触发持久化操作。Cache()是persis的一种特殊情况,将RDD持久化到内存中 转换算子 Cartesian 转换算子 计算两个RDD之间的笛卡尔乘积,并将它们作为新的RDD返回 coalesce 转换算子 将RDD进行重分区,使用HashPartitioner。它的简版是repartition算子 Cogroup 转换算子 相当于SQL中的全外关联full outer join,返回左右RDD中的记录,关联不上的为空。 Collect 执行算子 一个RDD转换成数组。根据一个偏函数返回一个符合偏函数的结果集RDD。即将RDD转换成数组 collectAsMap 一个RDD转换成Map combineByKey 转换算子 将RDD[K,V]转换成RDD[K,C],这里的V类型和C类型可以相同也可以不同。(单个值类型v操作 , 同分区内合并操作 , 多分区间的合并操作 ) Count 执行算子 返回RDD中的元素数量 countByKey 执行算子 统计RDD[K,V]中每个K的数量。 createCombiner 参数 组合器函数,用于将V类型转换成C类型,输入参数未RDD[K,V]中的V,输出为C distinct 转换算子 去除RDD重复的元素,返回所有元素不重复的RDD flatMap 转换算子 类似于map。1对多,可以理解成将原来的数据集拍扁了。RDD中每个元素可生成一个或多个元素构成的新RDD例如将数组、列表拆分成单个值或字符串拆分成单个字符 flatMapValues 转换算子 类似于flatMap,只不过flatMapValues是针对[K,V]中的V值进行flatMap操作。 filter 转换算子 过滤,根据里面的规则返回(true的)一个过滤过后的rdd First 执行算子 返回RDD中的第一个元素,不排序。 Fold 执行算子 是aggregate的简化版,将aggregate中的seqOp和combOp使用同一个函数op。 foldByKey 转换算子 作用于RDD[K,V],根据K将V做折叠、合并处理。 foreach 执行算子 遍历RDD,将函数f应用于每一个元素。需要注意如果RDD执行foreach,只会在Executor端有效,并且不是Driver端 foreachPartition 执行算子 与foreach类似,只不过是对每一个分区使用f fullOuterJoin 转换算子 类似于SQL的全连接, glom 转换算子 将RDD中每一个分区中所有类型为T的元素转换成Array[T] groupBy 根据业务需求,按照自定义的返回值来分区 groupByKey 转换算子 根据key将value进行分组。该函数用于将RDD[K,V]中每个K对应的V值,合并到一个集合Iterable[V]中 intersection 转换算子 取交集。返回两个RDD中相同的数据集合,返回元素去重。类似于SQL中的inner join join 转换算子 类似于SQL中的内关联join,只返回两个RDD根据K可以关联上的结果
-
-
创建Rdd的方式有几种?
Spark Core为我们提供了三种创建RDD的方式包括:
-
使用程序中的集合创建RDD
-
使用本地文件创建RDD
-
使用HDFS文件创建RDD
-
-
map和mapPartitons有什么区别?
-
rdd的mapPartitions是map的一个变种,它们都可进行分区的并行处理。
-
两者的主要区别是调用的粒度不一样:map的输入变换函数是应用于RDD中每个元素,而mapPartitions的输入函数是应用于每个分区。
-
-
spark的重分区算子? 区别? 抄
-
重分区函数:
repartition(numPartitions:Int):RDD[T]
coalesce(numPartitions:Int,shuffle:Boolean=false):RDD[T]
它们两个都是RDD的分区进行重新划分,repartition只是coalesce接口中shuffle为true的简易实现,(假设RDD有N个分区,需要重新划分成M个分区)
1)N<M。一般情况下N个分区有数据分布不均匀的状况,利用HashPartitioner函数将数据重新分区为M个,这时需要将shuffle设置为true。
2)如果N>M并且N和M相差不多,(假如N是1000,M是100)那么就可以将N个分区中的若干个分区合并成一个新的分区,最终合并为M个分区,这时可以将shuff设置为false,在shuffl为false的情况下,如果M>N时,coalesce为无效的,不进行shuffle过程,父RDD和子RDD之间是窄依赖关系。
3)如果N>M并且两者相差悬殊,这时如果将shuffle设置为false,父子RDD是窄依赖关系,他们同处在一个Stage中,就可能造成Spark程序的并行度不够,从而影响性能,如果在M为1的时候,为了使coalesce之前的操作有更好的并行度,可以讲shuffle设置为true。
-
-
总结宽依赖算子?
-
所有bykey 的算子 groupbykey reducebyky…
-
repatition,cartesian算子
-
部分join算子
-
-
使用什么方法可以代替join?
-
广播变量+map+filter
-
-
reducebykey和groupbykeyt的区别?
-
Reducebykey
-
当采用reduceByKeyt时,Spark可以在每个分区移动数据之前将待输出数据与一个共用的key结合。借助下图可以理解在reduceByKey里究竟发生了什么。 注意在数据对被搬移前同一机器上同样的key是怎样被组合的(reduceByKey中的lamdba函数)。然后lamdba函数在每个区上被再次调用来将所有值reduce成一个最终结果。
-
-
Groupbykeyt
-
当采用groupByKey时,由于它不接收函数,spark只能先将所有的键值对(key-value pair)都移动,这样的后果是集群节点之间的开销很大,导致传输延时。
-
-
因此,在对大数据进行复杂计算时,reduceByKey优于groupByKey。
-
-
DAG如何划分stage?
-
对于窄依赖,partition的转换处理在stage中完成计算,不划分(将窄依赖尽量放在在同一个stage中,可以实现流水线计算) 对于宽依赖,由于有shuffle的存在,只能在父RDD处理完成后,才能开始接下来的计算,也就是说需要要划分stage(出现宽依赖即拆分)
-
总结 Spark会根据shuffle/宽依赖使用回溯算法来对DAG进行Stage划分,从后往前,遇到宽依赖就断开,遇到窄依赖就把当前的RDD加入到当前的stage/阶段中
-
-
如何划分job?
-
由于spark的懒执行,在驱动程序调用一个action之前,spark应用不会做任何事情。针对每个action,Spark调度器就创建一个执行图(execution graph)和启动一个Spark Job。每个job有多个 stage组成,这些stage就是实现最终的RDD所需的数据转换的步骤。一个宽依赖划分为一个stage。每个stage由多个tasks组成,这些tasks就表示每个并行计算并且会在多个执行器上执行。
-
-
Spark的提交流程总结?
-
Driver端启动SparkSubmit进程,启动后开始向Master进行通信,此时创建了一个对象(SparkContext),接着向Master发送任务消息
-
Master接收到任务信息后,开始资源调度,此时会和所有的Worker进行通信,找到空闲的Worker,并通知Worker来拿取任务和启动相应的Executor
-
Executor启动后,开始与Driver进行反向注册,接下来Driver开始把任务发送给相应的Executor,Executor开始计算任务
-
-
Spark持久化的级别?
-
如果使用默认的存储级别(MEMORY_ONLY),存储在内存中的 RDD 没有发生溢出,那么就选择默认的存储级别。默认存储级别可以最大程度的提高 CPU 的效率,可以使在 RDD 上的操作以最快的速度运行。
-
如果内存不能全部存储 RDD,那么使用 MEMORY_ONLY_SER,并挑选一个快速序列化库将对象序列化,以节省内存空间。使用这种存储级别,计算速度仍然很快。
-
持久化的级别
-
val NONE = new StorageLevel(false, false, false, false)
-
val DISK_ONLY = new StorageLevel(true, false, false, false)
-
val DISK_ONLY_2 = new StorageLevel(true, false, false, false, 2)
-
val MEMORY_ONLY = new StorageLevel(false, true, false, true)
-
val MEMORY_ONLY_2 = new StorageLevel(false, true, false, true, 2)
-
val MEMORY_ONLY_SER = new StorageLevel(false, true, false, false)
-
val MEMORY_ONLY_SER_2 = new StorageLevel(false, true, false, false, 2)
-
val MEMORY_AND_DISK = new StorageLevel(true, true, false, true)
-
val MEMORY_AND_DISK_2 = new StorageLevel(true, true, false, true, 2)
-
val MEMORY_AND_DISK_SER = new StorageLevel(true, true, false, false)
-
val MEMORY_AND_DISK_SER_2 = new StorageLevel(true, true, false, false, 2)
-
val OFF_HEAP = new StorageLevel(true, true, true, false, 1)
-
-
-
Spark持久化的选择?
* 1.优先使用内存 * 2.内存放不下 MEMORY_ONLY_SER * 3.尽量避免使用disk(迪斯科)
-
Spark持久化和容错的应用场景?
-
应用场景:一般对于做了大量迭代计算的重要阶段做checkpoint,使这个点的rdd成为顶层父rdd,恢复时只需要恢复该rdd,不用重新计算
比如迭代1000次,第998从失败了,正好再997次checkpoint了,此时恢复会很快。
-
-
spark的序列化?
-
java kryo
-
-
什么是累加器?
-
Accumulator是spark提供的累加器,顾名思义,该变量只能够增加。只有driver能获取到Accumulator的值,而Executor的Task只能对其做增加操作。你也可以为Accumulator命名(不支持Python),这样就会在spark web ui中显示,可以帮助你了解程序运行的情况。
-
作用:累加器用来把Executor端变量信息聚合到Driver端。在Driver程序中定义的变量,在Executor端的每个Task都会得到这个变量的一份新的副本,每个task更新这些副本的值后,传回Driver端进行merge。
-
-
什么是广播变量?
-
将Executor端使用到的Driver端的变量生成一个副本,放到Executor端的BlockManager。有几个Executor使用到对用的变量,就有几个副本无论该Executor中有多少个使用该变量的task,只需要有一个变量副本集合。因为是多个task共享,因此广播出来的变量副本不能被修改
-
-
节点和task 执行的关系?
-
每个节点可以起一个或多个Executor。
-
每个Executor由若干core组成,每个Executor的每个core一次只能执行一个Task。
-
每个Task执行的结果就是生成了目标RDD的一个partiton。
-
注意: 这里的core是虚拟的core而不是机器的物理CPU核,可以理解为就是Executor的一个工作线程。而 Task被执行的并发度 = Executor数目 * 每个Executor核数。
-
-
diver 失败了如何恢复?
-
supervise 在集群模式下,driver失败了就自动重启
-
对driver的元数据做CK
-
-
cluster 模式如何查看日志?
-
yarn模式下调试运行中的spark作业
-
在yarn模式下,spark作业运行相关的executor和ApplicationMaster都是运行在yarn的container中的
-
一个作业运行完了以后,yarn有两种方式来处理spark作业打印出的日志
-
第一种是聚合日志方式(推荐,比较常用)
-
第二种 web ui(如果你有精力的话,可以去配一下)
-
第三种 分散查看(通常不推荐)
-
-
Spark 的优化
-
避免创建重复的RDD;
-
尽可能使用同一个RDD
-
对多次使用的RDD进行持久化
-
尽量避免使用shuffle类算子
-
使用map-side预聚合的shuffle操作
-
使用高性能的算子
-
广播大变量
-
使用Kryo优化序列化性能: java Kryo
-
优化数据结构:
对象,字符串,集合都比较占用内存 字符串代替对象 数组代替集合 使用原始类型(比如Int、Long)替代字符串
优化数据结构
-
资源调优
-
spark调优数据倾斜调优:map filter
-
-
excutor内存分配
-
内存会被分为几个部分: 第一块是让task执行我们自己编写的代码时使用,默认是占Executor总内存的20%; 第二块是让task通过shuffle过程拉取了上一个stage的task的输出后,进行聚合等操作时使用,默认也是占Executor总内存的20%; spark.shuffle.memoryFraction 用来调节executor中,进行数据shuffle所占用的内存大小默认是0.2
第三块是让RDD持久化时使用,默认占Executor总内存的60%。 spark.storage.memoryFraction 用来调节executor中,进行数据持久化所占用的内存大小,默认是0.6
-
-
Rdd partition的个数有什么来决定的?
-
默认的
-
指定的
-
从hdfs读取数据,由块的个数
-
从kafka读取数据,由topic的partition个数决定
-
-
总结spark Shuffle?·作业的性能主要就是消耗在了shuffle环节,因为该环节包含了大量的磁盘IO、序列化、网络数据传输等操作。 因此,如果要让作业的性能更上一层楼,就有必要对shuffle过程进行调优。 但是也必须提醒大家的是,影响一个作业性能的因素,主要还是代码开发、资源参数以及数据倾斜,shuffle调优只能在整个的性能调优中占到一小部分而已。 因此大家务必把握住调优的基本原则,千万不要舍本逐末。
-
**什么是DStream?
一连串不间断的batch,一个batch就是一个时间段的Rdd
-
**sparkStreaming和Storm对比?
Spark Streaming与Storm的优劣分析
事实上,Spark Streaming绝对谈不上比Storm优秀。这两个框架在实时计算领域中,都很优秀,只是擅长的细分场景并不相同。
Spark Streaming仅仅在吞吐量上比Storm要优秀,而吞吐量这一点,也是历来挺Spark Streaming,贬Storm的人着重强调的。但是问题是,是不是在所有的实时计算场景下,都那么注重吞吐量?不尽然。因此,通过吞吐量说Spark Streaming强于Storm,不靠谱。
事实上,Storm在实时延迟度上,比Spark Streaming就好多了,前者是纯实时,后者是准实时。而且,Storm的事务机制、健壮性 容错性、动态调整并行度等特性,都要比Spark Streaming更加优秀。 SparkStreaming,有一点是Storm绝对比不上的,就是:它位于Spark生态技术栈中,因此SparkStreaming可以和SparkCore、SparkSQL无缝整合,也就意味着,我们可以对实时处理出来的中间数据,立即在程序中无缝进行延迟批处理、交互式查询等操作。这个特点大大增强了Spark Streaming的优势和功能。
-
**sparkStreaming的算子类型? transformation output
-
**sparkStreaming 的receiver ?
会启动一个线程单独拉取数据
-
**SparkStreaming从kafka获取数据的两种方式?
1.一是Receiver-based Approach。该种读取模式官方最先支持,并在Spark 1.2提供了数据零丢失(zero-data loss)的支持; 2.一是Direct Approach (No Receivers)。该种读取方式在Spark 1.3引入。
-
**SparkSQL的核心抽象?
Spark SQL 是 Spark 用来处理结构化数据的一个模块,它提供了 2 个编程抽象:DataFrame 和 DataSet,并且作为分布式 SQL 查询引擎的作用。
-
**什么是SparkFrame
-
1.与 RDD 类似,DataFrame 也是一个分布式数据容器。然而 DataFrame 更像传统数据库的二维表格,除了数据以外,还记录数据的结构信息,即 schema。
-
2.从 API 易用性的角度上看,DataFrame API 提供的是一套高层的关系操作,比函数式的 RDD API 要更加友好,门槛更低。
-
-
*Rdd创建DataFrame的方式?
-
反射样例类
-
隐式转换
-
元数据
-
-
**spark创建DataFrame的方式?
-
通过spark的数据源进行创建
-
从一个存在的RDD进行转换
-
还可以从HIve Table进行查询返回
-