写点什么

架构师第十三周总结

用户头像
Geek_Gu
关注
发布于: 2020 年 12 月 20 日

Spark

Spark 有三个主要特性:RDD 的编程模型更简单,DAG 切分的多阶段计算过程更快速,使用内存存储中间计算结果更高效。这三个特性使得 Spark 相对 Hadoop MapReduce 可以有更快的执行速度,以及更简单的编程实现。和 MapReduce 一样,Spark 也遵循移动计算比移动数据更划算这一大数据计算基本原则。但是和 MapReduce 僵化的 Map 与 Reduce 分阶段计算相比,Spark 的计算框架更加富有弹性和灵活性,进而有更好的运行性能。Spark 和 MapReduce 进行逻辑回归机器学习的性能比较,Spark 比 MapReduce 快 100 多倍。除了速度更快,Spark 和 MapReduce 相比,还有更简单易用的编程模型。使用 Scala 语言在 Spark 上编写 WordCount 程序,主要代码只需要三行。


和 MapReduce 一个应用一次只运行一个 map 和一个 reduce 不同,Spark 可以根据应用的复杂程度,分割成更多的计算阶段(stage),这些计算阶段组成一个有向无环图 DAG,Spark 任务调度器可以根据 DAG 的依赖关系执行计算阶段。Spark 作业调度执行的核心是 DAG,有了 DAG,整个应用就被切分成哪些阶段,每个阶段的依赖关系也就清楚了。之后再根据每个阶段要处理的数据量生成相应的任务集合(TaskSet),每个任务都分配一个任务进程去处理,Spark 就实现了大数据的分布式计算。负责 Spark 应用 DAG 生成和管理的组件是 DAGScheduler,DAGScheduler 根据程序代码生成 DAG,然后将程序分发到分布式计算集群,按计算阶段的先后关系调度执行。


RDD 是 Spark 的核心概念,是弹性数据集(Resilient Distributed Datasets)的缩写。RDD 既是 Spark 面向开发者的编程模型,又是 Spark 自身架构的核心元素。MapReduce 针对输入数据,将计算过程分为两个阶段,一个 Map 阶段,一个 Reduce 阶段,可以理解成是面向过程的大数据计算。在用 MapReduce 编程的时候,思考的是,如何将计算逻辑用 Map 和 Reduce 两个阶段实现,map 和 reduce 函数的输入和输出是什么,这也是上周在学习 MapReduce 编程的时候强调的。而 Spark 则直接针对数据进行编程,将大规模数据集合抽象成一个 RDD 对象,然后在这个 RDD 上进行各种计算处理,得到一个新的 RDD,继续计算处理,直到得到最后的结果数据。所以 Spark 可以理解成是面向对象的大数据计算。在进行 Spark 编程的时候,思考的是一个 RDD 对象需要经过什么样的操作,转换成另一个 RDD 对象,思考的重心和落脚点都在 RDD 上。


RDD 上定义的函数分两种,一种是转换(transformation)函数,这种函数的返回值还是 RDD;另一种是执行(action)函数,这种函数不再返回 RDD。RDD 定义了很多转换操作函数,有计算 map(func)、过滤 filter(func)、合并数据集 union(otherDataset)、根据 Key 聚合 reduceByKey(func, [numPartitions])、连接数据集 join(otherDataset, [numPartitions])、分组 groupByKey([numPartitions]) 等十几个函数。跟 MapReduce 一样,Spark 也是对大数据进行分片计算,Spark 分布式计算的数据分片、任务调度都是以 RDD 为单位展开的,每个 RDD 分片都会分配到一个执行进程去处理。RDD 上的转换操作又分成两种,一种转换操作产生的 RDD 不会出现新的分片,比如 map、filter 等,也就是说一个 RDD 数据分片,经过 map 或者 filter 转换操作后,结果还在当前分片。就像你用 map 函数对每个数据加 1,得到的还是这样一组数据,只是值不同。实际上,Spark 并不是按照代码写的操作顺序去生成 RDD,比如 rdd2 = rdd1.map(func)这样的代码并不会在物理上生成一个新的 RDD。物理上,Spark 只有在产生新的 RDD 分片时候,才会真的生成一个 RDD,Spark 的这种特性也被称作惰性计算。


Spark 的运行流程:Spark 应用程序启动在自己的 JVM 进程里,即 Driver 进程,启动后调用 SparkContext 初始化执行配置和输入数据。SparkContext 启动 DAGScheduler 构造执行的 DAG 图,切分成最小的执行单位也就是计算任务。然后 Driver 向 Cluster Manager 请求计算资源,用于 DAG 的分布式计算。Cluster Manager 收到请求以后,将 Driver 的主机地址等信息通知给集群的所有计算节点 Worker。Worker 收到信息以后,根据 Driver 的主机地址,跟 Driver 通信并注册,然后根据自己的空闲资源向 Driver 通报自己可以领用的任务数。Driver 根据 DAG 图开始向注册的 Worker 分配任务。Worker 收到任务后,启动 Executor 进程开始执行任务。Executor 先检查自己是否有 Driver 的执行代码,如果没有,从 Driver 下载执行代码,通过 Java 反射加载后开始执行。

