Hadoop

参考:《Hadoop入门教程》https://blog.csdn.net/yuan_xw/article/details/50003197

《Hadoop架构介绍——HDFS的体系结构》https://blog.csdn.net/u013063153/article/details/53114678

《HDFS运行原理》https://www.cnblogs.com/laov/p/3434917.html

《Hadoop工作流程》https://blog.csdn.net/hongchenlingtian/article/details/53524705

一、概念

Hadoop是Apache开源组织的一个分布式计算开源框架,实现在大量计算机组成的集群中对海量数据进行分布式计算。Hadoop的核心是HDFS(分布式文件系统)和MapReduce。

分布式系统:网络互连的若干计算机。

分布式计算:分布式系统上执行的计算,将任务分解,然后合并计算结果。

 二、HDFS

特点:1. 海量数据存储;2.文件分块存储到不同计算机上;3.高容错性(每个数据块都有备份),1T的数据要用3T的空间存储。

HDFS是 master/slave 架构,一个HDFS集群是有一个NameNode 和多个DataNoe节点,NameNode负责管理文件的命名空间、客户端对文件的访问,NameNode执行文件系统的namespace操作,例如打开、关闭、重命名文件和目录,同时决定block到具体Datanode节点的映射。DataNode负责管理节点上的存储、读写,Datanode在Namenode的指挥下进行block的创建、删除和复制。

2.1 HDFS写流程

有一个文件FileA,100M大小。Client将FileA写入到HDFS上。

HDFS按默认配置。

HDFS分布在三个机架上Rack1,Rack2,Rack3。

a. Client将FileA按64M分块。分成两块,block1和Block2;

b. Client向nameNode发送写数据请求,如图蓝色虚线①------>。

c. NameNode节点,记录block信息。并返回可用的DataNode,如粉色虚线②--------->。

    Block1: host2,host1,host3

    Block2: host7,host8,host4

    原理:

        NameNode具有RackAware机架感知功能,这个可以配置。

        若client为DataNode节点,那存储block时,规则为:副本1,同client的节点上;副本2,不同机架节点上;副本3,同第二个副本机架的另一个节点上;其他副本随机挑选。

        若client不为DataNode节点,那存储block时,规则为:副本1,随机选择一个节点上;副本2,不同副本1,机架上;副本3,同副本2相同的另一个节点上;其他副本随机挑选。

d. client向DataNode发送block1;发送过程是以流式写入。

    流式写入过程,

        1>将64M的block1按64k的package划分;

        2>然后将第一个package发送给host2;

        3>host2接收完后,将第一个package发送给host1,同时client想host2发送第二个package;

        4>host1接收完第一个package后,发送给host3,同时接收host2发来的第二个package。

        5>以此类推,如图红线实线所示,直到将block1发送完毕。

        6>host2,host1,host3向NameNode,host2向Client发送通知,说“消息发送完了”。如图粉红颜色实线所示。

        7>client收到host2发来的消息后,向namenode发送消息,说我写完了。这样就真完成了。如图黄色粗实线

        8>发送完block1后,再向host7,host8,host4发送block2,如图蓝色实线所示。

        9>发送完block2后,host7,host8,host4向NameNode,host7向Client发送通知,如图浅绿色实线所示。

        10>client向NameNode发送消息,说我写完了,如图黄色粗实线。。。这样就完毕了。

分析,通过写过程,我们可以了解到:

    写1T文件,我们需要3T的存储,3T的网络流量贷款。

    在执行读或写的过程中,NameNode和DataNode通过HeartBeat进行保存通信,确定DataNode活着。如果发现DataNode死掉了,就将死掉的DataNode上的数据,放到其他节点去。读取时,要读其他节点去。

    挂掉一个节点,没关系,还有其他节点可以备份;甚至,挂掉某一个机架,也没关系;其他机架上,也有备份。

 参考:https://www.cnblogs.com/laov/p/3434917.html

