spark初级篇之面试基础(下)
- 什么是二次排序?
根据某一刻数据进行排序,当数据相同时根据另外的列数据进行排序8
排序分为两种:
- 分组排序求topN,
- 全局排序
- spark master 资源分配的方式?
- 尽量集中:尽量在某一台或某几台机器上启动
- 尽量打散:尽量让需要的资源平均的在不同的机器上启动
- master的作用?
Master HA 的四大方式:分別是 ZOOKEEPER,FILESYSTEM, CUSTOM, NONE;
需要说明的是:
ZOOKEEPER 是自動管理 Master;
FILESYSTEM 的方式在 Master 出现突障后需要手动启动机器,机器启动后会立即成为 Active 级别的 Master
来对外提供服务(接受应用程序提交的请求、接受新的 Job 运行的请求)
CUSTOM 的方式允许用户自定义 Master HA 的实现,这对于高级用户特别有用;
NONE,这是默应情况,当我们下载安装了 Spark 集群中就是采用这种方式,该方式不会持久化集群的数据, Driver,
Application, Worker and Executor. Master 启动起立即管理集群;
- 如何划分job?
在spark程序里面有多少个action就会产生多少个job - DAG如何划分为stage?
从最后一个RDD往前看,每遇到一个shuffle就划分一个stage - 线程的生命周期?线程池有什么优势?
- 线程的生命周期(5种状态):新建、就绪、运行、阻塞(等待阻塞、同步阻塞、其他阻塞)、死亡。
- 线程池优势:
- spark序列化? java kryo
Java序列化
在默认情况下,Spark采用Java的ObjectOutputStream序列化一个对象。该方式适用于所有实现了java.io.Serializable的类。通过继承java.io.Externalizable,你能进一步控制序列化的性能。Java序列化非常灵活,但是速度较慢,在某些情况下序列化的结果也比较大。
Kryo序列化
Spark也能使用Kryo(版本2)序列化对象。Kryo不但速度极快,而且产生的结果更为紧凑(通常能提高10倍)。Kryo的缺点是不支持所有类型,为了更好的性能,你需要提前注册程序中所使用的类(class)。
- spark task 分为两种?
shuffleMapTask和resultTask
最后一个stage对应的task是resultTask,之前所有的stage对应的task都是shuffleMapTask,吐过spark程序执行的是shuffleMapTask,那么在程序执行完这个stage之后,还要继续执行下一个stage - spark 提交方式?
- client 客户端模式
- cluster集群模式
- 什么是共享变量?
共享变量分为:广播变量和累加器 - spark优化?要总结10条以上
- 开发优化
- 避免创建重复的rdd
- 尽可能使用同一个rdd
- 对多次使用的rdd进行持久化
- 尽量避免使用shuffle类算子
- 使用map-side预聚合的shuffle操作
- 使用高性能的算子
- 广播大变量
- 使用kryo优化序列化性能
- 优化数据结构
- 资源优化
- Hadoop mr hive hbase 优化
- mapreduce优化
- 任务调度
- 数据预处理与inputSplit的大小
- map和reduce认为的数量
- combine函数
- 压缩
- 自定义comparator
- hive优化
- join优化
- group by 优化
- 合并小文件
- hive实现(not)in
- 排序优化
- 使用分区
- Distinct使用
- hql使用自定义的mapred脚本
- HDTF
- 聚合函数count和sum
- hbase优化
- 修改Linux最大文件数
- 修改JVM配置
- 修改hbase配置
- 什么是数据倾斜
数据倾斜就是我们在计算数据的时候,数据的分散度不够,导致大量的数据集中到了一台或几台机器上计算,这些数据的计算速度远远低于平均计算速度,导致整个计算过程过慢。
- 解决:
- 增大分区
- 加随机前缀
- 过滤掉key
- spark配置文件优先级?
代码 submit 配置文件 - spark submit参数有哪些?
–master MASTER_URL 选择运行模式,spark://host:port,
–class CLASS_NAME 程序主类名
–name NAME 应用名
–jars JARS driver和executor都需要的包,多个包之间用逗号(,)分割
–properties-file FILE 读取的环境变量文件位置,默认读取的位置为conf/spark-defaults.conf
–driver-memory MEM driver使用的内存(e.g. 1000M, 2G)(Default: 512M)
–driver-class-path driver所依赖的包,多个包之间用冒号(:)分割
–executor-memory MEM 每个executor使用的内存 (e.g. 1000M, 2G)(Default: 1G).Spark standalone with cluster deploy mode only:
–driver-cores NUM diver使用的核心数(Default:1)
–supervise 重启失败的driver
–kill SUBMISSION_ID 删掉指定的driver
–status SUBMISSION_ID 返回指定的driver状态
–total-executor-cores NUM 所有executors使用的核心总数YARN-only:
–driver-cores NUM diver使用的 核心数(只用于cluster),8(Default: 1)
–executor-cores NUM 每个executor使用的核心数 (Default: 1).
–queue QUEUE_NAME 提交到yarn上的队列名 (Default: “default”).
–num-executors NUM 启动的executor的数量 (Default: 2). - spark资源调度方式?
- standalone
- yarn
- mesos
- master资源分配?
- 尽量集中
- 尽量打散
- spark日志查看?
- 日志聚合
- web
- 各个节点
- 三种spark shuffle 流程?主要优化?画图
- 实时计算框架有哪些?
sparkStreaming storm fink blink
- sparkstreaming和storm的区别?
- storm实时性好,容错机制好,事务性好,有一个ack机制,非常的完善机制。但是storm吞吐量一般,是一个单独计算框架,无法和其他计算框架整合。
- sparkstreaming吞吐量非常好,最关键的是可以和spark离线批处理(rdd),spark的交互式查询语句(离线处理)进行无缝的整合。处理一些非常复杂的业务时候有一定的优势,上手难度低,只要会写rdd,那么很快就会写sparkstreaming,开发成本低,但实时性没有storm好,容错处理起来也非常麻烦。
- storm是来一条数据处理一条数据,没有就不做处理,sparkstreaming是每隔多长时间计算一个spark的任务,也叫做长时间处理。
- sparkstreaming的核心?
Dstream:sparkstreaming的数据抽象,代表一个持续不断的数据流。 - 什么是Dstream?
其实Dstream 就是spark 对rdd进行的一个封装,底层走到流程还是我们之前讲的RDD的那一套。
转换 | 描述 |
print() | 在Driver中打印出DStream中数据的前10个元素。 |
saveAsTextFiles(prefix, [suffix]) | 将DStream中的内容以文本的形式保存为文本文件,其中每次批处理间隔内产生的文件以prefix-TIME_IN_MS[.suffix]的方式命名。 |
saveAsObjectFiles(prefix, [suffix]) | 将DStream中的内容按对象序列化并且以SequenceFile的格式保存。其中每次批处理间隔内产生的文件以prefix-TIME_IN_MS[.suffix]的方式命名。 |
saveAsHadoopFiles(prefix, [suffix]) | 将DStream中的内容以文本的形式保存为Hadoop文件,其中每次批处理间隔内产生的文件以prefix-TIME_IN_MS[.suffix]的方式命名。 |
foreachRDD(func) | 最基本的输出操作,将func函数应用于DStream中的RDD上,这个操作会输出数据到外部系统,比如保存RDD到文件或者网络数据库等。需要注意的是func函数是在运行该streaming应用的Driver进程里执行的。 |
- sparkstreaming的receiver
每一个inputDStream,关联一个Receiver对象,启动时占用一个线程,此时不能用setMaster不能用local[1] - sparkstreaming的数据源?
无论是storm 还是sparkStreaming ,他们对接的数据源主要都是kafka - sparkstreaming算子?
转换 | 描述 |
map(func) | 源 DStream的每个元素通过函数func返回一个新的DStream。 |
flatMap(func) | 类似与map操作,不同的是每个输入元素可以被映射出0或者更多的输出元素。 |
filter(func) | 在源DSTREAM上选择Func函数返回仅为true的元素,最终返回一个新的DSTREAM 。 |
repartition(numPartitions) | 通过输入的参数numPartitions的值来改变DStream的分区大小。 |
union(otherStream) | 返回一个包含源DStream与其他 DStream的元素合并后的新DSTREAM。 |
count() | 对源DStream内部的所含有的RDD的元素数量进行计数,返回一个内部的RDD只包含一个元素的DStreaam。 |
reduce(func) | 使用函数func(有两个参数并返回一个结果)将源DStream中每个RDD的元素进行聚 合操作,返回一个内部所包含的RDD只有一个元素的新DStream。 |
countByValue() | 计算DStream中每个RDD内的元素出现的频次并返回新的DStream[(K,Long)],其中K是RDD中元素的类型,Long是元素出现的频次。 |
reduceByKey(func, [numTasks]) | 当一个类型为(K,V)键值对的DStream被调用的时候,返回类型为类型为(K,V)键值对的新 DStream,其中每个键的值V都是使用聚合函数func汇总。注意:默认情况下,使用Spark的默认并行度提交任务(本地模式下并行度为2,集群模式下位8),可以通过配置numTasks设置不同的并行任务数。 |
join(otherStream, [numTasks]) | 当被调用类型分别为(K,V)和(K,W)键值对的2个DStream 时,返回类型为(K,(V,W))键值对的一个新 DSTREAM。 |
cogroup(otherStream, [numTasks]) | 当被调用的两个DStream分别含有(K, V) 和(K, W)键值对时,返回一个(K, Seq[V], Seq[W])类型的新的DStream。 |
transform(func) | 通过对源DStream的每RDD应用RDD-to-RDD函数返回一个新的DStream,这可以用来在DStream做任意RDD操作。 |
updateStateByKey(func) | 返回一个新状态的DStream,其中每个键的状态是根据键的前一个状态和键的新值应用给定函数func后的更新。这个方法可以被用来维持每个键的任何状态数据。 |
转换 | 描述 |
window(windowLength, slideInterval) | 返回一个基于源DStream的窗口批次计算后得到新的DStream。 |
countByWindow(windowLength,slideInterval) | 返回基于滑动窗口的DStream中的元素的数量。 |
reduceByWindow(func, windowLength,slideInterval) | 基于滑动窗口对源DStream中的元素进行聚合操作,得到一个新的DStream。 |
reduceByKeyAndWindow(func,windowLength,slideInterval, [numTasks]) | 基于滑动窗口对(K,V)键值对类型的DStream中的值按K使用聚合函数func进行聚合操作,得到一个新的DStream。 |
reduceByKeyAndWindow(func, invFunc,windowLength,slideInterval, [numTasks]) | 一个更高效的reduceByKkeyAndWindow()的实现版本,先对滑动窗口中新的时间间隔内数据增量聚合并移去最早的与新增数据量的时间间隔内的数据统计量。例如,计算t+4秒这个时刻过去5秒窗口的WordCount,那么我们可以将t+3时刻过去5秒的统计量加上[t+3,t+4]的统计量,在减去[t-2,t-1]的统计量,这种方法可以复用中间三秒的统计量,提高统计的效率。 |
countByValueAndWindow(windowLength,slideInterval, [numTasks]) | 基于滑动窗口计算源DStream中每个RDD内每个元素出现的频次并返回DStream[(K,Long)],其中K是RDD中元素的类型,Long是元素频次。与countByValue一样,reduce任务的数量可以通过一个可选参数进行配置。 |
- storm的组件?
storm数据来一条,处理一条
- Spouts🛰数据源
- Bolts🔃处理数据的逻辑
- Tuple🗃封装一条条数据的tuple
- ck可以保存那些数据?
1.元数据
元数据包括哪些呢???
配置信息,sparkconf
Dstream的操作信息
没有处理的batch的信息
元数据需要进行checkPoint,其实主要讲的是driver失败了,该如何恢复
2.运行时的计算数据
实时计算过程中的数据
这些数据都需要我们备份到稳定,可靠的文件系统:hdfs - driver失败了,该如何恢复?
- ck 元数据
- –supervise
- Sparkstreaming 从kafka 获取数据的方式?
receiver
direct - 基于receiver方式怎么保证数据不丢失?
启动一个叫write ahead log–>WAL机制才能保证数据不丢,但是启动这种机制之后,也有不足的地方。
第一,只能数据不丢,但是不能保证数据有没有被重复的消费。
第二,开启wal机制之后,性能会比较低下,影响网络读写速度。 - 基于direct方式,我们如何管理偏移量? zk ck
sparkstreaming程序会自己管理偏移量
这个偏移量,我们可以让程序帮你管,我们也可以拿到这个偏移量之后,自己写zookeeper的api,把这个偏移量写入ZK,通过偏移量消费
利用ck容错机制,将偏移量保存 - 如何部署应用程序?
启用预写日志机制
设置Receiver接收速度 - 应用程序如何升级?
1、升级后的Spark应用程序直接启动,先与旧的Spark应用程序并行执行。当确保新的应用程序启动没问题之后,就可以将旧的应用程序给停掉。但是要注 意的是,这种方式只适用于,能够允许多个客户端读取各自独立的数据,也就是读取相同的数据。
2、小心地关闭已经在运行的应用程序,使用StreamingContext的stop()方法,可以确保接收到的数据都处理完之后,才停止。然后将升级后的程序部署上去,启动。这样,就可以确保中间没有数据丢失和未处理。因为新的应用程序会从老的应用程序未消费到的地方,继续消费。但是注意,这种方式必须是支持数据缓存的数据源才可以,比如Kafka、Flume等。如果数据源不支持数据缓存,那么会导致数据丢失。
注意:配置了driver自动恢复机制时,如果想要根据旧的应用程序的checkpoint信息,启动新的应用程序,是不可行的。需要让新的应用程序针对新的checkpoint目录启动,或者删除之前的checkpoint目录。
小结: 1 掌握好时机(数据特别少),可以stop的,这个时候,关键是数据没有丢失,数据是不是在kafka里面还得有,因为kafka可以默认情况保存7天的数据,但 是实际项目中远远不止7天。
2.我同时启动另外一个升级好的sparkstreaming程序,你的两份数据是一样的,而且有可能出现一些重复的数据,这个时候,还得去重。
- 怎么查看日志?
一、web端日志的查看
二、服务器端日志查看 - 容错的语义?
1、最多一次:每条记录可能会被处理一次,或者根本就不会被处理。可能有数据丢失。
2、至少一次:每条记录会被处理一次或多次,这种语义比最多一次要更强,因为它确保零数据丢失。但是可能会导致记录被重复处理几次。
3、一次且仅一次:每条记录只会被处理一次——没有数据会丢失,并且没有数据会处理多次。这是最强的一种容错语义。 - Hive 和 sparkSQL的区别??
-两者都是以sql的方式做交互式的查询,处理的都是结构化数据
区别:
Hive本质的数据是落在hdfs上,hive更多的是做数据仓库,用来做数据分析的
SparkSQL 底层是RDD,无法让数据落地
SparkSQL 速度秒杀hive - sparkSQL 核心抽象?
dataframe
DataFrame是一种以RDD为基础的分布式数据集,类似于传统数据库中的二维表格。DataFrame与RDD的主要区别在于,DataFrame带有schema元信息,即DataFrame所表示的二维表数据集的每一列都带有名称和类型。 - spark 1.0 和2.0 的区别?
Spark1和Spark2区别
- Spark2 Apache Spark作为编译器:增加新的引擎Tungsten执行引擎,比Spark1快10倍
- ml做了很大的改进,支持协同过滤
http://spark.apache.org/docs/latest/ml-collaborative-filtering.html - spark2 org.apache.spark.sql加了SparkSession把Spark的SQLcontext和hiveContext整合dataFrame去掉了,统一采用dataset
- 做流的方式,例如设置10秒钟一批,5秒钟处理
- R语言API加入了很多机器学习的算法
Spark2.0新特性
1)Spark Core/SQL
在内存和CPU使用方面进一步优化Spark引擎性能,支持SQL 2003标准,支持子查询,对常用的SQL操作和DataFrame,性能有2-10倍的提升
2)sparksession
Spark2.0 中引入了 SparkSession 的概念,它为用户提供了一个统一的切入点来使用 Spark 的各项功能,统一了旧的SQLContext与HiveContext。用户不但可以使用 DataFrame 和Dataset 的各种 API,学习 Spark2 的难度也会大大降低。
3)统一 DataFrames 和 Datasets 的 API
它们都是提供给用户使用,包括各类操作接口的 API,1.3 版本引入 DataFrame,1.6版本引入Dataset,在 spark 2.0 中,把 dataframes 当作是一种特殊的 datasets,dataframes = datasets[row],把两者统一为datasets。
4) strutured Streaming
Spark Streaming基于Spark SQL(DataFrame / Dataset )构建了high-level API,使得Spark Streaming充分受益Spark SQL的易用性和性能提升。
5) 其它特性
mllib里的计算用 DataFrame-based aPI替代以前的RD计算裸机,提供更多的R语言算法,默认使用Scala 2.11编译与运行
- DataFrame与RDD的主要区别?
Rdd的本质是一个分布式的集合,这个集合里面放置的是同一个类型的数据
DataFrame 本质是一个分布式的二维表,表:表信息 - dataframe和dataset区别?
Dataset可以认为是DataFrame的一个特例,主要区别是Dataset每一个record存储的是一个强类型值而不是一个Row。因此具有如下三个特点:
1.DataSet可以在编译时检查类型
2.并且是面向对象的编程接口
3.后面版本DataFrame会继承DataSet,DataFrame是面向Spark SQL的接口。
DataFrame和DataSet可以相互转化,df.as[ElementType]这样可以把DataFrame转化为DataSet,ds.toDF()这样可以把DataSet转化为DataFrame。