深入解析Hadoop分布式文件系统架构:Namenode、Client与Datanodes的角色与功能
01.Hadoop分布式文件系统

在讨论如何实现存储与计算分离来优化数据存储之前,我们首先通过一张图来回顾一下Hadoop分布式文件系统的架构。从图中我们可以发现三个角色,分别是Namenode、Client、Datanodes。
其中,Client是用户用来操作HDFS文件系统进行创建、删除、移动或重命名操作的客户端。 Namenode是一个中央服务器,负责管理文件系统的命名空间和客户端对文件的访问。 Namenode执行文件系统名称空间操作,例如打开、关闭和重命名文件或目录。同时Namenode还负责确定数据块到具体Datanode节点的映射。 Datanode分布在集群中的各个节点上,每个节点上分布一个,管理其所在节点的数据存储。
在内部,HDFS公开了文件系统的命名空间,允许用户以文件的形式在其上存储数据。一个文件被分割成多个数据块,这些数据块存储在一组Datanode上。图中绿色方块代表划分后的数据块。在Namenode的统一调度下,进行数据块的创建、删除和复制。 Datanode还负责处理来自文件系统客户端的读写请求。
首先我们回顾一下Hadoop分布式文件系统HDFS中数据写入的流程。我们根据具体需求来介绍。将本地文件上传到HDFS需要采取哪些步骤?
步骤1:HDFS客户端向Namenode提交本地文件上传请求,触发对上传文件的预验证,主要检查权限,判断目录是否存在。如果验证失败,则本次上传失败。如果成功,请继续执行第二步。
步骤2:请求上传并获取Datanode列表。 Namenode会将本次上传所需的Datanode节点列表反馈给HDFS客户端。
第三步:完成上述步骤后,客户端开始上传文件。客户端上传文件时,并不是将文件一一上传到对应的Datanode,而是建立一个区块通道。如下图所示,Datanode1和Datanode2之间、Datanode2和Datanode3之间建立了块通道。只需要将文件上传到Datanode1,不需要上传到其他Datanode。
步骤4:区块通道建立后,会触发Datanode的ack操作。当Datanode将ack返回给HDFS客户端时,文件上传操作的实际准备工作就开始了。 HDFS客户端将本地文件切成块,写入到相应的Datanode,写入相应的缓冲区,然后将缓冲区的内容传输到磁盘,并通过阻塞通道。 Datanode保证文件上传。
步骤5:数据写入完成后,HDFS客户端将写入结果报告给Namenode。
接下来我们回顾一下Hadoop分布式文件系统(HDFS)中读取数据的流程,即如何将上传的文件下载到本地。
步骤1:HDFS客户端向Namenode提交下载文件预验证请求。与写入过程一致,Namenode开始检查权限。
步骤2:HDFS客户端获取文件所在的Datanode列表。因为Namenode是整个HDFS的元数据管理,它返回文件所在的Datanode列表给HDFS客户端,进行顺序下载操作,将数据块下载到本地并拼接成完整的文件。
步骤3:如下图所示,如果每次下载都经过Datanode1,则Datanode1的负载压力会太大。因此,在采集数据时,采用机架感知和负载均衡算法来减轻Datanode1的压力,实现从附近节点采集数据。
Hadoop YARN的工作机制中,主要有几大节点:Mapreduce客户端、资源管理器、节点管理器和数据节点。
(执行wordcount的Mapreduce任务,详细请看原视频评论)
02.Hadoop分布式文件系统存在的问题
回顾一下Hadoop分布式文件系统的数据写入和读取过程,不难发现Hadoop分布式文件系统存在的问题。具体总结如下:
1、计算与存储耦合
在传统的Hadoop集群系统中,计算和存储资源是紧密耦合的。当存储空间或计算资源不足时,只能同时扩展两者。如果用户的计算需求远大于存储需求,扩展集群会造成存储的浪费,反之,也会造成计算资源的浪费。
2. 扩张有限
这主要体现在集群节点的增加,导致扩容成本增加,风险加大。
3.HDFS性能问题
HDFS Namenode的全局锁虽然简化了锁模型,降低了复杂度,但是全局锁最大的缺点就是容易造成性能瓶颈。 HDFS管理器主要负责文件系统空间的运维、集群配置信息和数据块复制。 Namenode在运行过程中保存的每个文件和每个数据块之间的关系统称为元数据。在运行时,HDFS中每个文件、目录和数据块的元数据信息必须存储在Namenode的内存中。默认情况下,每100万个数据块分配最大空间,这限制了HDFS中的实际对象数量,也意味着对于具有大量文件的超大型集群,内存将成为限制系统扩展的瓶颈。同时,作为一个可扩展的文件系统,它支持单个集群中数千个节点,并且可以在单个命名空间的Datanode中实现良好的扩展。然而,Namenode无法在单个空间内水平扩展。因此,通常HDFS的性能瓶颈都存在于单个Namenode上。
4.HDFS成本问题
HDFS 文件系统中的典型文件大小通常在 G 字节到 T 字节之间。由于HDFS的复制特性,一个文件至少会存储3个副本。这个额外的空间会带来存储成本的额外增加。
针对以上问题,Hadoop采用存储计算分离架构的趋势越来越明显。
03.Hadoop实现存储与计算分离的解决方案
针对Hadoop分布式文件系统中计算资源和存储成本的问题,目前我们有两种解决方案来实现存储与计算的分离。
选项 1:Hadoop 兼容的文件系统
上图是目前兼容Hadoop3的文件系统。进入。同样的原理也适用于下载文件。
为什么Hadoop可以这样实现计算和存储分离呢?
我们以日常生活事件为例:家里的带宽升级到100Mbps后,我们上网看电影就不会出现卡顿的情况,下载一部电影只需要几分钟。几年前,当带宽较低时,下载一部电影可能需要几个小时。带宽的速度,特别是机房的带宽速度,现在已经变成了1000Mbps、2000Mbps、10000Mbps,甚至100000Mbps。但磁盘的速度基本上没有太大变化。带宽速度的提高带来了软件架构的变化。
选项 2:云原生 Hadoop 文件系统
第一种方案虽然可以实现计算与存储分离,但基础架构上仍然存在问题:虽然带宽增加了,但如果Hadoop集群机房与对应的对象存储机房距离较远,会受到以下因素的影响:网络抖动会增加传输失败的概率。如果确定某个目录需要多个RESTful请求才能完成操作,则多个请求会影响性能。因此,我们提出了解决方案二:DataSimba文件缓存层。
上图是DataSimba目前的存储计算分离架构。 SimbaFsClient是用Java开发的jar包,兼容Hadoop文件系统,按照Hadoop FileSystem API规范实现。 DataSimba文件缓存层主要实现Hadoop FileSystem的list、delete、rename、mkdir等接口。其中InputStream和OutputStream主要实现文件读写优化(预读、缓存读、异步写、批量写、文件压缩)等相关功能。
DataSimba文件缓冲层采用JNI(Java Native Interface)技术,将调用转换为本地simbafs.so来实现相关方法,完成文件上传/下载操作,并作为中间缓存层,实现计算与存储分离。
因此,DataSimba文件缓存层有效避免了计算与存储紧耦合、扩展空间、存储成本等问题。
DataSimba实现存储计算分离的压力测试是怎样的?
为什么 DataSimba 的性能优于 HDFS?