一.hdfs架构原理
一.架构设计理念:
1)支持超大数据集
hdfs分布式存储,定位针对超大数据集,比如30亿数据,每台机器存储大数据集的一部分
(2)应对硬件故障
大数据的理念,是不需要使用商用小型机,服务器,商用设备
大数据系统就部署在普通机器上就行了,比如16核64G的物理机
一般部署几十台、几百台、几千上万台机器都有可能
普通机器硬件容易出现故障,hdfs的理念是可以自动探查集群中某台集群出现故障,自动对故障进行恢复,而且速度比较快
(3)流式数据处理
hdfs读写文件系统上的数据的时候,是基于流的一种概念来的,英文名词是:streaming access。
hdfs用这个所谓的流式数据处理,其实主要就是为了保证高吞吐量的文件读写,而不是低延迟的文件读写。
hdfs是用在离线批处理场景的,尤其是数据仓库,数据分析这块。今天凌晨把昨天所有的数据都给在比如半小时内处理完毕。而不是数据来一条你就算一条
(4)简化的数据一致性模型
同时支持文件的读和写会有大量的并发冲突问题,非常麻烦
hdfs为了支持超大数据集,分布式存储,离线批量处理,它的数据一致性模型是简化的,一个文件只能一次写入,然后之后只能追加,不能随便修改之前的数据
它的理念是write-once,ready-many-times,一次写,然后多次读,这样就没有数据读写并发冲突,以及数据如何维护一致性的问题了
(5)尽量移动计算,但是不要移动数据
你要对分布在多台机器上的数据,进行分布式计算,使用比如mapreduce或者是spark都可以,那么此时尽可能让你的计算任务是靠近这个数据,而不是说在集群里通过网络胡乱传输数据,那样会导致性能极差极差
用一张图来表示架构设计理念
二.master-slave模式的分布式存储架构
hdfs分布式系统架构,是一种master-slave模式
hdfs里面有一个namenode进程,就是master,在集群里担任指挥中心的角色吧
还一个datanode进程,每台机器上面都有一个datanode进程负责存储这台机器的数据
namenode主要存放文件系统命名空间:filesystem namespace,每个文件都有一个目录,这里也就是存储文件目录树
一个大文件会被拆分成多个小文件,默认一个小文件128MB,也就是1G的文件会被拆成8个128MB的小文件叫block文件块,8个block存储在不同的datanode节点上面
存储文件的时候会先经过namenode,计算block应该存在哪台datanode上面,读取的时候也先经过namenode要从哪台机器上面读取文件,然后各自从datanode通信,获取数据再合并成一个大文件
用一张图片来表示master-slave模式的分布式存储架构
三.元数据管理机制
hdfs文件系统中有很多命令
hadoop fs -mkdir -p /user/dir01,创建一个目录层级结构
hadoop fs -rmr,删除目录,mv、cp
hadoop fs -put可以上传本地的大文件到hdfs上去,hadoop fs -get可以将hdfs上的文件给下载下来
那么namenode中存储了文件目录,文件->bolck->在哪个datanode上面,namenode管理元数据
两个很重要的文件edtislog、fsimage
editslog:每条指令都会修改内存中的元数据,然后写一个log到editslog文件中,editslog记录了操作日志
fsimage:存储元数据信息
刚开始fsimage是空的,每条指令都会写editslog文件,隔一段时间以后会将editslog和fsimage文件读到内存,然后从editslog回放数据合并到fsimage文件中后把fsimage写回磁盘,把editslog文件删除,这个操作叫checkpoint
可以通过dfs.namenode.checkpoint.period参数配置多久执行一次checkpoint
通过dfs.namenode.checkpoint.txns参数配置editslog中有多少条数据的时候执行一次checkpoint
namenode重启的时候,会将editslog和fsimage读到内存中,然后合并数据加载到内存中,然后删除editslog文件
大概原理是这样,里面还有很多细节,后面源码分析的时候会讲,比如每次操作都写磁盘editslog这样太慢了,用的双buffer等
用一幅图来表示现在master-slave模式的分布式存储架构、元数据管理机制
四:hadoop 1.x中的SecondaryNameNode
在上面的机制中,checkpoint的时候导致namenode卡顿,namenode启动的时候,editslog数据太多导致启动过慢,所有hadoop 1.x中有一个SecondaryNameNode机制。
有一个secondary namenode角色,一般独立部署一台机器,专门做editslog和fsimage合并的
每隔一段时间secondary namenode就会通知namenode写到new editslog文件,然后secondary namenode把namenode的editslog和fsimage拉到自己本地,然后合并一个新的fsimage文件然后发到namenode上去,然后namanode把new editslog变成editslog文件,secondary namenode也可以作为冷备,也叫checkpoint node,默认一个小时执行一个checkpoint,或者edtislog达到64mb执行一次checkpoint
用一幅图来表示现在master-slave模式的分布式存储架构、元数据管理机制、SecondaryNameNode
五:hadoop 1.x中的BackupNode
backupnode是namenode收到数据以后直接发到backupnode节点,backupnode在内存中维护一份一样的数据,然后由backupnode节点做checkpoint节点,这样可以让namenode节点不需要写editslog了
然后每次namenode重启的时候,要用-importCheckpoint指令,从其他地方去加载fsimage数据到自己内存中来,dfs.namenode.name.dir指定一个目录,这个目录必须是空目录,然后指定一个dfs.namenode.checkpoint.dir专门用来加载fsimage文件,然后启动namenode,使用-importCheckpoint就行了
用一幅图来表示现在master-slave模式的分布式存储架构、元数据管理机制、SecondaryNameNode、BackupNode
六:hadoop 2.x中的双实例HA高可用机制
有了SecondaryNameNode和BackupNode机制以后,namenode还是可能会丢数据,并且namenode没有高可用,所以hadoop 2.x中有了namenode双实例HA高可用机制,集群中会有两个namenode实例,一个是active状态,一个是standby状态,一个是主,一个是备。所有操作都是发送给active,standby不停的拉数据,作为热备
集群中还会引入一组journal nodes节点,一般是启动三个,用来保存editslog,每次namenode元数据变更就会发送给journal nodes节点,超过半数journal nodes节点发送成功,这个元数据才算安全的,也就是3个journal nodes节点要两个都发送成功了
standby namenode会监控着journal nodes中的editslog变更,拉到自己内存来形成一个和active namenode一样的fsimage
如果active namenode宕机了,standby namanode能立马感知到,然后确定自己读取了journal nodes的所有editslog之后,将自己切换为active namenode,namenode的数据是不会丢的,也实现了高可用
datanode配置了两天namenode会将数据上报给两个namenode
那么两台namenode是如何在故障的时候自动faillover的呢?靠的是ZKFC两个进程,就是每个namenode机器上都要跑一个ZKFailoverController的进程,简称之ZKFC,他们俩会不断的监控两个namenode,同时在zookeeper集群上(至少3个节点)维护namenode的状态
如果active namenode挂了,那么ZKFC里的也给HealthMonitor就会监控到,然后就会告诉ZKFC里的一个FailoverController通知说namenode挂了,接着FailoverContrller找ActiveStandbyElector组件说要主备重新选举
ActiveStandbyElector就会基于zk集群完成主备选举,这个过程就不说了,总之会选举出来standby namenode作为主的
然后zk会通知standby机器上的ZKFC中的ActiveStandbyElector组件,ActiveStandbyElector通知FailoverController要切换standby为active了,然后FailoverController再通知standby namenode切换为active namenode
而且journal nodes还仅仅只允许一台namenode给他写edits log,就是为了避免脑裂问题,两台namenode的网络环境不通了,他们俩都以为自己是active往journal nodes写数据,此时只能有一台写
这套架构中元数据管理是standby namenode做的,它拥有完整的数据,由standby namenode进行checkpoint,生成fsimage然后推送到active namenode节点上去
用一幅图来表示现在master-slave模式的分布式存储架构、元数据管理机制、SecondaryNameNode、BackupNode、双实例HA高可用机制
七:大文件分布式存储机制及多副本机制
上面都是介绍namenode存储,datanode是实际存储数据的,一个大文件会被拆分为多个block分开存储在不同机器上,默认一个文件128MB,也就是1个1G的文件会被拆分为8个block存储了不同的机器上面。
datanode每次启动的时候,都会扫描文件系统里的数据然后生成一份自己本地保存了哪些block的list数据,然后报告给namenode,namenode会做一些同步比对、校验啊之类的事情的。
并且实现数据的高可用,有多副本机制,默认是3个副本,hdfs考虑到机架的概念,一个机架上面两台机器,还一台机器在另一个机架上面,hdfs担心整个机架的机器都宕机了,还有副本,所以默认3个副本,当某个副本挂了以后,集群会感知到就会产生复制任务,再次复制一个副本出来
写入一个文件的时候namenode通过复制算法挑选出3台机器,写到一台机器上面,如果这台机器复制到第二台,然后第二台复制到第三台
用一幅图来表示现在master-slave模式的分布式存储架构、元数据管理机制、SecondaryNameNode、BackupNode、双实例HA高可用机制、分布式存储机制及多副本机制
八:安全模式
安全模式的机制,是在namenode刚启动的时候,就会进入一个模式,叫做安全模式,safe mode,在这个模式下,hdfs集群是不会进行block的复制的
这个时候namenode会等着从各个datanode获取心跳和block report,然后看看集群里的整体的block情况,以及每个block有几个副本,默认是要有3个副本的。如果一个block有3个副本,那么就ok了,安全了
如果一定比例(80%)的block都是有足够的3个副本的,那么namenode就会退出安全模式,namenode一直处于safe mode状态下,就是因为没有达到一定的比例,block是足够的3个副本的,只有50%的block是有3个副本的
此时如果发现有某个block副本数量不够(比如只有2个副本)的,就指示datanode复制足够的副本数量,那么就ok了
九:集群节点故障容错机制
(1)集群节点故障
网络分区,network partition,及群里网络故障了,datanode和namenode不能通信了,网络环境被分成了两块
datanode会定时发送心跳以及block report到namenode去,那如果网络分区了,namenode肯定会感知到的,因为一部分datanode心跳没发送过来了
这个时候namenode就会将这些无法发送心跳的datanode标记为dead状态,已经死掉了,然后就不会再让hdfs客户端去读写那些datanode了。默认是10min接收不到心跳才会标记datanode死掉了。而且这个时候datanode上的一些block不就不可用了么?这个时候namenode会检测到,然后会发现一些block的replica副本就不够了,那么此时namenode就会让其他的datanode去复制一些replica保证3副本
除了这种网络分区以外,还有别的一些故障,比如说datanode所在机器宕机了,或者datanode进程就挂了,或者是那个block对应的文件损坏了,都会让namenode感知到,此时namenode会自动在集群里复制block,保证每个block的三副本
(2)数据破损
hdfs的数据完整性校验机制,在一个客户端上传一个文件到hdfs的时候,其实是会基于文件内容算一个校验和出来的,就是checksum,放到一个隐藏文件里去,也是在hdfs里的,然后在读取文件内容的时候,会对读取到的文件内容重新算一个校验和,与之前上传时的校验和比对一下,如果不一样说明文件破损了,此时他会尝试对某个block读取其他的副本
(3)元数据文件损坏
fsimage和edits log都是非常关键的元数据,如果这些文件损坏了,那么hdfs可能就无法正常工作了,如果要保护这个namenode的可用性,可以使用namenode HA部署双机进行热备,出现故障自动切换namenode
hdfs整体架构和原理就完毕了,记住上面这张图,了解整体运行机制,有些细节没有描述,源码分析的时候再仔细看看