2.2 HDFS读流程

读操作就简单一些了,如图所示,client要从datanode上,读取FileA。而FileA由block1和block2组成。 

那么,读操作流程为:

a. client向namenode发送读请求。

b. namenode查看Metadata信息,返回fileA的block的位置。

    block1:host2,host1,host3

    block2:host7,host8,host4

c. block的位置是有先后顺序的,先读block1,再读block2。而且block1去host2上读取;然后block2,去host7上读取;

2.3 Hadoop作业提交

参考:https://blog.csdn.net/hongchenlingtian/article/details/53524705

RM是Resource Manager,任务调度处理中心,NM是NodeManager,maptask 和 reducetask 实施中心。

1.Client中,客户端提交一个mr的jar包给JobClient(提交方式:hadoop jar ...)

2.JobClient持有ResourceManager的一个代理对象,它向ResourceManager发送一个RPC请求,告诉ResourceManager作业开始,
然后ResourceManager返回一个JobID和一个存放jar包的路径给Client

3.Client将得到的jar包的路径作为前缀,JobID作为后缀(path = hdfs上的地址 + jobId) 拼接成一个新的hdfs的路径,然后Client通过FileSystem向hdfs中存放jar包,默认存放10份
(NameNode和DateNode等操作)

4.开始提交任务,Client将作业的描述信息(JobID和拼接后的存放jar包的路径等)RPC返回给ResourceManager

5.ResourceManager进行初始化任务,然后放到一个调度器中

6.ResourceManager读取HDFS上的要处理的文件,开始计算输入分片,每一个分片对应一个MapperTask,根据数据量确定起多少个mapper,多少个reducer

7.NodeManager 通过心跳机制向ResourceManager领取任务(任务的描述信息)

8.领取到任务的NodeManager去Hdfs上下载jar包,配置文件等

9.NodeManager启动相应的子进程yarnchild,运行mapreduce,运行maptask或者reducetask

10.map从hdfs中读取数据,然后传给reduce,reduce将输出的数据给回hdfs

2.4 Hadoop常用Linux命令

http://hadoop.apache.org/docs/r1.0.4/cn/hdfs_shell.html

例如:Hadoop fs -cat 文件路径

注意:Hadoop命令需要安装,默认指向hadoop工具包

hadoop命令:https://www.cnblogs.com/feong/p/5148361.html
查看指定目录下内容:hadoop fs -ls [/production/ecom/adslog/(文件目录)]
将本地文件夹存储至hadoop上:hadoop fs -put [本地目录] [hadoop目录]
在hadoop指定目录内创建新目录:hadoop fs -mkdir [目录地址]
在hadoop指定目录下新建一个空文件,touchz命令:hadoop fs -touchz /test_put_dir/test_new_file.txt
打开某个已存在文件:hadoop fs -cat [file_path]
将hadoop上某个文件重命名:hadoop fs -mv [旧文件名] [新文件名]
将hadoop上某个文件down至本地已有目录下:hadoop fs -get [文件目录] [本地目录]
删除hadoop上指定文件:hadoop fs -rm [文件地址]
删除hadoop上指定文件夹(包含子目录等):hadoop fs -rm -r [目录地址]
将hadoop指定目录下所有内容保存为一个文件,同时down至本地:hadoop dfs -getmerge /user /home/t
将正在运行的hadoop作业kill掉:hadoop job -kill [job-id]


三、MapReduce

参考:https://www.cnblogs.com/firstsheng618/p/9022879.html

 MapReduce是一种变成模型,用于大规模数据集的并行运算。Map和Reduce都是按照键值对来处理的,有一个shuffle过程,将Map的输出按键排序,放到合适的区间,再交给Reduce处理。

