Map-Reduce



我认为上图代表着MapReduce不仅仅包括Map和Reduce两个步骤这么简单,还有两个隐含步骤没有明确,全部步骤包括:切片、转换、聚合、叠加,按照实际的运算场景上述步骤可以简化。

具体的流程为:

  • 原始数据 -) [切片] -> 数据对单元集合(列表) (k1,v1)
  • 数据对单元集合 (k1,v1) -> [Map转换] -) 数据对单元集合 (k2,v2)
  • 数据对单元集合 (k2,v2) -> [聚合(合并] -) 数据对单元集合(字典)(k2,[v2])
  • 数据对单元集合 (k2,[v2]) -> [抽象(叠加)reduce] -) 数据对单元集合(列表)[(k3,v3)]

Spark作业流程

  1. 用户编写Spark程序,定义RDD创建、转换、行动、存储等操作。提交程序(spark-submit xx.py)申请Spark集群执行该程序;
  2. Spark集群收到用户的程序后,启动Driver进程,负责响应执行用户的函数。Driver也可以在Client端启动,也可以在某个worker节点启动; Driver启动后,发现函数包含了RDD的相关操作(这些操作会分散在集群中并行完成),与Master节点通信申请资源;
  3. 在Spark集群中的所有worker节点都会向Master节点注册自己的计算资源;Master资源会通过心跳检测来检测节点状态;在收到driver在3条件下申请后,master会命令已注册的worker节点按照调度策略启动executor进程;
  4. Master检查发现worker节点状态存活且worker节点上的executor启动成功,Master将已经启动的资源信息通知driver进程,让driver进程了解可以使用哪些资源来完成Spark程序;
  5. driver根据Spark程序中的RDD操作情况对程序进行分割,分割后的任务发送给已经申请的多个executor资源,每个executor独立完成分配的计算任务,并将执行的结果反馈给driver,driver负责了解每一个executor进程的完成情况,以统一了解整个spark程序的完成情况;
  6. worker节点上运行的executor是真正工作的执行者,在每个worker节点上可以启动多个executor,每个executor单独运行一个JVM进程,每个计算任务则是运行在executor中的一个线程,最后executor负责将计算结果保存到磁盘中;
  7. driver通知client应用程序执行完成。

    上述的步骤中有三个细节需要特别注意:
  • spark采用惰性计算来生成RDD(只有遇到action操作才会生成新的RDD),生成操作通过将所有相关操作形成一个有向无环图DAG来试试,每个DAG会触发Spark生成一个作业。
  • driver节点中的DAGScheduler实例会想有向无环图中的节点依赖关系遍历,并将所有操作切分成多个调度阶段(stage),并生成对应的taskSet。
  • driver节点中的TaskScheduler会为每一个taskSet生成taskSetManager(管理每个taskset的内部调度任务,维护taskset的声明周期),并提交到worker节点的executor进程中执行。
  • 从微观上来看,一个spark应用程序最终是分解成了多个taskset的任务急。在并行执行taskset的情况下,TaskScheduler调度策略可以分为FIFO先进先出和FAIR公平调度两种模式。

Spark并发机制

  • Spark的基础数据结构RDD是由一系列的分区构成的,每个分区中包含一个RDD的部分数据;
  • 在Spark调度和执行计算任务时,会为RDD的每个分区创建一个Task;
  • 默认的情况下,Spark为每个需要执行的Task分配一个CPU内核资源



Spark RDD和Job生命周期

RDD 的生存周期主要包括 RDD 的创建和操作。RDD 的创建有两种方式:从 HDFS(或其他分布式存储系统)输入创建以及从父 RDD 转换得到新 RDD。对于 RDD 的操作可以分为两种,即 Transformation 和 Action。Transformation 是根据现有的数据集创建一个新的数据集,Action 是在 RDD 上运行计算后,返回一个值给驱动程序。Transformations 操作是Lazy 的,也就是说从一个 RDD 转换生成 转换生成另一个 RDD 的操作不马上执行,Spark 在遇到Transformations 操作时只会记录需要这样的操作,并不会去执行,需要等到有 Actions 操作的时候才会真正启动计算过程进行计算。

