分布式文件系统HDFS
HDFS架构
HDFS工作机制
HDFS概念
HDFS,它是一个文件系统,用于存储文件,通过目录树来定位文件;其次,它是分布式的,由很多服务器联合起来实现其功能,集群中的服务器有各自的角色。
HDFS的设计适合一次写入,多次读出的场景,且不支持文件的修改。适合用来做数据分析,并不适合用来做网盘应用。
HDFS优缺点
优点:
1)高容错性:数据自动保存多个副本,当一个副本丢失后,可以自动回复。
2)适合大数据处理:文件规模大(个数多)、数据规模大(数据大小)
3) 流式数据访问:一次写入,多次读取,不能修改,只能追加。保证数据一致性。
4) 构建成本低:可以构建在廉价的机器上。
缺点:
1)不适合做低延迟数据访问,比如毫秒级的数据访问是做不到的。
2)无法高效的对大量小文件进行存储。
3)无法并发写入和随机修改。
对于HDFS的架构,存在以下组件:
Client ,NameNode DataNode 和SecondaryNameode
Client: 客户端
1)负责文件的切片,文件上传到HDFS的时候会把文件切分成一个个BLOCK进行上传存储
2)与NameNode进行交互,获得文件的存储位置,检查是否存在重复文件等
3)与DataNode进行交互,写入真正的数据,以及读取数据
4)提供了一些HDFS的访问命令,以及API操作
NameNode :主节点 只有一个(在没有HA的情况下)
1) 管理HDFS的命名空间
2) 管理数据块的映射信息
3) 配置副本策略
4) 处理客户端的请求
DataNode: 工作者
1)存储真正的数据(按照块进行存储)
2)执行数据块的读写操作
3)定时向NameNode进行汇报(心跳机制)
SecondaryNameNode:
SecondaryNameNode,作为nameNode的辅助节点,帮助namenode合并fsimae 与edits文件,由于SecondaryNameNode 的元数据不能与nameNode的元数据保持实时同步,所以不能作为NameNode的热备节点
HDFS 的文件块大小
HDFS 中的文件在物理上是分块存储(block),块的大小可以通过配置参数( dfs.blocksize) 来规定,默认大小在 hadoop2.x 版本中是 128M,老版本中是 64M。
HDFS 的块比磁盘的块大,其目的是为了最小化寻址开销。如果块设置得足够大,从磁 盘传输数据的时间会明显大于定位这个块开始位置所需的时间。因而,传输一个由多个块组 成的文件的时间取决于磁盘传输速率。
如果寻址时间约为 10ms,而传输速率为 100MB/s,为了使寻址时间仅占传输时间的 1%, 我们要将块大小设置约为 100MB。默认的块大小 128MB。
块的大小:10ms100100M/s = 100M
NameNode(主)
就是是Master,它相当于是一个主管(管理者)
1.管理HDFSD的名称空间
2.配置副本策略
3.管理数据块(Block)映射信息(存储一些块信息)
4.处理客户端的读写操作 NameNode就是维护着HDFS的目录树结构,NameNode(基于内内存),不会和磁盘发生交互操作,只在内 存中完成
每次Namenode启动都会加载metadata信息到内存中以便提供访问操作 NameNode中会存储着metadata有 文件权限,所属人,文件大小 ,时间,Block列表信息, Block的偏移量,位 置信息
因为NameNode为了方便操作提高效率.NameNode是基于内存的,所以会出现一个通病"掉电易失"
Namenode会记录client对Datanode的操作信息和Datanode中快信息,如果"掉电易失",无法完成对当前 信息的记录工作了
SecondaryNameNode --> 帮组NameNode做磁盘操作
存储在次磁盘中东西
metadata存储早磁盘中名字是"fsimage" 对Datanode进行擦做,增删改查操作以日志的形式记录 edits(edit log对DataNode操作日志)
DataNode(从)
是slaveNamoNode下达的命令,DataNode来进行实际的执行操作(即具体文件数据的存储) Hadoop 2.x 版本 --> 存储文件块信息都是128MB
1.存储实际的数据块 2.执行数据块的读写操作 BdataNode就是Block真正存储的地方,DataNode就是就是一个本地磁盘以文件形式存储了Block块的信 息,同时还存储Block的原数据信息文件 HDFS启动的时候 DataNode会想NameNode汇报Block块信息
DataNode通过向NameNode发送心跳信息与其保持联系(3秒),如果NameNode10分钟没有收到 DataNode的心跳信息,则认为当前DataNode已经宕机(lost),启动其他dataNode去复制当前宕机的 DataNode中所有块信息
hdfs读过程
1) 客户端通过调用FileSystem对象的open()方法来打开希望读取的文件,对于HDFS来说,这个对象是DistributedFileSystem通过使用远程调用RPC来调用namenode,以确定文件起始块的位置
2) 对于每一个块NameNode返回存有该块副本的DataNode地址
3)DistributedFileSystem类返回一个FSDataInputStream对象(该对象是一个支持文件定位的输入流)给客户端以便读取数据,接着客户端对这个输入流调用read()方法
4)FSDataInputStream随即连接距离最近文件中第一个块所在的DataNode,通过对数据流反复调用read()方法,可以将数据从DataNode传输到客户端
- 当读取到块的末端时,FSInputStream关闭与该DataNode的连接,然后寻找下一个块的最佳DataNode
- 客户端从流中读取数据时,块是按照打开FSInputStream与DataNode的新建连接的顺序读取的。它也会根据需要询问NameNode来检索下一批数据块的DataNode的位置。一旦客户端完成读取,就对FSInputStream调用close方法
在读取数据的时候,如果FSInputStream与DataNode通信时遇到错误,会尝试从这个块的最近的DataNode读取数据,并且记住那个故障的DataNode,保证后续不会反复读取该节点上后续的块。FInputStream也会通过校验和确认从DataNode发来的数据是否完整。如果发现有损坏的块,FSInputStream会从其他的块读取副本,并且将损坏的块通知给NameNode
HDFS文件写入流程
1) 客户端通过对DistributedFileSystem对象调用create()方法来新建文件
2)DistributedFileSystem对namenode创建一个RPC调用,在文件系统的命名空间中新建一个文件,此时该文件中还没有相应的数据块
3)namenode执行各种不同的检查,以确保这个文件不存在以及客户端有新建该文件的权限。如果检查通过,namenode就会为创建新文件记录一条记录,否则,文件创建失败并向客户端抛出一个IOException异常。DistributedFileSystem向客户端返回一个FSDataOuputStream对象,由此客户端可以开始写入数据,
4)在客户端写入数据时,FSOutputStream将它分成一个个的数据包,并写入内部队列,这个队列称为“数据队列”(data queue)。
FSOutputStream处理数据队列时它的责任是挑选出合适存储数据复本的一组datanode,并以此来要求namenode分配新的数据块。这一组datanode将构成一个管道,以默认复本3个为例,所以该管道中有3个节点.FSOutputStream将数据包流式传输到管道中第一个datanode,该datanode存储数据包并将它发送到管道中的第2个datanode,同样,第2个datanode存储该数据包并且发送给管道中的第三个datanode
5)datanode写入数据成功之后,会为FSOutputStream发送一个写入成功的信息回执,也称为确认队列,当收到管道中所有的datanode确认信息后,该数据包才会从确认队列中删除
如果任何datanode在写入数据期间发生故障,则执行以下操作:
1)首先关闭管道,确认把队列中的所有数据包都添加回数据队列的最前端,以确保故障节点下游的datanode不会漏掉任何一个数据包
2)为存储在另一正常datanode的当前数据块制定一个新标识,并将该标识传送给namenode,以便故障datanode在恢复后可以删除存储的部分数据块
3)从管道中删除故障datanode,基于两个正常datanode构建一条新管道,余下数据块写入管道中正常的datanode
4) namenode注意到块复本不足时,会在另一个节点上创建一个新的复本
在一个块被写入期间可能会有多个datanode同时发生故障,但概率非常低。只要写入了dfs.namenode.replication.min的复本数(默认1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数dfs.replication的数量(默认3)
SecondaryNameNode
ps:SecondaryNameName并不是NameNode的备份 SecondaryNameNode主要是负责对NameNode中fsimage和edits文件尽心合并操作,并将合并好的文 件推还给NameNode fsimage的产生有两种情况
第一种:当NameNode格式化成功后,并且启动成功会产生第一个fsimage文件(只产生一次) 第二种.已经存在fsimage文件并且NameNode启动的时候 会产生一个空的日志文件,Edits文件,这位文件 会记录着客户端对dataNode所有操作日志,SecondaryNameNode会对NameNode中产生fsimage和 Edits进行合并从操作,并产生新的fsimage文件推还给NameNode做备份使用
SecondaryNameNode 第一个就是间隔时间 默认时间 3600秒 SecondaryNameNode就会想Namenode发送CheckPoint请求
第二个就是当前edits文件大小达到1000000次(操作)
SecondaryNameNode就会想Namenode发送CheckPoint 请求
满足一个即可
可以在hdfs-site.xml 进行修改 name --> fs.checkpooint.period --> 可以修改 默认是3600
name --> fs.checkpoint.size --> 可以修改 默认是 1000000(次)
执行流程: SecondaryNameNode首先会询问NameNode是否需要CheckPoint(触发CheckPoint需要满足两个条 件中的任意一个,定时时间到和Edits中数据写满了)。直接带回NameNode是否检查结果。 SecondaryNameNode执行CheckPoint操作,首先会让NameNode滚动Edits并生成一个空的 edits.inprogress,滚动Edits的目的是给Edits打个标记,以后所有新的操作都写入edits.inprogress, 其他未合并的Edits和Fsimage会拷贝到SecondaryNameNode的本地,然后将拷贝的Edits和Fsimage 加载到内存中进行合并,生成fsimage.chkpoint,然后将fsimage.chkpoint拷贝给NameNode,重命名 为Fsimage后替换掉原来的Fsimage。NameNode在启动时就只需要加载之前未合并的Edits和Fsimage 即可,因为合并过的Edits中的元数据信息已经被记录在Fsimage中我们在搭建HDFS的时候就会有配置 文件进行设置
1.Fsimage:HDFS文件系统中元数据的一个永久性的检查点(备份),启动包含了HDFS文件系统的suoyo9u 目录和文件inode的序列化信息,md5是fsimage的验证信息码
2.edits:HDFS系统对datanode的所有的增删改(没有查)操作,就是客户端对datanode的操作记录
3.seen_txid: 文件保存的一个数字,后一个edits_的数字值 4.VERSION 版本内信息号, 相当于是当前 edits和fsimage的 版本信息
时间同步服务器
需要搭建完全分布式 或高可用的Hadoop集群,需要有一个非常严格的要求,就是所有服务器节点的时间 要是一致的
第一种就是手动修改时间 date -s “20190824 10:30:30” 第二种即是使用ntpdate命令 同不是件 ntpdate -u ntp1.aliyun.com
第三搭建时间服务器
1.需要在每台机器上安装一个命令 ntp yum install -y ntp 2.以hadoop01服务器作为时间服务器 需要对时间服务器进行配置 配置在/etc/ntp.conf ps:如果通过vi明令发现这ntp.conf是空文件,那么在确定有ntp.conf.rpmnew文件的前提下 删除当前空文件 rm -rf /etc/ntp.conf 将ntp.conf.rpmnew文件移动到当前目录下成为ntp.conf mv /etc/ntp.conf.rpmnet /etc/ntp.conf 在编辑这个即可 vi /etc/ntp.conf 在文件中第18行的位置,会出现时间同步的 范围 在配置文件语句的下面添加相同语句 restrict 10.211.55.0 mask 255.255.255.0 nomodify notrap 自己IP地址(当服务器的IP) 除了当前这个网段都不允许修改 这个0的作用代表整个IP端都能访问 10.211.55.0~255 配置文件中从 23~26行结束 所有server服务都要停止 #server 0.centos.pool.ntp.org iburst #server 1.centos.pool.ntp.org iburst #server 2.centos.pool.ntp.org iburst #server 3.centos.pool.ntp.org iburst 在这4个时间服务的前面添加# 代表被注释 不会执行 在这4个时间同步服务的下面添加 server 127.127.1.0 — > 本地时间同步点 保存退出文件即可 需要启动NTP服务 service ntpd [start|stop|restart] 重启NTP服务 service ntpd restart 其他节点 可以对当前服务器进行同步时间 ps:需要关闭其他节点 ntpd服务 service ntpd stop 以后再同不时间 不链接外网的前提下 ntpdate 时间服务器的IP地址即可
角色/服务器名称 NameNode SecondaryNameNode DataNode
hadoop01 存在
hadoop02 存在 存在
hadoop03 存在
hadoop04 存在
ps:提供一个定时器任务脚本 crontab -e 开启定 时器任务 分 小时 日 月 周 命令 */10 * * * * ntpdate 时间服务器IP地址 >> /root/ntpdate.walog crontab -r 删除了 退出或停止linux,都会消失
集群安全模式
当集群启动的时候 ,先加载NameNode,NameNode节点内部会先加载镜像文件夹到内存中,并执行Edits 日志,在进行加载和执行日志的时候,即刚刚启动时,NameNode是不会接受任何对当前进群操作的信息 的,此时NameNode处于的这种状态—>安全模式 在安全模式只下不会接受任何对集群的操作,此时若需要退出安全模式需要满足以下条件之一即可,“小 副本条件”,“Namenode会在30秒后自动退出安全模式”
如果在安全模式下处理命令
hdfs dfsadmin -safemode [get|enter|leave|wait] get—>查看安全模式 enter -->进入安全模式
leave -->离开安全模式 wati–>安全模式等待
Clouera提出了QJM/QuromJournal Manager
这是一个基于Paxos算法实现的HDFS HA方案,它给出了一种较好的解决思路和方案 (1)基本原理就是用2N+1台 JN 存储EditLog,每次写数据操作有大多数(>=N+1)返回成功时即认为 该次写成功,数据不会丢失了。当然这个算法所能容忍的是多有N台机器挂掉,如果多于N台挂掉, 这个算法就失效了。这个原理是基于Paxos算法
(2)在HA架构里面SecondaryNameNode这个冷备角色已经不存在了,为了保持standby NN时时的 与主Active NN的元数据保持一致,他们之间交互通过一系列守护的轻量级进程JournalNode。 (3)任何修改操作在 Active NN上执行时,JN进程同时也会记录修改log到至少半数以上的JN中,这时 Standby NN 监测到JN 里面的同步log发生变化了会读取 JN 里面的修改log,然后同步到自己的的目录 镜像树里面
(4)当发生故障时,Active的 NN 挂掉后,Standby NN 会在它成为Active NN 前,读取所有的JN里面 的修改日志,这样就能高可靠的保证与挂掉的NN的目录镜像树一致,然后无缝的接替它的职责,维护 来自客户端请求,从而达到一个高可用的目的。
(5)QJM方式来实现HA的主要优势:
1、不需要配置额外的高共享存储,降低了复杂度和维护成本
3、系统鲁棒性(Robust:健壮)的程度是可配置
4、JN不会因为其中一台的延迟而影响整体的延迟,而且也不会因为JN的数量增多而影响性能(因为NN 向JN发送日志是并行的)
zookeeper
zookeeper是Hadoop生态圈下的一个组件,作用于分布式协调服务,是Google提供的维护Hadoop高可用 的一个总组件,提供分布式程序的一致性服务,还提供,配置维护,域名服务,分布式同步,组服务等等 通常分布式系统中,构成一个集群的每一台机器都有自己的角色,典型集群模式是主从模式 (Master/Slave)
[外链图片转存失败(img-G1pw7n3C-1568965643753)(1567504595317.png)]
Zookeeper是一种没有主从模式的概念,Zookeeper引用了概念Leader,Flower,Observer三个角色 中,Zookeeper常用是Leader和Flower
1.最终一致性:client不论连接到哪个Server,展示给它都是同一个视图,这是zookeeper重要的性 能。第一个clinet上传了数据 其他client在访问得到的是同一个数据 2.可靠性:具有简单、健壮、良好的性能,如果消息被到一台服务器接受,那么它将被所有的服务器接 受。 3.实时性:Zookeeper保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的 信息。但由于网络延时等原因,Zookeeper不能保证两个客户端能同时得到刚更新的数据,如果需要 新数据,应该在读数据之前调用sync()接口。 4.等待无关(wait-free):慢的或者失效的client不得干预快速的client的请求,使得每个client都能有 效的等待。 5.原子性:更新只能成功或者失败,没有中间状态。 6.顺序性:包括全局有序和偏序两种:全局有序是指如果在一台服务器上消息a在消息b前发布,则在所 有Server上消息a都将在消息b前被发布;偏序是指如果一个消息b在消息a后被同一个发送者发布,a必 将排在b前面。
zkfc
Hadoop提供了ZKFailoverController角色,部署在每个NameNode的节点上,作为一个deamon进程, 简称zkfc
FailoverController主要包括三个组件:
1、HealthMonitor: 监控NameNode是否处于unavailable或unhealthy状态。当前通过RPC调用NN相 应的方法完成
2、ActiveStandbyElector: 管理和监控自己在ZK中的状态 3、ZKFailoverController 它订阅HealthMonitor 和ActiveStandbyElector 的事件,并管理NameNode 的状态
(5)ZKFailoverController主要职责:
1、健康监测:周期性的向它监控的NN发送健康探测命令,从而来确定某个NameNode是否处于健康 状态,如果机器宕机,心跳失败,那么zkfc就会标记它处于一个不健康的状态。
2、会话管理:如果NN是健康的,zkfc就会在zookeeper中保持一个打开的会话,如果NameNode同时 还是Active状态的,那么zkfc还会在Zookeeper中占有一个类型为短暂类型的znode,当这个NN挂掉 时,这个znode将会被删除,然后备用的NN,将会得到这把锁,升级为主NN,同时标记状态为 Active。
节点/服务器 NN1 NN2 DN ZK ZKFC JNN
3、当宕机的NN新启动时,它会再次注册zookeper,发现已经有znode锁了,便会自动变为Standby状 态,如此往复循环,保证高可靠,需要注意,目前仅仅支持多配置2个NN (hadoop2.x)
4、master选举:如上所述,通过在zookeeper中维持一个短暂类型的znode,来实现抢占式的锁机 制,从而判断那个NameNode为Active状态。
fsck
在HDFS中,提供了fsck命令,用于检查HDFS上文件和目录的健康状态、获取文件的block块信息和位置信息等。
具体命令介绍:
-move: 移动损坏的文件到/lost+found目录下
-delete: 删除损坏的文件
-openforwrite: 输出检测中的正在被写的文件
-list-corruptfileblocks: 输出损坏的块及其所属的文件
-files: 输出正在被检测的文件
-blocks: 输出block的详细报告 (需要和-files参数一起使用)
-locations: 输出block的位置信息 (需要和-files参数一起使用)
-move: 移动损坏的文件到/lost+found目录下
-delete: 删除损坏的文件
-openforwrite: 输出检测中的正在被写的文件
-list-corruptfileblocks: 输出损坏的块及其所属的文件
-files: 输出正在被检测的文件
-blocks: 输出block的详细报告 (需要和-files参数一起使用)
-locations: 输出block的位置信息 (需要和-files参数一起使用)
-racks: 输出文件块位置所在的机架信息(需要和-files参数一起使用)