MapReduce计算模型主要由三个阶段构成:Map、Shuffle、Reduce。Map是映射,负责数据的过滤分类,将原始数据转化为键值对;Reduce是合并,将具有相同key值的value进行处理后再输出新的键值对作为最终结果;为了让Reduce可以并行处理Map的结果,必须对Map的输出进行一定的排序与分割,然后再交给对应的Reduce,这个过程就是Shuffle。Shuffle过程包含Map Shuffle和Reduce Shuffle。

3.1 Map Shuffle

在Map端的shuffle过程就是对Map的结果进行分区、排序、分割,然后将属于同一个分区的输出合并在一起并写在磁盘上,最终得到一个分区有序的文件。分区有序的含义是Map输出的键值对按分区进行排列,具有相同partition值的键值对存储在一起,每个分区里面的键值对又按key值进行升序排序(默认),大致流程如下:

3.2 Reduce Shuffle

  • Map --> Task Tracker --> Job Tracker:map任务完成
  • Reduce --> Job Tracker --> 开启reduce任务: 获取Map的输出位置

Reduce任务通过HTTP向各个Map任务拖取它所需要的数据。Map任务成功完成后,会通知父TaskTracker状态已经更新,TaskTracker进而通知JobTracker(这些通知在心跳机制中进行)。所以,对于指定作业来说,JobTracker能记录Map输出和TaskTracker的映射关系。Reduce会定期向JobTracker获取Map的输出位置,一旦拿到输出位置,Reduce任务就会从此输出对应的TaskTracker上复制输出到本地,而不会等到所有的Map任务结束。

  • Map结果 --> Reduce --> 内存 --> 内存达到限度 --> 内存Merge --> 磁盘文件

Copy过来的数据会先放入内存缓冲区中,如果内存缓冲区中能放得下这次数据的话就直接把数据写到内存中,即内存到内存merge。Reduce要向每个Map去拖取数据,在内存中每个Map对应一块数据,当内存缓存区中存储的Map数据占用空间达到一定程度的时候,开始启动内存中merge,把内存中的数据merge输出到磁盘上一个文件中,即内存到磁盘merge。在将buffer中多个map输出合并写入磁盘之前,如果设置了Combiner,则会化简压缩合并的map输出。Reduce的内存缓冲区可通过mapred.job.shuffle.input.buffer.percent配置,默认是JVM的heap size的70%。内存到磁盘merge的启动门限可以通过mapred.job.shuffle.merge.percent配置,默认是66%。

  • map输出全部完成 --> Reduce生成多个文件 --> 文件合并

当属于该reducer的map输出全部拷贝完成,则会在reducer上生成多个文件(如果拖取的所有map数据总量都没有内存缓冲区,则数据就只存在于内存中),这时开始执行合并操作,即磁盘到磁盘merge,Map的输出数据已经是有序的,Merge进行一次合并排序,所谓Reduce端的sort过程就是这个合并的过程。一般Reduce是一边copy一边sort,即copy和sort两个阶段是重叠而不是完全分开的。最终Reduce shuffle过程会输出一个整体有序的数据块。

3.3 MapReduce中的分组排序 GroupBy

itertools.groupby() 方法

https://docs.python.org/2/library/itertools.html#itertools.groupby

itertools提供操作迭代对象的函数,主要用到groupby()方法操作迭代器。

参数:iterable,可迭代的对象,比如文件、列表

key=keyfunc,分组函数, 默认为 lambda x:x,可以用itemgetter()指明按第几列分组

使用:文件按列分号,并按照某A列排序,读取文件并按A分组,再处理A分组里的内容

import itertools
from operator import itemgetter
def read_file():
  for line in sys.stdin:
    fields = line.strip().split('\t')
    yield fields
    
def mapper():
  readin = read_file()
  for key, group in itertools.groupby(readin, itemgetter(2)):
    print key
    for g in group:
      print g  

 

 

 

weixin073智慧旅游平台开发微信小程序+ssm后端毕业源码案例设计 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。 1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md或论文文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。 5、资源来自互联网采集,如有侵权,私聊博主删除。 6、可私信博主看论文后选择购买源代码。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值