说起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:本人的博客会先更新在简书上然后再更新博客,个人感觉简书对于知识的传播还是挺方便的哈哈~

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

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

    一.什么是安全模式 hadoop安全模式是name node的一种状态,处于该状态时有种量特性: 1.namenode不接受任何对hfds文件系统的改变操作(即此时整个文件系统处于只读状态): 2.不 ...

  2. Hadoop源码编译过程

    一.           为什么要编译Hadoop源码 Hadoop是使用Java语言开发的,但是有一些需求和操作并不适合使用java,所以就引入了本地库(Native Libraries)的概念,通 ...

  3. 如何导入hadoop源码到eclipse

    需要进一步学习hadoop.需要看看内部源码实现,因此需要将hadoop源码导入都eclipse中. 简单总结一下,具体步骤如下: 首先确保已经安装了git.maven3.protobuf2.5.如果 ...

  4. 安装Hadoop系列 — 导入Hadoop源码项目

    将Hadoop源码导入Eclipse有个最大好处就是通过 "ctrl + shift + r" 可以快速打开Hadoop源码文件. 第一步:在Eclipse新建一个Java项目,h ...

  5. 详细讲解Hadoop源码阅读工程(以hadoop-2.6.0-src.tar.gz和hadoop-2.6.0-cdh5.4.5-src.tar.gz为代表)

    首先,说的是,本人到现在为止,已经玩过.                   对于,这样的软件,博友,可以去看我博客的相关博文.在此,不一一赘述! Eclipse *版本 Eclipse *下载 Jd ...

  6. Mac搭建Hadoop源码阅读环境

    1.本次Hadoop源码阅读环境使用的阅读工具是idea,Hadoop版本是2.7.3.需要安装的工具包括idea.jdk.maven.protobuf等 2.jdk,使用的版本是1.8版,在jdk官 ...

  7. Eclipse导入Hadoop源码项目及编写Hadoop程序

    一 Eclipse导入Hadoop源码项目 基本步骤: 1)在Eclipse新建一个java项目[hadoop-1.2.1] 2)将Hadoop压缩包解压目录src下的core,hdfs,mapred ...

  8. Centos7下编译CDH版本hadoop源码支持Snappy压缩

    1 下载snappy包并编译 wget https://github.com/google/snappy/releases/download/1.1.3/snappy-1.1.3.tar.gz tar ...

  9. Hadoop源码学习笔记之NameNode启动场景流程一:源码环境搭建和项目模块及NameNode结构简单介绍

    最近在跟着一个大佬学习Hadoop底层源码及架构等知识点,觉得有必要记录下来这个学习过程.想到了这个废弃已久的blog账号,决定重新开始更新. 主要分以下几步来进行源码学习: 一.搭建源码阅读环境二. ...

随机推荐

  1. Tsung测试Tigase

    用两台主机坐Tigase的Tsung测试,其中1台运行Tigase,另1台运行Tsung. 1.Tigase服务器设置 tigase.conf: #osgiEnabled=(true|false) # ...

  2. iOS取得AddressBook联系人信息

    新建一个CContact类用于存放联系人信息,下面是该类的代码: CContact.h代码: 01 #import <Foundation/Foundation.h> 02   03   ...

  3. EffectiveJava——请不要在代码中使用原生态类型

    先看一个栗子,看看能不能找出来里面的错误: /** * 请不要在新代码中使用原生态类型 * @author weishiyao * */ public class Test { public stat ...

  4. Hibernate(一)__简介

    一. hibernate是什么 (一)hibernate 是一个orm框架,orm (object relation mapping) 对象关系映射框架 o object -> 业务层(只对对象 ...

  5. C#调用C和C++函数的一点区别

    最近做U800电话的二次开发,需要调用厂商的C函数库来打电话,后来想加入通话录音功能,但发现程序默认生产的WAV文件过大,又找了个WAV转MP3的C++函数库程序,出了点问题.下面是转MP3的程序接口 ...

  6. linux常用命令之压缩打包

    DF df – report file system disk space usage 查看文件系统的使用清空 用法 df [-hi] [path] 选项 -h human readable ,以人类 ...

  7. vsftp "上传 553 Could not create file"

    我在LINUX下VSftp建立一个FTP服务器,但从WINDOWS使用FTP时,无法上传也无法下载!出错如下 ftp>; ls 200 PORT command successful. Cons ...

  8. letter-spacing

    letter-spacing:3px的意思就是字母之间的间距是3px:

  9. NodeBB – 基于 Node.js 的开源论坛系统

    NodeBB 是一个更好的论坛平台,专门为现代网络打造.它是免费的,易于使用. NodeBB 论坛软件是基于 Node.js 开发,支持 Redis 或 MongoDB 的数据库.它利用 Web So ...

  10. SharePoint 部署解决方案Feature ID冲突

    中文报错: 部署步骤“添加解决方案”中出现错误: 已在此服务器场中安装 ID 为 735efe4e-8b50-4310-b588-c6ae2ba0759f 的功能.请使用强制属性显式地重新安装此功能. ...