HDFS 读写分离

为什么HDFS需要读写分离

当前架构:

目前HDFS在HA模式下的架构图如如下:
HDFS 读写分离

HA同步机制简单介绍:

客户端读写都通过RPC连接Active Namenode进行操作,Standby Namenode不具有读写的功能只负责同步操作记录(Editlog)。Editlog是Active Namenode通过RPC写到由PAXOS协议实现的一组Journalnode,然后Standby Namenode通过HTTP协议去拉Journalnode的Editlog进行同步的。

读写的全局锁

上面介绍了客户端只能通过RPC从Active Namenode,那么Active Namenode既承载了读的压力,又承载了写的压力。感性上我们会觉得它的压力很大,那么我们根据事实进行分析一下。
HDFS 读写分离

如上图所示,Namenode的FSNamesystem类中主要有三块。

  1. INodeMap中存着目录树的映射关系:Id -> INode
  2. BlocksMap中存着块和块位置信息的映射信息。Block -> BlockInfo
  3. DataNode Manager : 用于对DataNode进行管理。
    (GSet是一种高效的HashMap实现)

而这三种数据结构都在全局锁读写锁的锁范围内:
全局读写锁类(暂时不对读写锁的进行实现分析,封装了常见的读写锁实现类ReentrantReadWriteLock):
HDFS 读写分离
虽然写的场景在集群中可能只占10%左右,读的场景占90%左右。但是无论是目录树还是块管理的更新,都在全局锁的写锁范围内,而写锁是排他锁,会对集群的整体读写延迟等性能和集群整体的吞吐量产生较大的影响。所以为了提升读写性能,和集群的吞吐量,社区等对HDFS读写分离展开了讨论和开发。

怎么改善全局锁限制

针对怎么改善全局锁限制,社区有很多的讨论,主要分为两大块:

1. 拆锁,把锁的粒度拆的更细。

1.1 采用分段锁,把全局锁分段,如下图所示:

HDFS 读写分离

该架构NameNode中数据结构与全局锁不同,分段锁具有两层映射关系:

  1. RangeMap: keyRange -> GSet
  2. RangeSet: key -> INode
    好处显而易见: 首先,锁的范围减小了,避免了全局锁限制。其次,每个锁之间的操作都是独立的,各个锁区间的操作,可以并行进行。

2. 从Standby Namenode进行读

社区HDFS-12943的issues针对这个功能进行讨论和开发中。我们详细跟进并且分析该读写分离模式的实现原理和源码分析。