架构师训练营第一期 - 第十三周学习总结
spark 是现阶段使用最广泛的大数据计算引擎,是 MR 的替代者,其性能远远超过 MR。Spark 将一个用户作业生成 DAG,DAG 切分的多阶段计算过程更快速,同时优先使用内存存储中间计算结果更高效;而 MR 则需要将作业切分为多个 map/reduce 任务,每次任务结束后,需要再启动另外一个 map/reduce 任务,同时其中间结果输出到 HDFS 磁盘文件,下个任务需要从 HDFS 再读取文件进行处理;另外,RDD 的编程模型也更简单。
RDD 是 Spark 的核心概念,是弹性分布式数据集(Resilient Distributed Datasets)的缩写。RDD 既是 Spark 面向开发者的编程模型,又是 Spark 自身架构的核心元素。spark 跟 RDD 是一个强对应的关系,理解 spark 围绕着 RDD 去理解,开发 spark 围绕着 RDD 去编程,spark 的内部代码中 RDD 也是无处不在。
大数据计算就是在大规模的数据集上进行一系列的数据计算处理。MapReduce 针对输入数据,将计算过程分为两个阶段,一个 Map 阶段,一个 Reduce 阶段,可以理解成是面向过程的大数据计算。在用
MapReduce 编程的时候,思考的是,如何将计算逻辑用 Map 和 Reduce 两个阶段实现,map 和 reduce 函数的输入和输出是什么,MapReduce 是面向过程的。而 Spark 则直接针对数据进行编程,将大规模数据集合抽象成一个 RDD 对象,然后在这个 RDD 上进行各种计算处理,得到一个新的 RDD,继续计算处理,直到得到最后的结果数据。所以 Spark 可以理解成是面向对象的大数据计算。我们在进行 Spark 编程的
时候,思考的是一个 RDD 对象需要经过什么样的操作,转换成另一个 RDD 对象,思考的重心和落脚点都在 RDD 上。
spark 在 RDD 上定义了很多函数,这些函数分两种,一种是转换(transformation)函数,这种函数的返回值还是 RDD;另一种是执行(action)函数,这种函数不再返回 RDD。Spark 任务只有在调用 action 算子的时候,才会真正执行。
RDD 既是一个编程模型也是一个操作层面的物理数据,是大数据的数据集。因此处理时跟 MapReduce 一样,Spark 也是对大数据进行分片计算,Spark 分布式计算的数据分片、任务调度都是以 RDD 为单位展开的,每个 RDD 分片都会分配到一个执行进程去处理。RDD 上的转换操作又分成两种,一种转换操作产生的 RDD 不会出现新的分片,比如 map、filter 等,也就是说一个 RDD 数据分片,经过 map 或者 filter 转换操作后,结果还在当前分片,即是数据的分片关系不会改变。这样的转换不会进行 shuffle 操作。另一种转换操作产生的 RDD 则会产生新的分片,比如 reduceByKey,来自不同分片的相同 Key 必须聚合在一起进行操作,这样就会产生新的 RDD 分片。这样的转换会进行 shffle 操作。实际执行过程中,是否会产生新的 RDD 分片,并不是根据转换函数名就能判断出来的。
RDD 之间的依赖关系有两种:窄依赖和宽依赖,从上一个 RDD 到下一个 RDD 时没有 shuffle 操作的是窄依赖,有 shuffle 操作的是宽依赖。
RDD 一方面是编程模型在编程的时候针对 RDD 进行不断地各种各样的转换操作生成新的 RDD 来完成大数据计算逻辑,另一方面 RDD 也是 spark 的核心物理概念在物理上面的数据就是一个 RDD。和 MapReduce 一个应用一次只运行一个 map 和一个 reduce 不同,Spark 可以根据应用的复杂程度,分割成更多的计算阶段(stage),这些计算阶段组成一个有向无环图 DAG,Spark 任务调度器根据 DAG 的依赖关系执行计算阶段。每一个计算阶段是一个计算任务集,在集群中的一台服务器上进行计算,不同的任务集在不同的服务器上运行。计算阶段划分的依据是 shuffle 也就是宽依赖,不是转换函数的类型,有的函数有时候 shuffle,有时候是没有的。
Spark 作业调度执行的核心是 DAG,有了 DAG,整个应用就被切分成哪些阶段,每个阶段的依赖关系也就清楚了。之后再根据每个阶段要处理的数据量生成相应的任务集合(TaskSet),每个任务都分配一个任务进程去处理,Spark 就实现了大数据的分布式计算。负责 Spark 应用 DAG 生成和管理的组件是 DAGScheduler,DAGScheduler 根据程序代码生成 DAG,然后将程序分发到分布式计算集群,按计算阶段的先后关系调度执行。
spark 构建了一个自己的生态体系,除了最核心的 spark 本身,在这之上还有:
sparkSQL:把 SQL 转换成 spark 的计算任务
sparkstreaming:流处理计算
MLlib:进行机器学习大数据计算
GraphX:图计算,很多大数据计算特别是数据挖掘和机器学习可以转换成图计算。
MR\Hive\spark 这些大数据引擎被称为是批处理计算引擎,是以一大批数据作为输入进行计算的。数据量大计算时间长,通常是离线进行计算的。与之对应的是流处理计算,计算时间短(以秒或毫秒为单位)数据量小(一条数据或者一小批(秒/毫秒时间内的数据))进行计算,需要实时的快速的对大规模流入的数据进行计算。
最早的流处理计算是 Storm,它的典型特征是:低延迟、高性能、分布式、可伸缩、高可用。
Storm 的角色:
Nimbus:负责资源分配和任务调度。
Supervisor:负责接受 Nimbus 分配的任务,启动和停止属于自己管理的 Worker 进程。
Worker:运行具体处理组件逻辑的进程。
Task:Worker 中每一个 Spout/Bolt 的线程称为一个 Task。
storm 编程的时候是要编一个 Topology,这里面重要的是要编一些 spout 和 bolt,然后把这些 spout 和 bolt 通过 Topology 构建成一个计算结构逻辑拓扑结构,然后把 Topology 提交给 storm 集群,storm 集群就会在一个分布式的集群中督促这些 spout 和 bolt 完成一个流式的快速计算。
Topology:Storm 中运行的一个实时应用程序,因为各个组件间的消息流动形成逻辑上的一个拓扑结构。
Spout:在一个 Topology 中产生源数据流的组件。通常情况下 Spout 会从外部数据源中读取数据,然后转换为 Topology 内部的源数据。Spout 是一个主动的角色,其接口中有个 nextTuple() 函数,Storm 框架会不停地调用此函数,用户只要在其中生成源数据即可。
Bolt:在一个 Topology 中接受数据然后执行处理的组件。Bolt 可以执行过滤、函数操作、合并、写数据库等任何操作。Bolt 是一个被动的角色,其接口中有个 execute(Tuple input) 函数,在接受到消息后会调用此函数,用户可以在其中执行自己想要的操作。
Tuple:一次消息传递的基本单元。本来应该是一个 key-value 的 map,但是由于各个组件间传递的 tuple 的字段名称已经事先定义好,所以 tuple 中只要按序填入各个 value 就行了,所以就是一个 value list。
Stream:源源不断传递的 tuple 就组成了 stream。
Nimbus,整个 storm 集群中全局唯一。Supervisor 作为一个具体的负责计算的各种节点,它在集群中有很多台,它们都向 zk 注册。Nimbus 通过 zk 管理 Supervisor,向它们去分配计算任务,Supervisor 领到任务后会启动 worker,在 worker 进程里执行具体的 task 计算。
spark 的 spark streaming 也是流处理计算引擎,它简单复用以前的 spark 的基础设施快速地搭建基于 spark 的流式计算系统,进行流式计算的时候只是改变了对应的数据源,通过设置时间窗口(比如 1 秒)把流进来的数据进行缓存,切分成微批再转换成 RDD 进行计算处理。
flink 跟 spark 的架构思路非常像,spark 是以批处理为基础支持流程流,而 flink 是以流处理为基础支持批处理。批处理跟流处理之间的界限其实并没有那么明显,看起来流处理和批处理是非常不同的两种应用场景,但是在技术内核技术体系里面它们之间的界限其实并不那么明确,流处理里面的每个微小批大了就变成批处理了,而批处理的每个时间片或者数据分片小了就变成流处理了。
KNN 算法,也叫 K 近邻(K NearestNeighbour)算法:对于一个需要分类的数据,将其和一组已
经分类标注好的样本集合进行比较,得到距离最近的 K 个样本,K 个样本最多归属的类别,就是这个需要分类数据的类别。
KNN 算法处理流程:计算待分类数据与每个样本之间的距离->对距离排序,取距离最近的前 K 个训练样本->统计这 K 个训练样本的类别->统计得到最多的类别为待分类数据的类别
对于文本分类通常需要先提取若干个特征值,由特征值组成一个特征向量。得到一篇文本的特征值,可以使用 TF-IDF 算法提取文本的特征词的 TF-IDF。其原理是:当一个词在别的文档中出现得越少,而在这篇文档中出现得越多,TF-IDF 值越高的词就越可能称为特征词。
提取文本的特征值 TF-IDF 算法:
TF 是词频(Term Frequency),表示某个单词在文档中出现的频率。TF=某个词在文档中出现的次数/文档总词数
IDF 是逆文档频率(Inverse Document Frequency),表示这个单词在所有文档中的稀缺程度。IDF=Log(所有的文档总数/出现该词的文档数)
TF-IDF=TF*IDF
对一篇文章/文本中所有的词都求取 TF-IDF,然后对 TF-IDF 进行排序,取 TF-IDF 高的若干个值构成特征向量(特征空间),用特征空间距离就可以进行 KNN 分类算法了。
K-means 聚类算法:通过随机的中心点(种子点)求取所有数据和中心点之间的距离进行聚类,聚类完了以后,聚类结果中的数据再计算它的中心点,再重新进行距离计算进行计算,这样不断地对每个数据进行重新分类,直到最后稳定下来分类关系不再改变。稳定一般是指算出来的新中心点更旧的中心点的距离非常小,小于一个阈值就完成了。
搜索引擎是根据想要的东西去进行搜索,推荐引擎是系统主动为用户推荐东西(猜你喜欢什么)。
基于人口统计的推荐:如果两个人是同一类,A 用户喜欢一个东西,则向同类 B 用户推荐这个东西。
基于商品属性的推荐:如果两件商品本身属性相近,一个人喜欢其中一件商品,则向它推荐另一件商品。
基于用户的协同过滤推荐:如果两个用户都喜欢某些商品,则他们属于同一类,将其中一个喜欢的而另一个用户还没有的商品推荐给另一个用户。
基于商品的协同过滤推荐:如果用户 A 喜欢商品 ABD,而用户 B 喜欢商品 BCD,用户 C 喜欢 B,则商品 BD 属于同类,向用户 C 推荐商品 D。
不管是基于用户的协同过滤还是基于商品的协同过滤,它们找同类的方法其实都是通过用户的喜好识别同类的,只是基于用户是识别用户的同类,基于商品是识别商品的同类,然后进行推荐。
评论