Job 的生存周期是从 Action 作用于某 RDD 时开始的,此时该 Action 将会作为一个 Job被提交。在提交的过程中,DAGScheduler 模块介入运算,计算 RDD 之间的依赖关系。RDD之间的依赖关系就形成了 DAG。每一个 Job 被分为多个 stage,划分 stage 的一个主要依据是当前计算因子的输入是否是确定的,如果是则将其分在同一个 stage,避免多个 stage 之间的消息传递开销。当 stage 被提交之后,由 TaskScheduler 根据 stage 来计算所需要的 task,并将 task 提交到对应的 Worker。

pyspark

  • 数据集
  • access.log:第一列为网络标号,0表示2G和3G的网络,1为4G网络。用以过滤和去重
  • words.txt: 关于python的英文文档介绍,用于实现计数和topk。
  • bayes1.dat: 朴素贝叶斯输入数据,有四个天气维度决定一个人是否出行,四个维度分别是天气外观、温度、湿度、刮风,最后一个值是否出行。
  • bayes2.dat: 朴素贝叶斯测试数据。
  1. [kejun.he@spark36 ~]$ cat access.log
  2. 0 12341234 www.baidu.com/s?wd=spark
  3. 1 22113345 www.hulian.com
  4. 1 332244 www.wanglian.com
  5. 0 15558 www.zhice.com
  6. 1 332244 www.wanglian.com
  7. 1 999222 www.up.com
  8. 1 999222 www.up.com
  9. 1 999222 www.up.com
  10. [kejun.he@spark36 ~]$ cat bayes1.dat
  11. sunny hot high FALSE no
  12. sunny hot high TRUE no
  13. overcast hot high FALSE yes
  14. rainy mild high FALSE yes
  15. rainy cool normal FALSE yes
  16. rainy cool normal TRUE no
  17. overcast cool normal TRUE yes
  18. sunny mild high FALSE no
  19. sunny cool normal FALSE yes
  20. rainy mild normal FALSE yes
  21. sunny mild normal TRUE yes
  22. overcast mild high TRUE yes
  23. overcast hot normal FALSE yes
  24. rainy mild high TRUE no
  25. [kejun.he@spark36 ~]$ cat bayes2.dat
  26. sunny mild normal True
  27. sunny hot high False
  28. rainy cool high True
  29. overcast cool normal False
  30. [kejun.he@spark36 ~]$ hadoop fs -put access.log /user/kejun.he/input
  31. [kejun.he@spark36 ~]$ hadoop fs -put words.txt /user/kejun.he/input
  32. [kejun.he@spark36 ~]$ hadoop fs -put bayes1.dat /user/kejun.he/input
  33. [kejun.he@spark36 ~]$ hadoop fs -put bayes2.dat /user/kejun.he/input

过滤,去重及统计

