聊聊HDFS BlockManager的服务化改造

前言


在现有的HDFS中,NameNode扮演着一个十分重要的角色。它不仅需要处理集群中所有文件相关的操作(此处可理解为INode相关的操作),它还要处理更小粒度级别的操作,也就是block块级别的操作。随着HDFS的快速迭代发展,它所需要执行的操作也越来越重了。另一方面,一旦集群的数据量规模大幅度扩展的时候,相应的INode文件、block块数据信息将会耗掉NameNode大量的内存,这将会大大降低HDFS的可扩展性。所以在这里,我们是否可以将文件服务与块服务完全独立开,毕竟块相关操作是一个更加底层的操作。在进一步地来说,如果真的要将文件服务于块服务完全独立开,这意味着要将BlockManager服务从原先的NameNode进程服务中脱离开,变成一个单一的服务。而它与原先的NameNode内相关联的操作就得需要RPC通信的方式来弥补了。本文笔者就聊聊BlockManager服务改造的一些想法,此想法源自于Hadoop社区早期的一些文档资料,个人感觉还是很有意思的。

NameNode内存占用分析


在介绍本文主要内容之前,我们不妨来看看几组有意思的数据,来直观地感受NameNode中文件、块数据所占用的内存开销。

假设目前我们有一个1EB(1EB=1024PB=2的60次方字节)数据量规模的集群,如果按照1台机器12块盘,每块盘5T来算(1个节点的容量就是12*5=60T),那么需要的总节点数量就为1024PB/60T=17476.26666666667,此处约等于17k的机器数量。这已经是一个很恐怖的数字了,我们知道,维护管理一个5000个节点的集群就已经是一个比较困难的事情,更何况是破万节点数的集群。

这里还没完,我们继续来看这么大规模数据量的情况下,它内部的文件、块数据的存储空间容量如何呢?

假设集群中每个块的大小设置为64MB(2的26次方字节),文件与块的比例为1:1,意思就是一个文件刚好写满一个block块。那么此集群中的文件(block块)数=2的60次方字节(1EB)/64MB=2的34次方。也就是说,在基于上述假设的情况下,集群中将会有2的34次方(170亿左右)个文件/块的数量。按照社区文档中对当前每个INode文件对象以及block块对象的空间占用字节统计,一个INode为188个字节,1个block为136字节(现在的实际值可能已略有不同)。那么这些INode以及block总的占用空间将达到(188+136)*2的34次=5.063*240字节=5.063TB。考虑到INode对象中还包含了若干字节(此处为24字节)的block的引用数据,所以其实INode的真实占用字节数为188-24:136+24=164:160,这个值已经接近于1:1了。所以通过一连串的分析,我们可以得出一个结论:block块数据几乎占据了一半NameNode的内存使用空间

所以将块相关的管理操作从NameNode进程服务中剥离开将会大大降低NameNode的负载。

现有FSM与BM之间的关联性


在现有NameNode内,FSM(FileSystem Manager)与BM(Block Manager)耦合度比较高,前者的操作往往回处罚后者的执行。我们来看下面几个例子:

  • startFile初始创建文件方法
    • 第一步,首先FSM会创建一个新的INode对象,并生成一个唯一的inodeId来代表此文件。然后将此id传给BM。
    • 第二步,BM根据此id,在此id下创建block集合对象。此集合意为此文件所包含的文件块。
  • addBlock添加块方法(当客户端写入数据时会调用到)
    • 第一步,FSM解析文件路径到inodeId,将此id传给BM。
    • 第二步,BM根据此id,找到对应的block集合对象,在这个集合对象内添加新的block块。
  • 删除、更新块方法的执行过程与addBlock方法相似。

通过上述几个典型的方法过程分析,我们可以看出其中的确是有比较大的耦合度,这在未来是不利于NameNode的扩展的。所以FSM与BM的分离就是将上述方法过程的第一步与第二步分在2个进程内执行。这样也将它们所维护的INode数据,block数据完全分离开。

BlockManager服务化改造核心设计要点


如果真的要将BlockManager进行服务化的改造,需要考虑哪些点呢?笔者在阅读完社区相关文档后,归纳出以下节点。

