Hadoop源码之HDFS(1)--------通信方式

说起hadoop这个东西,只能说真是个伟大的发明,而本人对cutting大神也是无比的崇拜,记得刚接触hadoop的时候,还觉得这个东西挺多余的,但是现在想想,这个想法略傻逼......

2006-2016,hadoop至今已经走过了10个年头,版本也已经发展到2.7了,现在hadoop3.0也快出来了,虽然spark,flink这些优秀的框架近几年的势头非常的强劲,但是我认为,近几年内并不会有哪个框架会取代hadoop,所以其实还是挺值得研究的。

那么我这系列的文章呢,主要是想讲讲Hadoop的核心组件HDFS,这个文件系统现在应用真是非常的广泛,特别是hadoop由1.x升到2.x之后,hdfs不论是从容错性、可靠性、可扩展性都有了非常大的提升,体系结构也有了很大的变化。正巧最近忙里偷闲阅读了一下hdfs的源代码和看了一本介绍hdfs源代码的书,希望分享下我自己的一些理解吧。

首先简单说说HDFS的基本结构吧,主从式架构相信大家都非常熟悉,hadoop也是采用这一个,由namenode和datanode组成,但是在1.x版本中已经证实了仅仅依靠secondary namenode来保证hadoop集群的可靠性是远远不够的,因为secondary namenode不是热备份,而只是帮助namenode恢复数据而已,并且数据也不是恢复到最新的数据(有关secondary namenode的帮助恢复的工作原理有兴趣的朋友可以留留言,我可以简要介绍下,要是大家都有这个需求我就另发一篇讲讲这个secondary namenode,不过这个都是1.x的事了,大家应该不感兴趣吧哈哈~),因此,要保证hadoop集群的高可用,在2.x中引入了HA机制,有关这个HA机制,主要是以来zookeeper来实现的,这里先不细讲,后面我会专门写文章讲这个的,这里主要HDFS结构中几种节点的通信。

那么HDFS通信协议呢,有两种,一种是Hadoop RPC接口,一种是流式接口,那么这两种接口各自有各自的分工,前者主要是负责一些连接的管理、节点的管理以及一些数据的管理,而后者主要是数据的读写传输。

1.Hadoop RPC 接口

首先,不同于流式接口,Hadoop RPC接口是基于protobuf实现的,protobuf是google的一种数据格式,这里不做细究。那么Hadoop RPC的接口主要有那么几个,包括ClientProtocol,ClientDatanodeProtocol,DatanodeProtocol,InterDatanodeProtocol,NamenodeProtocol这几个,这几个接口都是节点间的主要通信接口,其他的一些涉及安全、HA的接口我们以后在讨论。

首先是重中之重的ClentProtocol,为什么是重中之重呢?我们需要对数据文件做的操作基本上都是靠这个接口来实现的,我看的源代码是2.6.4,大致数了下,这个接口有89十个方法,醉了......这里主要的一些方法有getBlockLocations()、create()、append()、addBlock()、comlete()等等,具体这些方法怎么我家下来介绍完集中接口之后,结合HDFS读文件和写文件的流程来介绍这些方法的使用。

然后是ClientDatanodeProtocol接口,这个接口是Client端和Datanode端通信使用的,主要有getReplicationVisibleLength()、getBlockLocalPathInfo()、refreshNamenodes()、deleteBlockPool()、getHdfsBlocksMetadata()、shutdownDatanode()这么些方法,我们从这些方法名可以看到,这些方法基本上都是与数据块的管理相关,很显然嘛,Datanode主要的用途就是存储数据嘛,他又不能自己管理数据。

那么接下来就是datanode和namenode通信的接口,DatanodeProtocol,这个接口也是非常重用,解决了很多的问题,datanode的注册、心跳应答数据块汇报都是靠这个接口完成的。这个接口里,有datanode启动相关的,心跳相关的和数据块读写相关的方法。启动相关的方法,其实主要是四个,versionRequest()、registerDatanode()、blockReport()和cacheReport(),按流程来说就是先是versionRequest(),确认namenode和datanode的版本信息是否一致,如果一直,则建立连接,然后是registerDatanode(),从名字也能看得出,这个方法是拿来注册这个datanode节点的,注册了之后namenode中才会有这个节点相关的信息,然后是blockReport()和cacheReport(),datanode汇报自己节点上的数据块信息(有人很疑问,为啥一个新的节点要汇报数据块信息?我认为应该是有些节点是因为失效了又重新加入集群中,所以里面本来就有数据)。通过这四步,datanode就成功启动加入集群了。心跳相关的方法其实主要就一个sendHeartbeat(),这个方法就是用来发送心跳的,心跳是默认3秒钟一次。最后是数据块读写相关的方法,有reportBadBlocks()、blockReceivedAndDeleted()和commitBlockSynchronization()方法,这些方法其实都是拿来管理数据块的,比如出现无效的数据块或者写数据过程中节点故障数据没写完等等。