Storm、Spark Streaming、Flink


用消息队列实现大数据实时处理,如果处理起来比较复杂,那么就需要很多个消息队列,将实现不同业务逻辑的生产者和消费者串起来,消息队列负责完成数据的流转;处理逻辑既是消费者也是生产者,也就是既消费前面消息队列的数据,也为下个消息队列产生数据。storm 根据以上逻辑产生,只要定义好处理流程和每一个节点的处理逻辑,代码部署到流处理系统后,就能按照预定义的处理流程和处理逻辑执行。

有了 Storm 后,开发者无需再关注数据的流转、消息的处理和消费,只要编程开发好数据处理的逻辑 bolt 和数据源的逻辑 spout,以及它们之间的拓扑逻辑关系 toplogy,提交到 Storm 上运行就可以了。


Spark Streaming 巧妙地利用了 Spark 的分片和快速计算的特性,将实时传输进来的数据按照时间进行分段,把一段时间传输进来的数据合并在一起,当作一批数据,再去交给 Spark 去处理。如果时间段分得足够小,每一段的数据量就会比较小,再加上 Spark 引擎的处理速度又足够快,这样看起来好像数据是被实时处理的一样,这就是 Spark Streaming 实时流计算。


Flink 既可以流处理又可以批处理。Flink 一开始就是按照流处理计算去设计的,Flink 对流处理的支持也更加完善,它可以对数据流执行 window 操作,将数据流切分到一个一个的 window 里,进而进行计算。

进行流计算 Flink 会初始化一个流执行环境 StreamExecutionEnvironment,然后利用这个执行环境构建数据流 DataStream。

进行批处理计算,Flink 会初始化一个批处理执行环境 ExecutionEnvironment,然后利用这个环境构建数据集 DataSet。

然后在 DataStream 或者 DataSet 上执行各种数据转换操作(transformation),这点很像 Spark。不管是流处理还是批处理,Flink 运行时的执行引擎是相同的,只是数据源不同而已。

HiBench

大数据基准测试的主要用途是对各种大数据产品进行测试,检验大数据产品在不同硬件平台、不同数据量、不同计算任务下的性能表现。

HiBench 内置了若干主要的大数据计算程序作为基准测试的负载(workload)。

  • Sort,对数据进行排序大数据程序。

  • WordCount,词频统计大数据计算程序。

  • TeraSort,对 1TB 数据进行排序,最早是一项关于软件和硬件的计算力的竞赛,所以很多大数据平台和硬件厂商进行产品宣传的时候会用 TeraSort 成绩作为卖点。

  • Bayes 分类,机器学习分类算法,用于数据分类和预测。

  • k-means 聚类,对数据集合规律进行挖掘的算法。

  • 逻辑回归,数据进行预测和回归的算法。

  • SQL,包括全表扫描、聚合操作(group by)、连接操作(join)几种典型查询 SQL。

  • PageRank,Web 排序算法。

此外还有十几种常用大数据计算程序,支持的大数据框架包括 MapReduce、Spark、Storm 等。

HiBench 使用
  1. 配置,配置要测试的数据量、大数据运行环境和路径信息等基本参数。

  2. 初始化数据,生成准备要计算的数据,比如要测试 1TB 数据的排序,那么就生成 1TB 数据。

  3. 执行测试,运行对应的大数据计算程序。


大数据算法

KNN 算法,即 K 近邻(K Nearest Neighbour)算法,是一种基本的分类算法。其主要原理是:对于一个需要分类的数据,将其和一组已经分类标注好的样本集合进行比较,得到距离最近的 K 个样本,K 个样本最多归属的类别,就是这个需要分类数据的类别。



红蓝绿三种颜色的点为样本数据,分属三种类别 w1​、w2​、 w3​ 。对于待分类点 Xu​ ,计算和它距离最近的 5 个点(即 K 为 5),这 5 个点最多归属的类别为 w1​(4 个点归属 w1​,1 个点归属 w3​),那么 Xu​ 的类别被分类为 w1​。KNN 算法的关键是要比较需要分类的数据与样本数据之间的距离,这在机器学习中通常的做法是:提取数据的特征值,根据特征值组成一个 n 维实数向量空间(这个空间也被称作特征空间),然后计算向量之间的空间距离。空间之间的距离计算方法有很多种,常用的有欧氏距离、余弦距离等。

KNN 算法是一种非常简单实用的分类算法,可用于各种分类的场景,比如新闻分类、商品分类等,甚至可用于简单的文字识别。对于新闻分类,可以提前对若干新闻进行人工标注,标好新闻类别,计算好特征向量。对于一篇未分类的新闻,计算其特征向量后,跟所有已标注新闻进行距离计算,然后进一步利用 KNN 算法进行自动分类。


