HDFS分布式文件系统

2003、2004年谷歌发表的两篇论文:

分布式文件系统(GFS),可用于处理海量网页的存储。

分布式计算架构mapreduce,用于处理海量网页的索引计算问题。

hadoop 的三大模式 hadoop最主要的三个模块_hadoop 的三大模式


hadoop由三个模块组成:

分布式存储HDFS 分布式计算MapReduce 资源调度引擎Yarn

hadoop 的三大模式 hadoop最主要的三个模块_数据_02


关键词:分布式 主从架构

HDFS模块:

namenode:主节点,主要负责集群的管理以及元数据信息管理(整个文件系统的元数据,以及每个路径文件所对应的数据块信息)
datanode:从节点,主要负责存储用户数据
secondaryNameNode:辅助namenode管理元数据信息,以及原始及信息的冷备份(每隔一段时间获取HDFS元数据的快照)

Yarn模块:

ResourceManager:主节点,主要负责资源分配
NodeManager:从节点,主要负责执行任务

hadoop 的三大模式 hadoop最主要的三个模块_大数据_03


保存文件到HDFS时,会按照128M的大小对文件进行切分成block块,以块的形式存储到HDFS文件管理系统中。

block 默认128M 配置文件hdfs-site.xml,每个block块的元数据大小为150字节。

<property>
    <name>dfs.blocksize</name>
    <value>块大小 以字节为单位</value><!-- 只写数值就可以 -->
</property>
   <property>
          <name>dfs.replication</name>
          <value>3</value>#副本默认数量
    </property>

如果一个文件大小为1KB,也要占用一个block块,但是实际占用磁盘空间还是1KB

block的好处:

文件可能大于集群中任何一个磁盘

使用块抽象而不是文件可以简化存储子系统

块非常适用于数据备份,提供数据容错能力和可用性

hadoop 的三大模式 hadoop最主要的三个模块_hdfs_04

豆知识:

块缓存:通常DataNode从磁盘中读取块,但是对于频繁访问的块可能被显式的缓存在内存中,以堆外缓存的形式存在。
默认条件下,一个块仅缓存在一个DataNode的内存中,可以针对每个文件配置DN的数量,作业调度器通过缓存在DN上运行任务,利用块缓存的优势提高读操作的性能。
连接(join)操作使用一个小的查询表就是块缓存的很好候选。用户或者应用通过在缓存池中增加一个cache directive 告诉nd需要缓存那些文件及存多久,cache pool缓存池是一个拥有管理权限和资源使用的管理性分组。
文件权限验证
r:read w:write x:execute权限x对于文件表示忽略,对于文件夹表示是否有权限访问其内容。防止好人做错事。

hdfs的shell命令

输入hadoop fs 或者hdfs dfs回车,可以查看所有的HDFS命令
学会使用help ,比如查看ls命令的使用说明 hadoop fs -help ls

#两种风格hadoop fs开头的和hdfs dfs开头的
#ls
hdfs dfs -help ls
hadoop fs -help ls 
#查看hdfs文件系统中指定目录的文件列表
hdfs dfs -ls /
hadoop fs -ls /
hdfs dfs -ls -R / 递归
#在hdfs文件系统中创建文件
hdfs dfs -touchz /edits.txt
#向HDFS文件中追加内容
hadoop fs -appendToFile edit1.xml /edits.txt#将本地磁盘当前目录的edit1.xml内容追加到HDFS根目录的edit.txt文件。
#查看HDFS文件内容
hdfs dfs -cat /edits.txt
hdfs dfs -text ./edits.txt
#从本地路径上传文件到HDFS
hdfs dfs -put /linux本地路径 /hdfs路径
hdfs dfs -copyFromLocal /linux本地磁盘文件 /hdfs路径文件
hdfs dfs -moveFromLocal /linux本地磁盘文件 /hdfs路径文件 #这个源文件会被删除
#在hdfs文件系统中下载 文件
hdfs dfs -get /hdfs路径 /本地路径
hdfs dfs -copyToLocal /hdfs路径 /本地路径 
#在hdfs文件系统中创建目录
hdfs dfs -mkdir /shell
#在hdfs文件系统中删除文件
hdfs  dfs -rm /edits.txt
###将文件彻底删除 不放在hdfs的垃圾桶中
hdfs dfs -rm -skipTrash /xcall
#在hdfs文件系统中修改文件名称(也可用于移动文件到目录)
hdfs dfs  -mv /xcall.sh /call.sh
hdfs dfs -mv /xcall.sh /shell
#在hdfs中拷贝文件到目录
hdfs dfs -cp /xrsync.sh /shell
#递归删除目录
hdfs dfs -rm -r /shell
#查找本文的内容(默认是hdfs文件系统)
hdfs dfs -ls file:///home/hadoop/
#查找文件
hadoop fs -find / -name part-r-00000 #在HDFS的根目录下,查找part-r-00000文件
##########linux find 命令
find .-name 'edit*'
hdfs安全模式