然后是InterDatanodeProtocol接口,这个接口很简单,就是datanode之间相互通信的接口,虽然这个接口简单,但是其实很有用,因为我们所说的副本就是通过datanode之间的通信来实现复制的而不是通过namenode同时将文件数据写到三个副本中。

最后就是NamenodeProtocol了,这个接口就不说了吧,在2.x都没什么用了,这个是namenode和secondary namenode通信的接口。

2.流式接口

流式接口有两种,一种是基于TCP的DataTransferProtocol,一种是HA机制的active namenode和standby namenode间的HTTP接口,第二种先不说,因为涉及HA机制节点的切换以及fsimage和editlog的合并方式等等,这个今后另起一篇来说。

那么就是DataTransferProtocol了,这个接口最主要的方法就是readBlock()、writeBlock()和transferBlock()了。读数据块、写数据块以及数据块额复制就是靠这些方法来实现。

介绍完两类接口之后,我们应该是还有一个问题没有解决吧,嘿嘿,hdfs的读写文件问题。二话不说,先来两张图:

第一张图是读数据的,第二张图是写数据的,这两张图是官方给的图。

先说说读文件,首先是HDFS客户端会调用DistributedFileSystem.open()打开跟集群的连接,并且打开文件,这个方法底层来说会调用ClientProtocol接口的open()方法,然后返回一个数据流给客户端,此时客户端会在调用接口的getBlockLocations()方法得到文件的一个数据块的位置等等信息,然后客户端就会通过数据流调用read()方法从这些位置信息里面选出一个最有的节点来进行数据读取(一般三个副本位置会选取网络开销最少的那个节点,本地节点就好了),传输完毕之后,客户端会再调用getBlockLocations()方法得到下一个数据块的位置信息,然后开始读,知道数据读取结束,客户端调用close()方法,关闭数据流。

说完读文件,就是写文件了,写文件就稍微比读文件要复杂一些。首先客户端会调用DistributedFileSystem.create()方法在hdfs中创建一个新的空文件,这个方法会在底层调用ClientProtocol.create()方法,namenode会在文件目录树下添加一个新的文件,并且将操作更新到editlog中,此举之后,集群会返回一个数据输出流,然后客户端就可以开始通过调用write()方法写数据到数据流中了,但是此时namenode中并没有任何这个数据的数据块元数据映射,所以数据流会调用addBlock()方法获取要写入datanode节点的信息,然后就是write()方法的调用写数据了,写到一个节点上之后,这个节点就开始建立与另外的datanode的连接,然后将数据复制到其他datanode,从而实现副本。当副本写完之后,第一个datanode就会返回一个确认包,确认数据已经写入完毕,并且调用blockReceivedAndDeleted()方法告诉namenode要更新内存元数据的数据,然后开始下一个数据块的写入,当数据写入完毕之后,调用close()方法关闭数据流。

追加写文件其实流程上跟写文件差不多,这里就不多做赘述了。

好了,写了那么多,主要是一个warming up,大致介绍下hdfs的一些基本原理和流程,接下来的文章里,希望能够更大家分享一些更细节的东西和hdfs内部的一些实现。共勉~

PS:本人的博客会先更新在简书上然后再更新博客,个人感觉简书对于知识的传播还是挺方便的哈哈~

时间: 2024-10-29 19:05:46

Hadoop源码之HDFS(1)--------通信方式的相关文章

hadoop源码剖析--hdfs安全模式

一.什么是安全模式 hadoop安全模式是name node的一种状态,处于该状态时有种量特性: 1.namenode不接受任何对hfds文件系统的改变操作(即此时整个文件系统处于只读状态): 2.不执行block的replica和delete动作. 二.安全模式的原理 安全模式实在name node启动时默认进入的,当然也可以手动开启或关闭安全模式. 在name node启动后自动进入安全模式,这时data nodes向name node汇报各自节点的block信息.要想自动离开安全模式需要满

hadoop源码解析---INodeReference机制