贝叶斯公式是一种基于条件概率的分类算法,如果已经知道 A 和 B 的发生概率,并且知道了 B 发生情况下 A 发生的概率,可以用贝叶斯公式计算 A 发生的情况下 B 发生的概率。事实上,可以根据 A 的情况,即输入数据,判断 B 的概率,即 B 的可能性,进而进行分类。

贝叶斯分类的一个典型的应用场合是垃圾邮件分类,通过对样本邮件的统计,知道每个词在邮件中出现的概率 P(Ai​),也知道正常邮件概率 P(B0​) 和垃圾邮件的概率 P(B1​),还可以统计出垃圾邮件中各个词的出现概率 P(Ai​∣B1​),那么现在一封新邮件到来,就可以根据邮件中出现的词,计算 P(B1​∣Ai​),即得到这些词出现情况下,邮件为垃圾邮件的概率,进而判断邮件是否为垃圾邮件。


推荐算法

常用:基于人口统计的推荐、基于商品属性的推荐、基于用户的协同过滤推荐、基于商品的协同过滤推荐。


基于人口统计的推荐是相对比较简单的一种推荐算法,根据用户的基本信息进行分类,然后将商品推荐给同类用户。这种推荐算法也不依赖商品的数据,和要推荐的领域无关,不管是服装还是美食,不管是电影还是旅游目的地,都可以进行推荐。对于稍微精细一点的场景,推荐效果就比较差。因此,在人口统计信息的基础上,根据用户浏览、购买信息和其他相关信息,进一步细化用户的分类信息,给用户贴上更多的标签,比如家庭成员、婚姻状况、居住地、学历、专业、工作等,即所谓的用户画像,根据用户画像进行更精细的推荐,并进一步把用户喜好当做标签完善用户画像,再利用更完善的用户画像进行推荐,如此不断迭代优化用户画像和推荐质量。


基于商品属性的推荐是将商品的属性进行分类,然后根据用户的历史行为进行推荐。需要对商品属性进行全面的分析和建模,难度相对也更大一点,在实践中,一种简单的做法是提取商品描述的关键词和商品的标签作为商品的属性。此外,基于商品属性的推荐依赖用户的历史行为数据,如果是新用户进来,没有历史数据,就没有办法进行推荐了,即存在“冷启动”问题。相对于基于人口统计的推荐,基于商品属性的推荐会更符合用户的口味,推荐效果相对更好一点。


基于用户的协同过滤推荐是根据用户的喜好进行用户分类,常用的就是 KNN 算法,寻找和当前用户喜好最相近的 K 个用户,然后根据这些用户的喜好为当前用户进行推荐。基于用户的协同过滤推荐和基于人口统计的推荐都是将用户分类后,根据同类用户的喜好为当前用户进行推荐。不同的是,基于人口统计的推荐仅仅根据用户的个人信息进行分类,分类的粒度比较大,准确性也较差;而基于用户的协同过滤推荐则根据用户历史喜好进行分类,能够更准确地反映用户的喜好类别,推荐效果也更好一点。


基于商品的协同过滤推荐是根据用户的喜好对商品进行分类,如果两个商品,喜欢它们的用户具有较高的重叠性,就认为它们的距离相近,划分为同类商品,然后进行推荐。商品的分类相对用户的分类更为稳定,通常情况下,商品的数目也少于用户的数目,因此使用基于商品的协同过滤推荐,计算量和复杂度小于基于用户的协同过滤推荐。


除了上面这些推荐算法,还有基于模型的推荐,根据用户和商品数据,训练数学模型,然后进行推荐。在实践中,通常会混合应用多种算法进行推荐。


机器学习

通过选择特定的算法对样本数据进行计算,获得一个计算模型,并利用这个模型,对以前未曾见过的数据进行预测。这个过程和人类的学习成长非常类似,也是经历一些事情(获得样本数据),进行分析总结(寻找算法),产生经验(产生模型),然后利用经验(模型)指导自己的日常行为。


构建一个机器学习系统,需要有三个关键要素:样本、模型、算法。

机器学习的数学原理:给定模型类型,也就是给定函数类型的情况下,如何寻找使结构风险最小的函数表达式。由于函数类型已经给定,实际上就是求函数的参数。各种有样本的机器学习算法基本上都是在各种模型的假设空间上求解结构风险最小值的过程,理解了这一点也就理解了各种机器学习算法的推导过程。由于计算机没有办法直接通过解析计算得到需要的函数表达式,因此必须使用数值计算的方式求函数表达式,也就是将大量的样本数据带入数值计算算法迭代计算函数的参数。给定不同参数,得到不同函数值和真实值的距离,这个距离就是损失,损失函数是关于模型参数的函数,距离越小,损失越小。最小损失值对应的函数参数就是最优函数。


用户头像

Geek_Gu

关注

还未添加个人签名 2019.09.09 加入

还未添加个人简介

评论

发布
暂无评论
架构师第十三周总结