在access.log中统计4G网络的不同用户访问次数。

  1. >>> log=sc.textFile("file:///home/kejun.he/access.log")
  2. >>> log.collect()
  3. [u'0 12341234 www.baidu.com/s?wd=spark', u'1 22113345 www.hulian.com', u'1 332244 www.wanglian.com', u'0 15558 www.zhice.com', u'1 999221 www.up.com/s?blabla', u'1 332214 www.wanglian.com', u'1 999221 www.up.com', u'1 999222 www.up.com', u'1 999223 www.up.com']
  4. >>> filter_rdd=log.filter(lambda x:x.split(" ")[0]=="1") #导入数据
  5. >>> filter_rdd.collect()
  6. [u'1 22113345 www.hulian.com', u'1 332244 www.wanglian.com', u'1 999221 www.up.com/s?blabla', u'1 332214 www.wanglian.com', u'1 999221 www.up.com', u'1 999222 www.up.com', u'1 999223 www.up.com']
  7. >>> import re
  8. >>> map_rdd=filter_rdd.map(lambda x:" ".join([x.split(" ")[1],re.compile("/.*").sub("",x.split(" ")[2])]))#数据转换:1去除网络标记号,2.保留站点信息
  9. >>> map_rdd.collect()
  10. [u'22113345 www.hulian.com', u'332244 www.wanglian.com', u'999221 www.up.com', u'332214 www.wanglian.com', u'999221 www.up.com', u'999222 www.up.com', u'999223 www.up.com']
  11. >>> revert_rdd=map_rdd.map(lambda x:(x.split(" ")[1],x.split(" ")[0])) #数据转换,形成<网站,用户>的key-value对
  12. >>> revert_rdd.collect()
  13. [(u'www.hulian.com', u'22113345'), (u'www.wanglian.com', u'332244'), (u'www.up.com', u'999221'), (u'www.wanglian.com', u'332214'), (u'www.up.com', u'999221'), (u'www.up.com', u'999222'), (u'www.up.com', u'999223')]
  14. >>> distinct_rdd=revert_rdd.distinct() #去重
  15. >>> distinct_rdd.collect()
  16. [(u'www.hulian.com', u'22113345'), (u'www.up.com', u'999222'), (u'www.wanglian.com', u'332214'), (u'www.up.com', u'999221'), (u'www.up.com', u'999223'), (u'www.wanglian.com', u'332244')]
  17. >>> set_one_rdd=distinct_rdd.mapValues(lambda x:1) #去除用户信息
  18. >>> set_one_rdd.collect()
  19. [(u'www.hulian.com', 1), (u'www.up.com', 1), (u'www.wanglian.com', 1), (u'www.up.com', 1), (u'www.up.com', 1), (u'www.wanglian.com', 1)]
  20. >>> from operator import add
  21. >>> reduce_rdd=set_one_rdd.reduceByKey(add)#统计次数
  22. >>> reduce_rdd.collect()
  23. [(u'www.up.com', 3), (u'www.hulian.com', 1), (u'www.wanglian.com', 2)]
  24. >>> reduce_rdd.saveAsTextFile("output") #保存统计结果

相关计数

与之前的Spark环境安装 实现的简单计数有区别,相关计数是计算两个或多个实体以一定方式共同出现的次数或者概率,在数据挖掘的领域中,我们也称为co-occurance。这个工作将切换到python文件运行的模式,不在pyspark下使用。

运算的步骤如下:

  • 获取每一行的文本数据
  • 对该行数据进行文本清洗
  • 清洗后进行转换关联,并形成key-value对
  • reduce统计
  1. from pyspark import SparkContext
  2. from operator import add
  3. import re
  4. print ("start doing ###############")
  5. sc=SparkContext("spark://spark36.localdomain:7077","myApp")
  6. naive_words=sc.textFile("hdfs:///user/kejun.he/input/words.txt").cache()
  7. words_rdd=naive_words.map(lambda str1: str1.replace("."," ").replace(","," ").replace("("," ").replace(")"," ").replace("-"," ").replace(":"," ").split(" ")).cache()
  8. #print words_rdd.collect()
  9. def cut_words(x):
  10. l=len(x)
  11. i=0
  12. while(i<l-1):
  13. if is_valid(x[i]) and is_valid(x[i+1]):
  14. yield ((x[i],x[i+1]),1)
  15. i+=1
  16. def is_valid(ch):
  17. match=re.search('^[a-zA-Z1-9]+$', ch)
  18. if match:
  19. return True
  20. else:
  21. return False
  22. transform_rdd=words_rdd.flatMap(cut_words)
  23. #print transform_rdd.collect()
  24. count_result=transform_rdd.reduceByKey(add)
  25. sorted_result=count_result.sortBy(lambda x:x[1])
  26. #print (sorted_result.collect())
  27. sorted_result.repartition(1).saveAsTextFile("count_co_occurance")

朴素贝叶斯

