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内部的一些实现。共勉~

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,293评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,604评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,958评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,729评论 1 277
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,719评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,630评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,000评论 3 397
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,665评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,909评论 1 299
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,646评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,726评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,400评论 4 321
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,986评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,959评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,197评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,996评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,481评论 2 342

推荐阅读更多精彩内容

  • 首先,我们在使用前先看看HDFS是什麽?这将有助于我们是以后的运维使用和故障排除思路的获得。 HDFS采用mast...
    W_Bousquet阅读 4,170评论 0 2
  • Hadoop部署方式 本地模式 伪分布模式(在一台机器中模拟,让所有进程在一台机器上运行) 集群模式 服务器只是一...
    陈半仙儿阅读 1,601评论 0 9
  • 先思考问题 我们处在一个大数据的时代已经是不争的事实,这主要表现在数据源多且大,如互联网数据,人们也认识到数据里往...
    墙角儿的花阅读 7,339评论 0 9
  • 初始 始即终,无法预言的未来 艾米把字条放回桌子上,轻轻的叹了一口气,“愿一切都保佑你。“ 接着她站起身来,走到窗...
    圣诞结_b67b阅读 288评论 0 0