hadoop随手笔记

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/asdfgggggggg/article/details/51995516


图2.1 HDFS文件系统的架构图

(1)hadoop的信息的传递主要依靠心跳机制:依靠传递packet来想Datanode写入数据,一个packet由多个数据chunk组成,每个chunk对应这一个校验和,当chunk的数目足够多的时候,packet会被写入Dataqueue。其中packet包含两种:心跳packet(里面不含有任何chunk,4个字节存储packet的长度,8个字节存储呢packet在block中的偏移量,8个字节存储呢在Block中的序列号,1个字节用于标识该packet是否是block中的最后一个packet)与数据packet。

(2)在发送packet之前,DataStreamer类首先会从Namenode中获得blockid与block的位置信息,然后会循环的从Dataqueue中取得第一个packet,然后将该packet写入与Datanode所建立的socket 中。当属于一个block的所有packet都发送给Datanode,并且返回了与每个packet所对应的相应信息之后,DataStream会关闭当前的数据block。

(3)在写入数据的时候DataNode节点会在Out/InStream就是数据包传输的管道线性排列,然后会依次按照将数据写入DataNode,然后会按照原路依次向上返回响应的信息,最终返回给客户端,使用responseprocessor用来处理客户端向DataNode发送数据后响应,因为每一个数据包(packet)在DataNode接受之后会有一个反馈,该线程会在客户端运行并且处理的packet的信息也不是最后一个是时候,会循环处理来自DataNode中的响应,如果返回的是失败的响应会记录下索引并抛出异常;在客户端会创建两个队列如Dataqueue与ackqueue队列,其中前一个用来存储将要发送的数据包,而后一个是用来保存已经发送,但是没有收到确认信息的数据包。


有一个文件FileA,100M大小。Client将FileA写入到HDFS上。
HDFS按默认配置。
HDFS分布在三个机架上Rack1,Rack2,Rack3。
a. Client将FileA按64M分块。分成两块,block1和Block2;
b. Client向nameNode发送写数据请求,如图蓝色虚线①------>。
c. NameNode节点,记录block信息。并返回可用的DataNode,如粉色虚线②--------->。
    Block1: host2,host1,host3
    Block2: host7,host8,host4
    原理:
        NameNode具有RackAware机架感知功能,这个可以配置。
        若client为DataNode节点,那存储block时,规则为:副本1,同client的节点上;副本2,不同机架节点上;副本3,同第二个副本机架的另一个节点上;其他副本随机挑选。
        若client不为DataNode节点,那存储block时,规则为:副本1,随机选择一个节点上;副本2,不同副本1,机架上;副本3,同副本2相同的另一个节点上;其他副本随机挑选。
d. client向DataNode发送block1;发送过程是以流式写入。
    流式写入过程,
        1>将64M的block1按64k的package划分;
        2>然后将第一个package发送给host2;
        3>host2接收完后,将第一个package发送给host1,同时client想host2发送第二个package;
        4>host1接收完第一个package后,发送给host3,同时接收host2发来的第二个package。
        5>以此类推,如图红线实线所示,直到将block1发送完毕。
        6>host2,host1,host3向NameNode,host2向Client发送通知,说“消息发送完了”。如图粉红颜色实线所示。
        7>client收到host2发来的消息后,向namenode发送消息,说我写完了。这样就真完成了。如图黄色粗实线
        8>发送完block1后,再向host7,host8,host4发送block2,如图蓝色实线所示。
        9>发送完block2后,host7,host8,host4向NameNode,host7向Client发送通知,如图浅绿色实线所示。
        10>client向NameNode发送消息,说我写完了,如图黄色粗实线。。。这样就完毕了。
分析,通过写过程,我们可以了解到:
    ①写1T文件,我们需要3T的存储,3T的网络流量贷款。
    ②在执行读或写的过程中,NameNode和DataNode通过HeartBeat进行保存通信,确定DataNode活着。如果发现DataNode死掉了,就将死掉的DataNode上的数据,放到其他节点去。读取时,要读其他节点去。
    ③挂掉一个节点,没关系,还有其他节点可以备份;甚至,挂掉某一个机架,也没关系;其他机架上,也有备份。

