目录
1、HDFS 2.0 双实例高可用机制
2、HDFS 2.0 元数据管理机制
3、HDFS 2.0 分布式存储机制
4、HDFS 2.0 容错机制
今天小白接着来探究hadoop2.0下,架构发生了哪些变化?前文也对1.0的架构进行了浅谈,【小白看架构 · HDFS1.0架构】,文中若有错误之处,欢迎大家留言讨论,谢谢大家。
1、双实例高可用机制
1.0的时代,基本来说,NameNode就是单机在跑的,虽然每一个NameNode都挂载着一个Secondary NameNode,但是Secondary NameNode其实就是一个冷备,它主要的职责就是在满足一定条件的情况下,去拉取NameNode的EditLog和FSImage到自己本地,进行合并,并将最新的FSImage推送给NameNode,然后NameNode就会把已经同步过的EditLog文件删除掉。
这样子的话,一旦NameNode宕机,磁盘坏了,虽然可以使用Secondary NameNode上的FSImage来启动,但其实还是会丢失checkpoin操作之前的元数据。
还有就是说,一旦NameNode宕机了,整个集群都会陷入不可用。所以,2.0时代,就出现了新的架构,双实例高可用架构。NameNode变成了俩台,引入了active 和standby的概念,一主一备,实时热备,不停地同步数据。
active NameNode 同步的过程通过一组journalnodes,来进行EditLog数据流的实时传输,并且为了保证元数据的安全,每一次日志的传输都要写入大多数journalnode机器才可以,比如3台,最少要写入3/2+1=2台。最大可能保证元数据同步成功。
standby NameNode,就监控着journalnodes,一旦有变更,就会读取EditLog,应用到自己的内存,和active NameNode的元数据保持一致。这里,当active NameNode挂掉的时候,这时候,数据不会丢失,journalnodes集群中还有部分数据,standby NameNode可以马上感知到,读取完所有数据之后,确保自己内存中数据是最新的之后,就会进行主备切换,保证集群马上就有新的主NameNode。
那么这样的主备切换,故障感知是怎么实现的呢?
每一个NameNode机器上都有一个ZKFailoverController进程,他的职责是监控NameNode进程的健康状态,并且会基于zookeeper集群来保存和维护NameNode集群的健康状态。一旦主NameNode挂了,ZKC进程中的HealthMonitor就会监控到,就会通过FailoverController去通知ActiveStandbyElector组件进行主备选举,基于zookeeper进行选举。
然后ZK集群就会选举出standby NameNode为新的主,通知standby机器上的ActiveStandbyElector组件,再通过FailoverController去进行切换。
整个过程如下图所示:
02
元数据管理机制
在这样的架构下,所有的DataNode都会配置俩台NameNode的信息,发送心跳,上报block report,这样子设计的话,主备俩台机器都能实时感知到集群中所有DataNode的状态和block的信息。
此时,checkpoint机制也会发生变化,在standby NameNode进程中,会有一个后台线程,他会定时去执行checkpoint,默认一小时或者有一百万条EditLog没有合并到FSImage中,就会触发。执行的步骤和我们上一篇文章讲到的backupNameNode很类似。
将内存中最新的那份FSimage写入到本地磁盘,并且将editlog清空,然后将最新的fsimage发送到activeNameNode上,覆盖掉原来的老fsimage,并将已经合并过的EditLog日志文件删除。
这里要说明的事,每次同步EditLog数据流的时候,journalnodes只允许一台NameNode进行写入EditLog,这样做的目的是为了防止脑裂的情况,俩台NameNode都觉得自己是主节点,都去写EditLog日志。
03
分布式存储机制
当发起写入文件的请求时,NameNode会根据文件的大小,将文件拆成多个block,每个block存储一部分数据,默认128M。NameNode会确定好哪个block放到哪一台DataNode上去,尽可能保证均衡。
DataNode接收到多个block之后,就会存到本地,根据多层级的目录去存储文件,多个层级,多个子目录,保证一个目录下文件数不会太多。这样子可以保证读取和写入的性能不会降低。
当DataNode启动的时候,都会扫描自己本地的文件系统里的各个文件数据,生成一份block相关的list数据,上报给NameNode,以便于NameNode进行文件对比,校验等操作。
04
容错机制
既然我们分成了多个block分布式存储到了多台DataNode机器,那么会不会出现某个机器宕机,磁盘损坏,导致block不可用?这种情况很有可能发生。一旦发生,一个文件的block就不完整了,客户端来读取就不能读到完整的一个文件。所以,必须要有容错机制去避免这样的问题。
副本机制,通过设置一个叫replication factor的参数,翻一下,复制因子,就是一个block复制多少个副本到其他机器,这样子,一旦某个DataNode挂了,还有某个文件的block副本在其他机器上可以正常读取使用。
比如设置3,此时namenode会先根据一个复制算法挑选出来3个datanode,每个datanode放一个block,返回给客户端了。客户端上传文件,会采用数据流动的机制去写文件,复制block。先第一个datanode写入一个block,接着datanode将这个block复制给第二个datanode,然后第二个datanode再将block复制给第三个datanode。
每隔一段时间,NameNode都会收到DataNode的心跳,和block report的上报。这样也保证了NameNode在分配DataNode写block时,可以更均衡地去分配。而且如果DataNode挂了,NameNode一段时间收不到心跳,就会标记为dead,客户端不会和这些机器交互,并且一旦发现某个文件的block的 副本数量不够了,也会让其他的DataNode机器去复制block,保证每个文件的副本数量。