一、向后兼容性。原先的API和一些接口协议都应该保证能依然走通。
二、支持可启用、禁用此功能特性。如果禁用了,则与原有的服务形式一致,FileSystem Manager的服务与Block Manager的服务都运行于同一进程内。
三、性能问题。将Block Manager服务单独出去之后,对整个NameNode的RPC请求处理的影响应尽可能地小,包括原先的块处理部分、或副本的重新复制等等。
四、高可用性。Block Manager服务应与NameNode服务一样,也能支持HA特性,也支持Active-Standby模式。
五、NN-BM协议的设计。之前Block Manager是运行在NameNode进程内的,文件、块的操作理论上说只是内部的操作,而将Block Manager服务化出去之后,这就需要RPC的通信来关联两个进程服务。所以这里需要定义一个新的NameNode-BlockManager之间的协议。

由于本文篇幅有限,笔者在下文中挑了其中一个点来进行分析。

FSM与BM的一致性控制


当我们把Block Manager模块独立化出去之后,一个比较大的问题将会马上显现出来:状态一致性问题。当这2个服务在同个进程最后的时候
,我们可以比较容易地控制其中的状态问题,但是一旦我们将它们分离出去,这其中的状态问题就不是这么简单了。

服务恢复


一个非常常见的例子,假设现在已经有2个服务,1个是FSM,另外一个是BM,那么有可能会出现以下3种异常情况

  • FSM服务挂了,BM还存活。
  • BM挂了,FSM还存活。
  • FSM、BM都挂了。

以上3种情况属于比较严重的会出现状态不一致的问题。下面简单介绍社区文档中提到的一种做法。

当2个服务中的某个服务出现进程挂掉的现象,另外一个进程服务检测到此事件,然后让自己进入一种“安全模式”,比如BM此时就
只接收块,但不进行处理块的动作。而对于FSM来说,则不处理来自客户端的任何API请求。这些操作都是为了防止出现状态不一致的问题。
归纳地来说就是,当另一方服务缺失的情况下,BM或FSM服务不会进行操作的自主执行。

与此同时,挂掉的进程服务应进行启动恢复的操作,恢复的手段一般是通过log恢复的办法,在此我们可以理解为就是editlog。

操作的同步


前一部分提到的进程挂掉的现象属于比较少见的的情况,另外一种更为常见的出现服务状态不一致的现象是请求操作的不同步性。因为将
BM服务化之后,2个进程内的操作是并行执行的,所以这里需要有一个分布式锁来做这方面的同步。锁的类型不一定都是排他锁,视操作
而定,可分为排他锁(Exclusive Lock)和共享锁(Shared Lock)。对于一些查询相关的操作,我们就可以采用共享锁。

FSM、BM内部操作的锁类别信息如下:



图 1-1 FSM/BM 相关操作

下面我们来看看分布式锁在FSM、BM内部的具体使用。

  • FSM查询类API(Block查询API与此完全类似):
    • 获取分布式锁。
    • 解析文件路径到inode,取出对应数据。
    • 释放锁操作,然后返回结果数据。
  • FSM更新类API:
    • 获取分布式锁。
    • 解析文件路径到inode id。
    • 如果此inode id在活跃的inode集合中(活跃的inode集合由FSM、BM共同维护及更新),表明当前此inode正在被执行其它更新操作,释放锁;过一会进行重试操作。
    • 更新inode操作,并记录一次editlog操作。
    • 释放锁操作。
  • BM更新类API(BM更新方法由FSM更新方法触发):
    • 获取分布式锁。
    • 解析文件路径,得到inode id。
    • 如果此inode id在活跃的inode集合中,释放锁;过一会进行重试操作。
    • 否则将此inode加入到活跃的inode集合中。
    • 释放锁操作(此部分由FSM服务完成)。
    • 随后触发下游RPC的调用,将inode id传给下游。
    • 获取分布式锁。
    • 将id从获取的inode集合内移除,更新inode操作,记录一条editlog记录。
    • 释放锁操作。

更多的BM、FSM内部的API调用过程,大家可以查阅本文末尾的文档链接。通过上述分布式锁的运用,可以在一定程度上保证FSM、BM操作之间的状态同步。

尽管目前HDFS并没有完全实现Block Manager服务化,但是基于这个理念,HDFS开发出了Ozone(HDFS-7240)。Ozone可以用来做对象存储,它的内部设计大大地区别于现有HDFS的存储体系,它将原本HDFS的Block Manager功能转化为了SCM(Storage Container Manager)。大家也不妨可以学习学习。

参考资料


[1].Block manager as a service
[2].Block-Manager-as-a-Service.pdf
[3].Object store in HDFS

posted @ 2020-01-12 19:08  回眸,境界  阅读(132)  评论(0编辑  收藏  举报