文件系统只接受读请求,不接受写请求,如删除,修改等。
在namenode启动的时候会向namenode汇报可用的block等状态,等整个系统达到安全标准是,hdfs会自动离开安全模式。
如果HDFS处于安全模式下,则block不能进行任何的副本复制操作,因此要达到最小的副本数量要求是基于datanode启动的状态来判断的。
默认启动时前30s在安全期中,过了30s之后,脱离了安全期,才对集群进行操作。
何时退出安全模式:
namenode知道集群共有多少个block(不考虑副本),假设值是total;
namenode启动后,会报上block report,namenode开始积累加统计满足最小副本数(默认1)的block个数,假设是num
当num/total>99.9%时,退出安全模式

NameNode&SecondaryNameNode

元数据需要高效的检索, 放在内存中, 为了安全持久,元数据做可靠的持久化,将所有的 元数据信息保存在FSImage文件中,随着时间推移膨胀,元数据操作日志edits文件,记录操作信息,随着时间推移也会变大,所以引入了SecondaryNamenode来做文件合并。

namenode工作机制
第一次启动时,创建edits和fsimage文件,如果不是第一次启动,直接加载编辑日志和镜像文件到内存
客户端对元数据进行增删改操作
namenode记录操作日志,更新日志,在内存中对数据进行增删改查
second namenode工作机制
询问namenode是否需要checkpoint,返回结果。事务大于一定程度或者隔一段时间请求执行checkpoint,nn滚动正在写的edits文件,将滚动前的日志和镜像文件拷贝到secondary namenode的内存中,合并。生成新的fsimage.chkpoint到namenode,重新命名为fsimage

客户端对hdfs进行写文件时,首先会被记录在edits文件中,每次hdfs更新时,edits先更新后,客户端才能看到最新的消息。fsimage是namenode中关于元数据的镜像,一般称为检查点。操作先放在edits的原因是,fsimage是nn的完整镜像,内容大,耗费内存和CPU。fsimage内容包含了namenode管理下的所有dn和block的运输局,随着edits内容增大,需要在一定时间带你和fsimage合并。

元数据信息多目录配置
为了保证数据的安全性,将元数据的磁盘做RAID1,本地目录可以配置成多个,且每个目录存放内容相同,增加了可靠性,逗号分隔

<property>
   <name>dfs.namenode.name.dir</name>
   <value>file:///*/namenodeDatas,file:///path/to/another/</value>
</property>

补充

优点

高容错
适合批处理:移动计算而不是移动数据,把数据位置暴露给计算框架。
适合大数据处理
流式数据访问:一次写入,多次读取,不能随即修改,只能增加。保证数据一致性。

缺点

不适合低延时数据访问。
适合高吞吐率的场景,就是一次写入大量的数据。
无法高效的对大量小文件继续存储(寻道>读取),违反了HDFS的设计没目标。
并发写入,文件随机修改。文件只能一个写,不能多个线程同时写,仅支持数据追加append,不支持文件的随机修改。

MapReduce计算框架初探

分布式i运算程序的编程框架

核心功能:核心功能是将用户编写的业务逻辑代码和自带默认组件组合成一个完整的分布式运算程序,并发运行在hadoop集群上。

hadoop 的三大模式 hadoop最主要的三个模块_大数据_05

