Hadoop架构原理

Hadoop架构原理

HDFS

  • 它由很多机器组成,每台机器上运行一个 DataNode 进程,负责管理一部分数据。然后有一台机器上运行了 NameNode 进程,NameNode 大致可以认为是负责管理整个 HDFS 集群的这么一个进程,它里面存储了 HDFS 集群的所有元数据。
  • 一般一份大文件被拆分成128M的多个block,并且分三个副本存放。

NameNode架构原理

功能概述

  • NameNode 有一个很核心的功能:管理整个 HDFS 集群的元数据,比如说文件目录树、权限的设置、副本数的设置,等等。
  • 当用户需要上传文件的时候,先通知namenode说我要在什么目录上上传文件。

NameNode内存存储

name是内存存储的,针对假如namenode不小心宕机hdfs的处理方法:

  • namenode每次在内存中修改完元数据后,都会写一条edits log,元数据修改的操作日志存到磁盘文件中,不修改磁盘文件内容,就是顺序追加。
  • 每次nameNode重启的时候,把edits log里的操作日志读到内存里回放一下,就恢复元数据了。

针对edits log如果越来越大,导致每次重启很慢的处理方法:

  • 引入一个新的磁盘文件叫做fsimage,然后再引入一个JournalNodes 集群,以及一个 Standby NameNode(备节点)
  • 每次 Active NameNode(主节点)修改一次元数据都会生成一条 edits log,除了写入本地磁盘文件,还会写入 JournalNodes 集群。
  • 然后 Standby NameNode 就可以从 JournalNodes 集群拉取 edits log,应用到自己内存的文件目录树里,跟 Active NameNode 保持一致。
  • 然后每隔一段时间,Standby NameNode 都把自己内存里的文件目录树写一份到磁盘上的 fsimage,这可不是日志,这是完整的一份元数据。这个操作就是所谓的 checkpoint 检查点操作。
  • 然后把这个 fsimage 上传到 Active NameNode,接着清空掉 Active NameNode 旧的 edits log 文件
  • 接着 Active NameNode 继续接收修改元数据的请求,再写入 edits log,这时候的edits log就变小了
  • 如果说此时,Active NameNode 重启了,只要把从 Standby NameNode 传过来的 fsimage 直接读到内存里,这个 fsimage 直接就是元数据,不需要做任何额外操作,纯读取,效率很高!然后再把新的 edits log 里少量的几十行的修改日志回放到内存里就 OK 了!这个过程的启动就快多了。
  • 由于Active NameNode 和 Standby NameNode他们俩内存里的元数据几乎是一模一样的,所以呢,如果 Active NameNode 挂了可以立马切换成 Standby NameNode 对外提供服务。这就是所谓的 NameNode 主备高可用故障转移机制

NameNode如何承载每秒上千次的高并发访问

产生的问题

  • 每次请求 NameNode 修改一条元数据,都要写一条 edits log。还会写入 JournalNodes 集群。包括了以下两个步骤: 写入本地磁盘、通过网络传输给 JournalNodes 集群
  • NameNode 在写 edits log 时的第一条原则:必须保证每条 edits log 都有一个全局顺序递增的 transactionId(简称为 txid),这样才可以标识出来一条一条的 edits log 的先后顺序。
  • 每个线程修改了元数据,要写一条 edits log 的时候,都必须按顺序排队获取锁后,才能生成一个递增的 txid,代表这次要写的 edits log 的序号
  • 问题:NameNode 本身用多线程接收多个客户端发送过来的并发的请求,结果多个线程修改完内存中的元数据之后,排着队写 edits log。写本地磁盘 + 网络传输给 JournalNodes,都是很耗时的。性能两大杀手:磁盘写 + 网络写

解决方法

基本思想

  • 将edits log写入内存缓冲,这样多个线程就可以快速的获取锁,生成txid。
  • 然后有一个线程可以将内存中的edits log 刷入磁盘,但在这个过程中,还是继续允许其他线程将edits log写入内存缓冲中。

上述方法存在的问题:针对同一块内存缓冲,同时有人写入,还同时有人读取后写磁盘,那也有问题,因为不能并发读写同一块共享内存数据

  • 解决方式:HDFS 在这里采取了 double-buffer 双缓冲机制来处理!将一块内存缓冲分成两个部分:
    • 其中一部分写入
    • 另一部分用户读取后写入磁盘和JournalNodes。

分段加锁机制 + 内存双缓冲机制

  • 首先将内存分成了两块,区域1和区域2。多个线程依次获取锁,生成txid,然后将edits log写入内存的区域1中,接着就立马释放锁,供后面的线程写区域1。这是第一次的锁。

  • 然后,第二步,各个线程竞争第二次的锁(这个锁是跟上面不同的另一步骤的锁)。有线程获取到锁后,就看看有没谁在写磁盘和网络JournalNodes。

    • 没有。直接交换双缓冲的区域1和区域2,释放锁。此后第一次获取锁写edits log到内存缓冲的线程都会写到区域2中,不再写区域1。然后这个线程将区域1中的数据读取出来,将里面的edits log写入磁盘文件以及通过网络写入 JournalNodes 集群
    • 有。判断txid是否是排在自己之后的,如果是那么肯定就已经把自己的edits log从缓冲写入到磁盘和网络了,直接返回。如果不是排在自己之后,释放锁,休眠1秒。
    • 当有线程写完磁盘和网络之后,就会唤醒之前休眠的那些线程。那些线程依次排队再一次获得锁,判断是否有人写磁盘和网络,如果没有。再判断有没有排在自己之后的线程已经将自己的edits log写入磁盘和网络,如果有直接返回,如果没有,交换两块缓存区域。后面的线程就写edits log到区域1 自己刷写区域2的磁盘和网络,重复上述过程。

    欢迎关注本人的公众号,不定期推送问答模式技术问题,并可随机参与抽奖
    在这里插入图片描述

  • 1
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值