学习素材
https://blog.csdn.net/rlnLo2pNEfx9c/article/details/78738084
http://dblab.xmu.edu.cn/blog/1264/ 厦门大学数据库实验室
杂碎问题
元素:一行为一个元素
例:flatMap(x => (x to 5)) 元素行拆分,可用于切分单词
reduce() 两两操作 同构
fold() 同reduce 但是有初始值
aggregate() :
它先聚合每一个分区里的元素,然后将所有结果返回回来,再用一个给定的conbine方法以及给定的初始值zero value进行聚合。
def aggregate [U: ClassTag] (zeroValue: U) (seqOp: (U,T)=>U,combOp: (U,U)=>U):U
分区如何计算?
惰性求值:
rdd的转化操作都是惰性求值的。调用行动操作前不会开始计算。
持久化:
持久化有内存,硬盘。
键值对操作:
归约
组合
操作模式:原始rdd-》二元组rdd
逐行扫描:key不变,对值进行计算。可以进行单行操作,也可以两两相加,或者分组。
例: flatMapValues(x => (x to 5)) 符号化?
两个rdd
(求键值rdd中键的平均值)
操作模式:键值rdd -> 值转换(扩展成二元组)-> reduce (值相加,值扩展相加)- >
2018-07-13:
基本概念:
交互式查询:
http://www.voidcn.com/article/p-tglsuazy-kc.html
内存计算:相比hadoop的批处理,spark更多的把数据放到内存中。Spark可看 做基于内存的Map-Reduce实现
流式计算的典型范式之一是不确定数据速率的事件流流入系统
https://blog.csdn.net/jiyiqinlovexx/article/details/27403761
迭代式计算:
https://www.cnblogs.com/wei-li/p/Spark.html
7月15日
spark streaming 即时处理
离散化流,时间区间的概念,
离散化流 DStream 支持转换保存
连续批次,时间片。
2019年2月2日:
计划:
教程,原理,实践。
2020-04-25:
spark 缓存存到哪儿了?
数据不均衡问题怎么引起的?
yarn调度原理流程以及注意?
spark内存模型?
rdd内的元素类型必须一样吗?
driver端程序,与excutor端程序区别?
教程
一、spark的计算和存储:
hadoop的存储,spark自己的计算处理。
二、spark特性
80个高层次的操作符互助查询。
除了map reduce,还支持sql,流数据,机器学习,图形算法
三、数据集抽象RDD(弹性分布式数据集)
RDD两种创建方式:内部已有的RDD,或者外部文件系统(HDFS,HBase,Hadoop的输入格式)
MapReduce之间共享数据只能外部共享,共享效率比较慢!
map的中间结果会放到hdfs上。
关注 spark技术分享,撸spark源码 玩spark最佳实践
实践:
一、安装
spark 安装包 以及可以扩展的组件?:
最小安装:
YARN需要安装:
hdfs如何挂接:
二、教程中的例子
1、内部,外部读取数据的例子
2、多个map串联
3、如何找到缓存的RDD数据集
mapReduce局限性:
一、局限
1.仅支持Map和Reduce两种操作;
2.处理效率低效;不适合迭代计算(如机器学习、图计算等),交互式处理(数据挖掘)和流失处理(日志分析)
3.Map中间结果需要写磁盘,Reduce写HDFS,多个MR之间通过HDFS交换数据;
4.任务调度和启动开销大;
5.无法充分利用内存;(与MR产生时代有关,MR出现时内存价格比较高,采用磁盘存储代价小)
6.Map端和Reduce端均需要排序;
2.MapReduce编程不够灵活。(比较Scala函数式编程而言)
3.框架多样化[采用一种框架技术(Spark)同时实现批处理、流式计算、交互式计算]:
1.批处理:MapReduce、Hive、Pig;
2.流式计算:Storm
3.交互式计算:Impala
Spark核心概(未看)
https://www.cnblogs.com/cnmenglang/p/6736250.html
BlockManager
嵌入在 spark 中的 key-value型分布式存储系统
Block :
是Spark storage模块中最小的单位。
会存储到Memory 、Disk。
Block是Partition的基础。
RDD是由不同的partition组成的,也是由不同的block组成的。
Block Interal:
默认是200ms,推荐最小50ms。
Receiver接收,切分成Block,一个周期batch会有Block数量=> RDD的分区Partition数量和Task数量
Task数量 = batch周期间隔 / block间隔 ,然后再与Spark Core数量进行比较
SparkSession
https://segmentfault.com/a/1190000009554236
Application、SparkSession、SparkContext之间具有包含关系,并且是1对1的关系。
SparkSession 是 Spark 2.0 版本引入的新入口。
RDD
1.分布在集群中的只读对象集合(由多个Partition 构成);
2.可以存储在磁盘或内存中(多种存储级别);
3.通过并行“转换”操作构造; transformations(map filter)
4.失效后自动重构;
5.RDD基本操作(operator)
2、Transformation具体内容
......
3、actions具体内容
........
4、算子分类
transformations 算子
- Value数据类型的Transformation算子,这种变换并不触发提交作业,针对处理的数据项是Value型的数据。
- Key-Value数据类型的Transfromation算子,这种变换并不触发提交作业,针对处理的数据项是Key-Value型的数据对。
action算子
- Action算子,这类算子会触发SparkContext提交Job作业。
接口定义方式不同:
Transformation: RDD[X]-->RDD[y]
Action:RDD[x]-->Z (Z不是一个RDD,可能是一个基本类型,数组等)
惰性执行:
Transformation:只会记录RDD转化关系,并不会触发计算
Action:是触发程序执行(分布式)的算子。
Transformation和Action区别:
http://www.cnblogs.com/beiyi888/p/9802249.html
Transformation:代表的是转化操作就是我们的计算流程,返回是RDD[T],可以是一个链式的转化,并且是延迟触发的。
Action:代表是一个具体的行为,返回的值非RDD类型,可以一个object,或者是一个数值,也可以为Unit代表无返回值,并且action会立即触发job的执行。
spark分区:
https://www.cnblogs.com/qingyunzong/p/8987065.html
分区:
相同的key的数据存储到了相同的节点,减少了网络传输问题。
分区只对键值对的数据计算才有帮助。
如何设置分区:
分区多意味着任务多
分区少可能会导致节点没有平均分配到数据,利用不充分
分区少还可能导致处理的数据多,节点内存不够用
合理的分区数:
一般合理的分区数设置为总核数的2~3倍
总核数=一个executor的cores * executor个数
spark分区作用
减少了通信开销
分区个数:尽量等于集群中的CPU核心数量:假设CPU核心与分区数据一对一执行
本地模式:可以
输入,输出都有分区吗?
hdfs part 文件跟分区有关系?
job,stage与shuffe:
https://zhuanlan.zhihu.com/p/50752866
job定义:程序中遇到一个action算子的时候,就会提交一个job
spark stage 定义:一个job通常包含一个或多个stage。job需要在分区之间进行数据交互,那么一个新的stage将会产生。
shuffe定义:分区之间的数据交互其实就是shuffle, 下一个stage的执行首先要去拉取上一个stage的数据(shuffle read操作),保存在自己的节点上,就会增加网络通信和IO。
spark与有向无环图:
narrow dependency(窄依赖) 与 wide dependency( 宽依赖)
如果一个父RDD的数据只进入到一个子RDD,比如map、union等操作,称之为narrow dependency(窄依赖)。否则,就会形成wide dependency( 宽依赖),一般也成为shuffle依赖,比如groupByKey等操作。
spark从原始文件到生成最终partion文件【名词】:
https://www.zhihu.com/question/33270495
file->block 原始文件拆分成块:
一对多 (inputformat?)
block->inputSplit 块合并成一个输入分片:
多对一
inputSplit不能跨文件?
inputSplit->task:
一一对应
集群->节点
一对多
节点->executor:
一对多
core 是虚拟的core,不是物理机器的cpu core,此处的core可以理解为executor的一个工作线 程。
executor可以使用多个core。
executor->task
一对多
一个由多个task组成
task并发 = executor数据 * 每个executor核数
task->partition
一对一
一个任务生成一个partition
目标RDD->partition
由多个partition组成
spark driver 与 executor 区别:
https://blog.csdn.net/lp284558195/article/details/80931818
sprak的DAG调度程序,把用户的应用程序先拆分成大的stage,再分成小的task。
driver:
用户程序转为任务,把逻辑图转为物理执行计划。
跟踪excutor运行状态,
调度任务task给executor,
UI展示任务执行情况。
executor是工作进程:
负责运行任务,
返回结果给driver
一个executor可以运行多个task
一个executor可以同时运行最多 核心数个任务
rdd持久化(缓存)的意义:
https://blog.csdn.net/dkl12/article/details/80742498
1、意义:加快速度,数据共享?
当持久化一个 RDD 时,每个节点的其它分区都可以使用 RDD 在内存中进行计算,在该数据上的其他 action 操作将直接使用内存中的数据。这样会让以后的 action 操作计算速度加快(通常运行速度会加速 10 倍)。
缓存迭代算法和快速的交互式使用的重要工具
2、存储级别
默认的策略:
如果内存空间不够,部分数据分区将不再缓存,在每次需要用到这些数据时重新进行计算
3、cahce方法 与 persit方法
cache()调用的persist(),是使用默认存储级别的快捷设置方法
RDD缓存策略
http://www.cnblogs.com/luogankun/p/3801047.html
序列化好处缺点:
序列化后的对象存放在内存中,占用的内存少,但是用时需要反序列化,会消耗CPU;
默认的方式(原生存储,cpu效率高,读取快):
spark默认存储策略为MEMORY_ONLY:只缓存到内存并且以原生方式存(反序列化)一个副本;
RDD
http://www.cnblogs.com/BYRans/p/5003029.html
rdd使用举例:举例创建,操作,
DataFrame :
dataFrame是从Rdd扩展:
可以生成rdd;
提供对类sql的支持:
筛选,合并,重新入库;
可以理解关系数据库的一张表;
对java api支持相比sacala 有限。
DataSet
并行度,核心数,任务数,分区数
https://blog.csdn.net/u012965373/article/details/80847543
计算节点数和每个计算节点核数,决定了最大任务数
提高并行度的方法(调优的方法)就是提高资源利用效率:在最少的时间内把任务运行完成。
一个executor的核心数决定了最大同时运行的任务数
一个分区的结果由一个任务生成
shuffe与效率
故障恢复
excutor故障恢复
如何处理的,很好的
driver故障恢复
todo
SPARK 管理
集群管理
Spark yarn 管理方式:
问题一:如何与yarn集成在一起?
spark-1.6.1-bin-hadoop2.6:
进程:
Master 与 Worker(Slave)
在yarn上启动sprak 应用程序的两种部署模式?
客户端模式:
driver运行在客户端进程中
集群模式:
dirver运行在 yarn applicationmaster中,与客户端进程是分离的
在yarn上的提交任务?
./bin/spark-submit --class org.apache.spark.examples.SparkPi \ --master yarn \ --deploy-mode cluster \ --driver-memory 4g \ --executor-memory 2g \ --executor-cores 1 \ --queue thequeue \ examples/jars/spark-examples*.jar \ 10
Spark mesos 管理方式:
问题一:如何安装mesos?
Cluster Manager:
standalong 模式:
Spark manager
mesos 模式:
mesos manager
用户权限
?
使用场景
流式处理的场景:
实时大数据分析、风控预警、实时预测、金融交易等诸多业务场景领域。
时延要求低的场景;
批量(或者说离线)处理对于以上业务需求不能胜任;
数据量大;
过去开发的统计数据计算,也算成一个简单的流失计算!
流式处理框架特点:
无界的数据集;
进行连续不断的处理,聚合,分析的过程;
延迟需要尽可能的低,时效性高,数据具有时效性;
实时计算与批量计算:
https://help.aliyun.com/knowledge_detail/62440.html
spark与storm对比:
http://www.cnblogs.com/yaohaitao/p/5703288.html
性能健壮性不及storm,但是吞吐量比storm高。
spark是一个生态,和Spark Core、Spark SQL无缝整合。
spark中间数据可以直接批处理、交互式查询;
Hive、Spark SQL、Impala比较:
https://www.cnblogs.com/jins-note/p/9513448.html
好像没有明显区别。
spark streaming + flume:
http://lxw1234.com/archives/2015/05/217.htm
组件:
flume-ng-core
spark-streaming-flume
spark架构:
https://spark.apache.org/docs/2.2.0/cluster-overview.html
spark配置:
https://spark.apache.org/docs/2.2.1/configuration.html
应用程序配置:
三种来源:
命令行
SparkConf
spark-defaults.conf
如何查看:
通过web ui 查看,4040端口,“Environment” tab。
spark 监控:
https://spark.apache.org/docs/2.2.1/monitoring.html
spark streaming
参考
https://www.w3cschool.cn/spark/y27pgozt.html
概念
基于spark rdd数据结构。
增加一个时间的概念,定时多久去数据源取一次数据,创建一个RDD。
创建与关闭:
创建:
//SparkContext创建
import org.apache.spark.streaming._
val ssc = new StreamingContext(sc, Seconds(1))
注意:
jvm中同一时间只有一个StreamingContext处于活跃状态
关闭前一个StreamingContext才能创建下一个StreamingContext。
调优:
1、数据接收并行度调优
创建多个DStream和Receive
合理设置 Batch Interval 和 Block Interval
2、数据处理并行度调优
task任务序列化 ?
启动合理个数的task,reduce有些计算可以指定并行度
3、数据序列化调优
数据格式优化,减少数据序列化开销。
使用Kyro序列化类库,该类库效率高。
根据数据量选择合适的序列话级别:小量数据可以不序列化。
4、batch interval 周期优化
UI上的batch处理时间与周期进行比较。处理时间长考虑缩短处理时间或者增加周期时长。
时间相当最好。数据充分利用处理能力
5、内存调优
stream尽量不需要放到硬盘上,毕竟stream的目的就是实时。
观测内存够用,不需要花费太长时间的GC,影响程序正常运行时间
离散流(DStreams):
来源:
从源中获取的输入流
输入流通过转换算子生成的处理后的数据流
特点:
连续
确定时间间隔
与RDD:
由一系列连续的rdd组成
与Receiver:
每一个输入流DStream和一个Receiver对象相关联
核占用问题:
receiver占用一个单独的核心。
数据源类型:
Spark Streaming拥有两类数据源:
基本源(Basic sources):
文件系统、套接字连接、Akka的actor等
高级源(Advanced sources):
Kafka,Flume,Kinesis,Twitter等
窗口计算:
参数:
窗口长度(windowDuration):窗口的持续时间
滑动的时间间隔(slideDuration):窗口操作执行的时间间隔。
注意:这两个参数必须是源DStream的批时间间隔的倍数
常见问题:
窗口比较大的情况如何处理?
输出操作:
foreachRDD:
创建连接:
在每一个rdd中创建 (序列化错误,连接对象在机器间不能传送)
dstream.foreachRDD(rdd => { 创建连接
在每一个元素中创建 (耗费资源)
dstream.foreachRDD(rdd => { rdd.foreach(record => { 创建连接
在每一个rdd分区中创建 right!
dstream.foreachRDD(rdd => { rdd.foreachPartition(partitionOfRecords => { 创建连接
转换:
UpdateStateByKey
Transform
有状态:
跨多个批,跨rdd的
Spark Streaming Checkpointing:
包括:
元数据,配置信息,操作集合,未完成的批,
何时必须开启checkpoint:
使用有状态的transformation。
比如:updateStateByKey,reduceByKeyAndWindow
从运行应用程序的driver的故障中恢复过来。
使用元数据恢复处理信息。
怎样配置checkpoint:
在容错可靠的文件系统中设置checkpoint目录:
getOrCreate创建StreamContext上下文。
应用程序的基础设置设置driver重启。
设置checkpoint间隔时间5-10秒。
Structured Streaming
参考:
http://vishnuviswanath.com/spark_structured_streaming.html Spark 结构化流之旅
https://ohmycloud.github.io/2018/11/27/a-tour-of-spark-structured-streaming/ A Tour of Spark Structured Streaming
https://www.infoq.cn/article/UEOq-ezu4ImwHxGiDFc8 是时候放弃 Spark Streaming,转向 Structured Streaming 了 (TO READ !)
https://github.com/lw-lin/CoolplaySpark/blob/master/Structured%20Streaming%20源码解析系列/4.2%20Structured%20Streaming%20之%20Watermark%20解析.md 解决了什么问题(TO EXPLORE)
原理
用户定义逻辑计划,交给spark进行计划的优化,执行。
偏移量追踪+状态管理
保证一次,不用使用者去维护sink去重逻辑。
几个Time
EventTime: 事件被产生的时间,
ProcessingTime:事件被系统处理的时间
IngestionTime:事件被放入系统的时间
Watermark水印
参考: https://towardsdatascience.com/watermarking-in-spark-structured-streaming-9e164f373e9
定义
withWatermark(eventTime: String, delayThreshold: String): Dataset[T]
第一个参数:消息时间列,必须跟聚合groupBy的列一样
第二个参数:阈值,有效消息的阈值单位可以是秒,以窗口的开始时间为基准
丢弃与更新
处理数据的时候,消息数据的范围是两次处理时间范围。
但是收到的消息的eventTime有可能是任何时候,或者更老。
所以处理的时候要从所有消息中通过eventTime进行筛选,是滚动筛选的,
在这批数据中找到最大的eventTime,eventTIme-业务定义的更晚的时间值=本次会处理消息最小的时间(水印)。
这批数据才是真的业务处理的数据。
如果一个事件落在水印内,更新;如果是更旧的数据,丢弃。
检查消息是否被保留: max eventTime — delayThreshold > T
T : 当前窗口开始的时刻。
delayThreshold : 用户设置的水印阈值
max eventTime: 系统处理所有事件的最大时刻.
一个窗口正在处理,如果有一个新事件进来,并且这个新事件的发生时间没有超过时间区间(窗口开始时间+水印阈值),则更新查询!
否则丢弃该事件。
举例:
接收了一个10:00:07秒产生的消息, 水印是5秒, 窗口开始10:00:00 ,超过10:00:05,所以该消息被丢弃
注意:
原来的聚合状态必须保存。(但是内存会变大)
窗口
窗口除了有时间特征外,还有分组,使用groupBy实现。
事件产生的时间戳用来标识属于哪个窗口。
翻转窗口Tumbling Window
不重叠,连续。
一个事件只属于一个窗口。
属于一种特殊的滑动窗口。
滑动窗口 Sliding Window
两个窗口会重叠。
一个事件可能会属于多个窗口。
举例:
收集过去4秒汽车的平均速度?
代码:
//a tumbling window of size 4 seconds
val aggregates = cars
.groupBy(window($"timestamp","4 seconds"), $"carId")
.agg(avg("speed").alias("speed"))
//a sliding window of size 4 seconds that slides every 2 seconds can be created using cars.groupBy(window($"timestamp","4 seconds","2 seconds"), $"carId")
代码输出:
Batch 1
[2018-01-21 00:50:00, 2018-01-21 00:50:04] car1 75.0
Batch 2
.....
SQLContext HiveContext
spark1.x时代的产物,演化到了spark2.0可能就没用了
机器学习库
Pipleline
作用:
构建复杂机器学习工作流应用。
是ML Lib的补充。
步骤:
1、定义stage
指标提取和转换模型训练等。
主要是Transformer 和 Estimator。
具体功能是:据集处理转化,模型训练,参数设置或数据预测
2、创建pipleline
组合器stage
3、得到piplelineModel
具体应用
参考:
https://www.ibm.com/developerworks/cn/opensource/os-cn-spark-practice5/
PipelineStage
子类是Transformer 和 Estimator
Transformer
主要是用来把 一个 DataFrame 转换成另一个 DataFrame
子类有Model类。
api:
http://spark.apache.org/docs/2.1.3/api/java/org/apache/spark/ml/Transformer.html
Estimator
评估器或适配器,主要是通过DataFrame训练得到一个Model(是Transformer的子类)。
子类有Predictor类。
api:
http://spark.apache.org/docs/2.1.3/api/java/org/apache/spark/ml/Estimator.html
RandomForestClassifier例子
类关系:
父类是Predictor,父类的父类是Estimator
内部方法:
方法fit,里面调用的是train训练数据的方法。
返回:
训练结束会返回一个RandomForestClassificationModel 模型。
预测:
返回的model可以用来Transformer预测。
特征处理
https://blog.csdn.net/xuejianbest/article/details/90769557
Spark提供的基础特征处理类之VectorAssembler和VectorIndexer
代码
rdd
foreachPartition VS foreach
https://my.oschina.net/dongtianxi/blog/745908
用foreachPartition替代foreach,有助于性能的提高
coalesce VS repartition
https://blog.csdn.net/Dax1n/article/details/53431373
写入mysql
https://bit1129.iteye.com/blog/2186405
最佳实践:
应该在worker打开链接,可以调用forEachPartition,在函数里打开链接
一个分区打开一个数据库链接,不要打开太多,减少链接数
尽量使用批量
写失败的情况,如何应对? 弹性
写大数据集注意网络超时
考虑使用数据库连接池(一个分区一个链接够了?就不需要连接池了吧)
链接共享数据库?
dataset
explode
https://blog.csdn.net/macanv/article/details/78297150
df = df.select(functions.explode(functions.col("data"))).toDF("key", "value");
dataFrame
explode
https://blog.csdn.net/strongyoung88/article/details/52227568
val dfScore = df.select(df("name"),explode(df("myScore"))).toDF("name","myScore")
ml
参考
https://www.cnblogs.com/code2one/p/9872241.html#collaborative-filtering-with-alternating-least-squares Spark之MLlib
als
https://spark.apache.org/docs/latest/ml-collaborative-filtering.html 官方文章
https://blog.csdn.net/u011239443/article/details/51752904 深入理解Spark ML:基于ALS矩阵分解的协同过滤算法与源码分析
评估
https://blog.csdn.net/u011707542/article/details/77838588 spark机器学习库评估指标总结
其它
内存溢出
spark 序列化
任务序列话
Core rdd 序列化
默认持久化级别是MEMORY_ONLY
stream rdd 序列话
默认级别: MEMORY_ONLY_SER,序列化占用空间更小,减少GC
多语言库以及版本
与hadoop的关系:
spark 使用了hadoop的存储 调度 管理的平台。
spark 唯一做的是替代hadoop的计算部分,也就是MapReduce部分。
spark与hadoop版本一致问题:
spark会跟着hadoop的版本走,hadoop是基础。
spark发布的时候会附带着hadoop一起打包发布。
pyspark库:
pyspark经过py4J通过nativeSocket的方式转换成jvm可一运行的指令。
pyspark往往跟着spark运行环境版本一起会发布一个配套的包。
scala库可以先不用安装spark:
有一种方法不用安装spark环境只需要引入一些库就可以写spark程序:
使用scala库。