本文主要介绍了hadoop源码中hdfs的INodeReference机制. 在hdfs2.6版本中,引入了许多新的功能,一些原有的源代码设计也有一定的改造.一个重要的更新就是引入了快照功能.但是当HDFS文件或者目录处于某个快照中,并且这个文件或者目录被重命名或者移动到其他路径时,该文件或者目录就会存在多条访问路径.INodeReference就是为了解决这个问题产生的. 问题描述 /a是hdfs中的一个普通目录,s0为/a的一个快照,在/a目录下有一个文件test.根据快照的定义,我们可以通

Hadoop源码编译与调试汇总

虽然在运行Hadoop的时候可以打印出大量的运行日志,但是很多时候只通过打印这些日志是不能很好地跟踪Hadoop各个模块的运行状况.这时候编译与调试Hadoop源码就得派上场了.这也就是今天本文需要讨论的. 先说说怎么编译Hadoop源码,本文主要介绍在Linux环境下用Maven来编译Hadoop.在编译Hadoop之前,我们需要准备好编译环境: 1.安装好1.6或以上的JDK;2.安装Maven,被做好相应的配置;3.安装ProtocolBuffer 2.5.0,MapReduce和HDFS

Hadoop源码如何查看

如何查看hadoop源码 1解压hadoop安装压缩文件成为文件夹,再进入解压后的文件夹下的src文件夹,选中core,hdfs,mapred三个文件夹 2打开eclipse新建一个Java工程项目 3将步骤1中的三个文件夹复制到新建的工程的src目录下 此时会出现2个问题:1是因为缺少工程文件的jar包 2是因为src下的3个文件的路径不对,需要修改其对应的路径 4右键工程名选择最后一项proprity(属性)--->选择左面的Java build path--->先删掉右面的Source下

Hadoop源码学习笔记(1) ——第二季开始——找到Main函数及读一读Configure类

Hadoop源码学习笔记(1) ——找到Main函数及读一读Configure类 前面在第一季中,我们简单地研究了下Hadoop是什么,怎么用.在这开源的大牛作品的诱惑下,接下来我们要研究一下它是如何实现的. 提前申明,本人是一直搞.net的,对java略为生疏,所以在学习该作品时,会时不时插入对java的学习,到时也会摆一些上来,包括一下设计模式之类的.欢迎高手指正. 整个学习过程,我们主要通过eclipse来学习,之前已经讲过如何在eclipse中搭建调试环境,这里就不多述了. 在之前源码初

Hadoop源码导入Eclipse

需要进一步学习hadoop.需要看看内部源码实现,因此需要将hadoop源码导入都eclipse中,简单总结一下,具体步骤如下: 首先确保已经安装了git.maven3.protobuf2.5.如果没有安装需要提前安装一下 1.下载hadoop源码 git clone git://git.apache.org/hadoop-common.git 2.进入hadoop-common目录,用maven生成eclipse工程 mvn install -DskipTests mvn eclipse:ec

Hadoop源码学习笔记(4) ——Socket到RPC调用

Hadoop源码学习笔记(4) ——Socket到RPC调用 Hadoop是一个分布式程序,分布在多台机器上运行,事必会涉及到网络编程.那这里如何让网络编程变得简单.透明的呢? 网络编程中,首先我们要学的就是Socket编程,这是网络编程中最底层的程序接口,分为服务器端和客户端,服务器负责监听某个端口,客户端负责连接服务器上的某个端口,一旦连接通过后,服务器和客户端就可以双向通讯了,我们看下示例代码: ServerSocket server = new ServerSocket(8111); S

细水长流Hadoop源码分析(3)RPC Server初始化构造

声明:个人原创,转载请注明出处.文中引用了一些网上或书里的资料,如有不妥之处请告之. 本文是我阅读Hadoop 0.20.2第二遍时写的笔记,在阅读过程中碰到很多问题,最终通过各种途径解决了大部分.Hadoop整个系统设计精良,源码值得学习分布式的同学们阅读,以后会将所有笔记一一贴出,希望能方便大家阅读源码,少走弯路. 目录 4 RPC服务器(org.apache.hadoop,ipc.Server) 4.1 服务器初始化 4 RPC服务器(org.apache.hadoop,ipc.Serve

hadoop源码解读namenode高可靠:HA;web方式查看namenode下信息;dfs/data决定datanode存储位置

点击browserFilesystem,和命令查看结果一样 当我们查看hadoop源码时,我们看到hdfs下的hdfs-default.xml文件信息 我们查找${hadoop.tmp.dir}这是引用变量,肯定在其他文件有定义,在core-default.xml中查看到,这两个配置文件有个共同点: 就是不要修改此文件,但可以复制信息到core-site.xml和hdfs-site.xml中修改 usr/local/hadoop 是我存放hadoop文件夹的地方 几个关于namenode的重要文