(4)分布式系统中解决互斥锁的问题,1.每次执行写入的时候,客户端都需要向NameNode申请互斥锁,从而导致了网络的开销增大;2.当某个客户端获得互斥锁之后和NameNode失去联系的时候,会造成互斥锁无法释放的问题。因此可以使用lease租约来解决互斥锁的问题。当获取到互斥锁的时候,会在租约这一段时间内,无需再申请互斥锁,在客户端一直工作的过程中,如果租约期满了之后,客户端会再次续约。这样即使客户端因为异常断开的时候,也不会一直占用互斥锁,并且HDFS会在客户端每次写入数据的时候回增加版本信息,异常客户端写入的数据版本号会很低,从而可以被安全的删除。

(5)NameNode是hadoop的首席、captain,它包含了hadoop中数据文件存储的索引,包括文件存储各种信息,负责管理HDFS文件系统,具体包括namespace命名空间的管理即文件系统的目录结构,数据block的管理(filename-->>block list,block--》》DataNode list)。其始终作为被动提供服务的Server,不会主动的向客户端DFSClient或者DataNode发送请求,所有的请求都是客户端或者DataNode发起的。

(6)inode同linux 中的inode,也是硬盘中开辟的一块空间,里面主要存储文件的信息,如创建日期,文件大小,拥有者,拥有组,(在给硬盘格式化的时候,被分为数据区(block)与信息区(inode))。在hadoop中也是inode用来存储文件信息,定义了各种权限、创建时间、文件的位置,inode是hadoop中文件存储的最基本的类,其子类有indeDirectory与inodeFile分别代表系统中的目录与文件。namespace是函数的命名空间,因为不同的程序员会规定相同的函数名,此时为了区分,需要将在前面加上标志用来区分文件。

(7)FSDirectory主要用来保存整个HDFS文件系统目录的状态,管理向磁盘写入的手或者从磁盘加载的数据,并且会将目录中的数据所发生的改变记录到日志当中,保存了一个最新的file--》Block list的映射表,并且将该映射表写入到磁盘中,当系统加载FSImage的时候,FSImage会在FSDirectory对象上重建文件目录的状态(因此这两类的内容是大致是一样的,用来存储信息)。FSEditLog类主要用于namnode对HDFS的namespace的修改操作进行日志记录。在namenode中,namespace(文件系统中的目录树/文件等元数据信息,但是不包括block信息)是被全部缓存在内存中的,所以一旦namenode重启或者宕机,这些元数据信息会丢失。因此在namenode重启的时候必须要将整个namespace进行重建,namemode的当前实现的是将namesapce信息记录到一个Fsimage继承自Storage的二进制文件中,当namenode重启的时候根据读取这个fsimage文件中的信息来重建namespace目录树结构,但是fsimage是存储在硬盘上的文件,不可能时时刻刻与namenode内存中的数据结构保持同步,而是通过每隔一段时间来更新一次fsimage文件,来保证fsimage与namenode内存中的namesapce的尽量同步,而在一个新的fsimage与上一个fsimage之间的namenode的操作,都会被记录到editlog文件中,因此每隔namenode都会对应着一个fsimage文件和editlog文件。FSEditlog类就是用来管理这个editlog文件的。

(8)host2NodesMap保存了从主机到主机上的所有的DataNode的DatanodeDescriptor的映射,主要负责对集群中的DataNode按照它们所在的主机进行分类管理。一个主机上可以同时开启多个DataNode线程,也就是多个DataNode节点,HDFS是以主机为基本单位来计算集群的负载情况的。当一个DataNode节点向NameNode注册成功之后,NameNode会将这个DataNode添加到它的FSNamesystem变量的Host2NodesMap成员变量中。

(9)NetworkTopology类代表一个具有树状网络拓扑结构的计算机集群。例如,在一个集群中可能有多个数据中心,在每个计算中心都分布着很多为计算需求而设置的计算机的机架,在网络拓扑结构中,每个叶子节点代表一个DataNode,而不同的机架之间的路由选择由InnerNode内部类来表示。而且,当NameNode将一个DataNode交给NetworkTopology类保存之前,它已经将DataNode所在的主机的IP地址解析成了/*/*/*/*格式。

(10)机架:由于现实场景中机架槽位与网口的限制,会使一个机架上的只能放置有限的服务器,在每个机架之间的服务器传输速度会远远大于机架之间的服务器的传输速度,机架之间的机器网络传输速度回受到上层交换机的网络速度的限制。


这里面rack即代表机架,DataNode即代表每台服务器,第一层与第二层是路由器。

第一个block副本放在和client所在的node里(如果client不在集群范围内,则这第一个node是随机选取的)。
第二个副本放置在与第一个节点不同的机架中的node中(随机选择)。 
第三个副本似乎放置在与第一个副本所在节点同一机架的另一个节点上。

但是hadoop是不能直接对机架做出感应的,所以这时候需要对文件系统进行配置,使得hadoop能够感知出机架。

(精华:DataNode与服务器硬件之间产生联系,命名方式:hostname:port,而且该DataNode在数据中心dog里的orange机架上,那么这个DataNode在网络拓扑结构中的位置为“/dog/orange”)。一个Node实力可能表示的是一个DataNode,也可能是集群中的机架或者路由器,而一个InnerNode实例表示的是一个机架或者路由器。每个Node在网络拓扑中有一个名称与对应的位置,而Node的位置信息使用类似文件路径的方式来定义。

(11)HostFileReader用于个弄哪些DataNode允许连接到NameNode,哪些允许连接到NameNode。

(12)BlocksMap维护从数据块到其元数据的映射,其中数据块的元数据信息包括数据所属的Inode、存储数据块的DataNode等。FSimage没有记录下每一个数据Block对应的哪几个DataNode的对应表的信息,只是存储了与namespace相关的信息,在所有的DataNode启动的时候,每个DataNode对本地磁盘进行扫描,将block对应到DataNode列表的信息汇报给NameNode,NameNode在接收到每个DataNode的块信息的时候,将这些信息都保存在内存中,NameNode是利用BlocksMap数据结构保存从Block到DataNode列表信息的映射关系的。(inode包含在元数据中,linux中的inode与hadoop中的inode存储的数据元素不一样)

(13)FSNamesystem HDFS文件系统的命名空间:主要管理的数据结构表:1.文件名到数据块列表的映射,这些信息会被持久化到FSimage和日志中。2.所有有效的数据块列表。3.数据块到DataNode的映射,这些信息只会被保存在内存中,并不会持久化。4.从DataNode到数据块的映射。5.最近发送过的心跳信息的DataNode列表。

(14)NameNode控制着两个重要的表:1.filename->blocksequence(namesapce)(一个文件所对的block序列),存放在硬盘当中。2.block->machinelist("inodes")(一个Block所在的machine列表),在每次NameNode启动的时候会被重新创建。

(15)DataNodeID用于唯一的标识一个DataNode,其中使用主机名:端口号的格式标识DataNode的ID名称,同时包含存储介质ID,服务器运行时所用的端口号,NameNode与DataNode进行连接时或者是DataNode之间通讯的时候会使用这个端口号。

(16)ClientDatanodeProtocol是用于和Client交互的,InterDatanodeProtocol是Datanode之间的通信接口。

(17)Magic number一般是指硬写到代码里的整数常量,数值是编程者自己指定的,其他人不知道数值有什么具体意义,ELF文件头会写入一个magic number,检查这个数和自己预想的是否一致可以判断文件是否损坏。在缓冲区数组旁放一个magic number(称作canary金丝雀),通过检查是否一致可检测缓冲区溢出攻击。

猜你喜欢

转载自blog.csdn.net/asdfgggggggg/article/details/51995516
今日推荐