map阶段2个步骤

1 设置inputFormat类,将数据切分成key value对,输入第二步。
2 自定义map逻辑,处理第一步的始输入kv对,转成新的key,value对进行输出。

shuffle阶段的4个步骤

3 对上一步输出的kv对进行分区,相同key的kv对属于同一分区。
4 对每个分区的数据按照key进行排序
5 对分区中的数据进行规约(combine)降低数据的网络拷贝
6 对排序后的kv对进行分组,k相同的kv为一组,将同一组的kv对的所有value放到一个集合当中。(每组数据调用一次reduce方法)

reduce阶段2个步骤

7 对多个map的让人物进行合并,排序,写reduce函数自己的逻辑,对输入的key,value对进行处理,转换诚信的key value对进行输出
8 设置将输出的key value对数据保存到文件中

hadoop的序列化和反序列化

序列化就是把内存中的对象转换成字节序列或者其他数据传输协议,以便存储到磁盘(持久化)和网络传输。

反序列化就是将收到的字节序列或者其他传输协议,或者磁盘的持久化数据转换成内存中的对象。

hadoop 的三大模式 hadoop最主要的三个模块_hadoop 的三大模式_06


在运行MapReduce程序时,有多个mapTask运行,在MapReduce中,每个mapTask处理一个切片spllit的数量,只是在逻辑上对输入进行分区,并不会在磁盘上切分进行存储。

控制maptask的个数:

控制maptask的个数只需要调整maxSize和minSize,maxsize(切片最大值)如果比blocksize小,切片会变小,等于参数值。minsize(切片最小值),参数比blocksize大,可以让切片比blocksize大。

mapreduce中的排序

maptask和reducetask均会对数据按照key进行排序,任何应用程序中的数据都会被排序,不管逻辑上是否需要。
默认排序式按照字典顺序进行排序,实现的方法是快速排序。
对于map task会将处理的结果暂时存放在环形缓冲区,达到阈值后,对缓冲区的数据进行一次快速排序,并写到磁盘。数据处理完毕后,对磁盘上的所有文件进行归并排序。
对于reducetask,文件大小超过一定的阈值,进行一次归并排序生成更大文件,如果内存中文件的大小或者数目超过一定阈值,进行一次合并后将数据写到磁盘上,所有数据拷贝完毕后,reduce统一对内存和磁盘上的所有数据进行一次归并排序。

mapreduce中的combiner

conbiner本质也是reduce聚合,combine类继承reducer父类。
combine是运行到map端的,对map task的结果做聚合,reduce是将来自不同的map reduce的数据做聚合。
作用:
combine可以减少map tassk落盘以及向reduce task传输的数据量

mapreduce task工作机制

1 read阶段 map task通过用户编写的recordreader,从输入inputsplit中解析出一个个kv。
2 map阶段 该节点主要是将解析出的kv对交给用户编写的map函数处理,并产生一系列的kv。
3 collect收集阶段 在用户编写map函数中,当数据处理完成时,一般会调用outputcollector.collect()输出结果。在该函数内部,将生成的kv分区(调用partitioner),并写入一个环形内存缓冲区。
4 spill阶段:即“溢写”,当环形缓冲区80%后,将数据写在本地磁盘上,生成一个临时文件,写入之前进行一次本地排序,并在必要时对数据进行合并压缩等操作。

详情
1 利用快速排序算法对缓存区内的数据进行排序,先按照分区编号partiton进行排序,然后再按照key进行排序,排序后,数据以分区为单位i聚集在一起。
2 按照分区编号由小到大依次将每个分区中的数据写入任务工作目录下的临时文件output/spillN.out(N当前溢写的次数)中,如果用户设置了combiner,则在写入文件之前,对每个分区中的数据进行一次聚集操作。
3 当分区数据的元信息写在内存索引数据结构spillrecord中,其中每个分区的元数据包括,在临时文件中的偏移量、压缩前数据大小和压缩后数据大小。如果当前内存索引大小超过1Mb,则将内存索引写到文件output/spillN.out.index。

5 合并阶段:当所有数据处理完成后,maptask对所有临时文件进行一次合并,以确保最终只生成一个数据文件。

当所有数据处理完后,maptask会将所有临时文件合并成一个大文件,并保存到文件output/file.out中,同时生成相应的索引文件output/file.out.index。
在进行文件合并过程中,maptask是以分区为单位进行合并,对于某个分区,将采用多轮递归合并的方式,每轮合并io.sort.factor(默认10)个文件,并将产生的文件重新加入待合并列表中,对文件排序后,重复以上过程,直到最终得到一个大文件。
让每个maptask最终只生成一个数据文件,可避免同时打开大量文件和同时读取大量小文件产生的随机读取带来的开销。

reduce****
6 copy阶段:reduce task从各个map task上远程拷贝一片数据,针对某一片数据,如果大小超过一定阈值,就写在磁盘上,否则放在内存中。
7 merge阶段: 在远程拷贝数据的同时,启动两个后台线程对内存和磁盘上的文件进行合并,以防止内存使用过多或磁盘上文件过多。
8 sort阶段:当所有的map task的分区数据全部拷贝完,按照mapreduce语义,编写reduce函数输入数据就是按照key继续聚集的一组数据,因为各个map task已经实现了局部排序,因此reduce task只需要对所有数据进行一次归并排序。
9 reduce阶段:进行groupingcomparator分组操作,将计算结果写在hdfs上,一个reduce task对应一个结果文件。

mapreduce的InputFormat

InputFormat是mapreduce中用于处理数据输入的一个组件,是最顶级的一个抽象父类。

hadoop 的三大模式 hadoop最主要的三个模块_HDFS_07

YARN资源调度框架

主从结构(master/slave)架构
ResourceManager主节点master
NodeManager从节点slave

ResourceManager

全局的资源管理器,集群中只有一个active对外提供服务
负责整个系统的资源管理和分配
处理客户端请求
启动/监控 applicationmaster
监控nodemanager 资源分配与调度
组件:

调度器(Scheduler)
“纯调度器”,根据队列、容量等限制条件将系统中的资源Container分配给各个正在运行的应用程序。
应用程序管理器(Applications Manager,ASM)
管理整个系统中所有应用程序,接收job的提交请求,为应用分配第一个Countainer来运行ApplicationMaster,监控,失败重启。

NodeManager

节点启动时,向RM注册并告知自己有多少资源可用。通过心跳上报节点的资源状态。
管理监控资源,管理日志,处理来自applicationn master的请求。

Container

YARN中的资源抽象,动态资源划分单位。仅支持CPU和内存两种资源。
是以Container为单位分配资源的,封装了某个节点上的多维资源。
一个nodemanager节点可以运行多个container,但是一个container不会跨节点
任何一个job或者application必须运行在一个或者多个container中
resource manager只负责告诉application master哪些containers是可以用的。application master还需要取nm请求分配具体的container。

Application Master

获取数据分片
为应用程序申请资源并进一步分配给内部任务
协调rm资源,通过nm监控容器
*************与rm之间的通信
核心,Yarn对整个集群进行动态资源管理
周期性向rm发送心跳,让rm确认appmaster的健康
Yarn 的动态性,就是来源于多个Application 的 ApplicationMaster 动态地和 ResourceManager 进行沟通,不断地申请、释放、再申请、再释放资源的过程。

YARN应用运行原理

应用程序提交

启动应用的applicationmaster实例

applicationmaster实例管理应用程序的执行

hadoop 的三大模式 hadoop最主要的三个模块_数据_08


步骤

1 用户将应用程序提交到resource manager上。

2 resource manager为应用程序application master申请资源,并与某个node manager通信启动第一个container,以启动对应的task。

3 application master与resource manager注册进行通信,为内部要执行的任务申请资源,一旦得到资源后,将与node manager通信,以启动对应的task。

4 所有任务运行完成后,application master向resource manager注销,整个应用程序运行结束。

hadoop 的三大模式 hadoop最主要的三个模块_HDFS_09


申请资源->启动appMaster->申请运行任务的container->分发Task->运行Task->Task结束->回收container

三种调度器

先进先出(FIFO)
容量调度(Capacity Scheduler)
公平调度(Fair Scheduler)