Spark学习笔记的更多相关文章

  1. Spark学习笔记之SparkRDD

    Spark学习笔记之SparkRDD 一.   基本概念 RDD(resilient distributed datasets)弹性分布式数据集. 来自于两方面 ①   内存集合和外部存储系统 ②   ...

  2. spark学习笔记总结-spark入门资料精化

    Spark学习笔记 Spark简介 spark 可以很容易和yarn结合,直接调用HDFS.Hbase上面的数据,和hadoop结合.配置很容易. spark发展迅猛,框架比hadoop更加灵活实用. ...

  3. Spark学习笔记2(spark所需环境配置

    Spark学习笔记2 配置spark所需环境 1.首先先把本地的maven的压缩包解压到本地文件夹中,安装好本地的maven客户端程序,版本没有什么要求 不需要最新版的maven客户端. 解压完成之后 ...

  4. Spark学习笔记3(IDEA编写scala代码并打包上传集群运行)

    Spark学习笔记3 IDEA编写scala代码并打包上传集群运行 我们在IDEA上的maven项目已经搭建完成了,现在可以写一个简单的spark代码并且打成jar包 上传至集群,来检验一下我们的sp ...

  5. Spark学习笔记-GraphX-1

    Spark学习笔记-GraphX-1 标签: SparkGraphGraphX图计算 2014-09-29 13:04 2339人阅读 评论(0) 收藏 举报  分类: Spark(8)  版权声明: ...

  6. Spark学习笔记3——RDD(下)

    目录 Spark学习笔记3--RDD(下) 向Spark传递函数 通过匿名内部类 通过具名类传递 通过带参数的 Java 函数类传递 通过 lambda 表达式传递(仅限于 Java 8 及以上) 常 ...

  7. Spark学习笔记0——简单了解和技术架构

    目录 Spark学习笔记0--简单了解和技术架构 什么是Spark 技术架构和软件栈 Spark Core Spark SQL Spark Streaming MLlib GraphX 集群管理器 受 ...

  8. Spark学习笔记2——RDD(上)

    目录 Spark学习笔记2--RDD(上) RDD是什么? 例子 创建 RDD 并行化方式 读取外部数据集方式 RDD 操作 转化操作 行动操作 惰性求值 Spark学习笔记2--RDD(上) 笔记摘 ...

  9. Spark学习笔记1——第一个Spark程序:单词数统计

    Spark学习笔记1--第一个Spark程序:单词数统计 笔记摘抄自 [美] Holden Karau 等著的<Spark快速大数据分析> 添加依赖 通过 Maven 添加 Spark-c ...

  10. Spark学习笔记——读写Hbase

    1.首先在Hbase中建立一张表,名字为student 参考 Hbase学习笔记——基本CRUD操作 一个cell的值,取决于Row,Column family,Column Qualifier和Ti ...

随机推荐

  1. Linux IPC实践(3) --具名FIFO

    FIFO具名/命名管道 (匿名)管道应用的一个限制就是只能在具有共同祖先(具有亲缘关系)的进程间通信. 如果我们想在不相关的进程之间交换数据,可以使用FIFO文件来做这项工作,它经常被称为命名管道;命 ...

  2. 高性能C++网络库libtnet实现:http

    HTTP libtnet提供了简单的http支持,使用也很简单. 一个简单的http server: void onHandler(const HttpConnectionPtr_t& con ...

  3. Linux0.11进程切换和TSS结构

    TSS 全称为task state segment,是指在操作系统进程管理的过程中,进程切换时的任务现场信息.       X86体系从硬件上支持任务间的切换.为此目的,它增设了一个新段:任务状态段( ...

  4. webService详解(一)

    [sql] 什么是webService  WebService,顾名思义就是基于Web的服务.它使用Web(HTTP)方式,接收和响应外部系统的某种请求.从而实现远程调用.   1:从WebServi ...

  5. [Python]Flask构建网站分析应用

    原文Saturday morning hacks: Building an Analytics App with Flask - 由orangleliu友情翻译 ,主要是通过埋点技术来实现web网页的 ...

  6. Leetcode_116_Populating Next Right Pointers in Each Node

    本文是在学习中的总结,欢迎转载但请注明出处:http://blog.csdn.net/pistolove/article/details/43532817 Given a binary tree st ...

  7. 集群通信组件tribes之使用方法

    上面已经对tribes的内部实现机制及原理进行了深入的剖析,在理解它的设计原理后看看如何使用tribes,整个使用相当简单便捷,只需要四步: ① 定义一个消息对象,由于这个消息对象是要在网络之间传递的 ...

  8. Java-HttpSession监听

    //HttpSession监听 public interface HttpSessionActivationListener extends EventListener { /** Notificat ...

  9. Android性能优化典例(一)

    在Android开发过程中,很多时候往往因为代码的不规范.api使用不恰当.控件的使用场景考虑不全面和用户不恰当的操作等都能引发一系列性能问题的,下面就是我目前整理的一些Android开发过程中需要注 ...

  10. PS 图像调整算法——反相

    这个顾名思义,对图像做减法. Image_new=1-Image_old; 原图: 反相: