在HDFS分布式存储和管理数据的过程中,为了保证数据的可靠性、安全性、高容错性等特点采用了以下技术。
6.1.5.1 文件命名空间
HDFS使用的系统结构是传统的层次结构。但是,在做好相应的配置后,对于上层应用来说,就几乎可以当成是普通文件系统来看待,忽略HDFS的底层实现。
上层应用可以创建文件夹,可以在文件夹中放置文件;可以创建、删除文件;可以移动文件到另一个文件夹中;可以重命名文件。但是,HDFS还有一些常用功能尚未实现,例如硬链接、软链接等功能。这种层次目录结构跟其他大多数文件系统类似。
对于上层应用来说,HDFS与普通文件系统最大的区别就是文件的副本冗余机制。HDFS中同一文件一般有多个拷贝,拷贝数称为文件的副本因子。每个文件的副本因子可以是不一样的,但一般都是3。这些元数据,还有整个文件系统的命名空间都由NameNode保存和维护。
6.1.5.2 权限管理
HDFS支持文件权限控制,但是目前的支持相对不足。HDFS采用了UNIX权限码的模式来表示权限,每个文件或目录都关联着一个所有者用户和用户组以及对应的权限码rwx(read,write,execute)。每次文件或目录操作,客户端都要把完整的文件名传给NameNode,每次都要对这个路径的操作权限进行判断。HDFS的实现与POSIX标准类似,但是HDFS没有严格遵守POSIX标准。
当用户连接到HDFS进行文件操作时,首先要向HDFS发送自己的身份信息。这个用户信息可以是来自客户端的配置,也可以是直接获取的当前操作系统的用户信息,但是会优先考虑前者。运行NameNode的用户,不需要任何配置,自动成为集群的超级用户。这样的安全策略会导致Hadoop集群面临很多安全问题,用户可以以任何身份访问HDFS,但是在Hadoop1.0.0版本中加入了用JAAS技术实现的安全和授权机制,使得Hadoop集群更加安全稳定。
6.1.5.3 元数据管理
NameNode是HDFS的元数据计算机,在其内存中保存着整个分布式文件系统的两类元数据:文件系统的命名空间,即系统目录树;数据块副本与DataNode的映射,即副本的位置。
对于上述第1类元数据,NameNode会定期持久化,第2类元数据则靠DataNode BlockReport获得。
NameNode把每次对文件系统的修改作为一条日志添加到操作系统本地文件中。比如,创建文件、修改文件的副本因子都会使得NameNode向EditLog添加相应的操作记录。当NameNode启动时,首先从镜像文件FsImage中读取HDFS所有文件目录元数据加载到内存中,然后把EditLog文件中的修改日志加载并应用到元数据,这样启动后的元数据是最新版本的。之后,NameNode再把合并后的元数据写回到FsImage,新建一个空EditLog文件以写入修改日志。
由于NameNode只在启动时才合并FsImage和EditLog两个文件,这将导致EditLog日志文件可能会很大,并且运行得越久就越大,下次启动时合并操作所需要的时间就越久。以Facebook的统计为例,规模为1.5亿个文件,1.5亿个数据块,2 000节点的集群,加载名字空间元数据和等待块位置映射信息上报,每个阶段所耗费的时间大概都在20 min。为了解决这一问题,Hadoop引入Secondary NameNode机制,Secondary NameNode可以随时替换为NameNode,让集群继续工作。
6.1.5.4 单点故障问题
HDFS的主从式结构极大地简化了系统体系结构,降低了设计的复杂度,用户的数据也不会经过NameNode。但是问题也是显而易见的,单一的NameNode节点容易导致单点故障问题。一旦NameNode失效,将导致整个HDFS集群无法正常工作。此外,由于Hadoop平台的其他框架如MapReduce,HBase,Hive等,都是依赖于HDFS的基础服务,因此HDFS失效将对整个上层分布式应用造成严重影响。前面讨论的Secondary NameNode可以部分解决这个问题,但是需要切换IP,手动执行相关切换命令,而且checkpoint的数据不一定是最新的,存在一致性问题,不适合做NameNode的备用机。除了Secondary NameNode,其他相对成熟的解决方案还有Backup Node方案、DRDB方案、AvatarNode方案。
6.1.5.5 数据副本
HDFS是用来为大数据提供可靠存储的,这些应用所处理的数据一般保存在大文件中。HDFS存储文件时,会将文件分成若干个块,每个块又会按照文件的副本因子进行备份。(www.xing528.com)
同副本因子一样,块的大小也是可以配置的,并且在创建后也能修改。习惯上会设置成64MB或128MB或256MB(默认是64MB),但是块大小既不能太小,也不能太大。
(1)块之所以不能太小,主要是因为以下两个方面:一是HDFS大多数操作是在读取大文件,如果块太小,磁盘将会更多地移动磁头,可能使得磁盘寻道时间长,降低了数据的吞吐率。二是每个块对应NameNode内存中一段元数据,块越小,需要维护的数据块的信息就越多,NameNode所消耗的内存就越多。
(2)块之所以不能太大,主要是从上层MapReduce来考虑的。一个是每个节点处理的数据量不能太大;另一个原因是JobTracker会根据块大小预估TaskTracker的处理时间,超过预估时间的节点会被当成故障节点。所以如果块太大,处理时间比较大,而且不好预估。假设某个节点出现故障,系统转交给其他节点的计算任务量也与块大小相关。
6.1.5.6 通信协议
HDFS是应用层的分布式文件系统,节点之间的通信协议都是建立在TCP/IP协议之上的。HDFS有3个重要的通信协议:Client Protocol、Client Data Node Protocol和DataNode Protocol。
(1)Client Protocol定义了客户端和NameNode之间的通信交互,其中定义了常见的文件操作、权限操作和文件的副本操作等。这个协议是基于RPC调用的,一般是由客户端发起RPC请求,NameNode处理后返回给客户端。
(2)Client DataNode Protocol是客户端和DataNode之间的协议,用于恢复块。
(3)DataNode Protocol是DataNode用来和NameNode通信的协议,主要用来发送节点的块信息和负载信息。这个协议也是基于RPC的,NameNode不会主动发起RPC,而是响应DataNode的RPC请求。如果NameNode希望DataNode执行某个命令,也是通过RPC的返回值传给DataNode。该协议的主要方法有节点注册、发送心跳、报告块位置、报告块异常、获得时间戳等。
6.1.5.7 容错
HDFS的设计目标之一是具有高容错性。集群中的故障主要有3类:Node Server故障、网络故障和脏数据问题。
(1)Node Server故障又包括NameNode故障和DataNode故障,前面已经提到了NameNode故障的处理,这里就只考虑DataNode故障。一般情况下,DataNode每隔3 s就向NameNode发送(通过RPC方式)一次心跳信息,NameNode会定期检查DataNode的心跳信息,如果某个DataNode超过一定时间(Stale Interval,一般是10 min)没有发送心跳信息,就认为这个DataNode已经发生故障。
(2)对于网络故障,HDFS采用了与TCP协议类似的处理方式:ACK报文,即每次接收方收到数据后都会向发送方返回一个ACK报文,如果没收到ACK报文就认为接收方发生故障或者网络出现故障。
(3)由于HDFS的硬件配置都是比较廉价的,数据容易出错。为了防止脏数据问题,HDFS的数据都配有校验数据,一般采用CRC32校验,每512字节作为一个chunk(数据块),生成4字节的checksum(校验和)。每隔一定时间,DataNode会向NameNode发送BlockReport以报告自己的块信息。每次DataNode在BlockReport操作之前会先验证数据块的正确性,报告时也只报告正确的数据块。
NameNode收到BlockReport后,如果发现某个DataNode没有上报被认为是存储在该DataNode的块信息,就认为该DataNode的这个块是脏数据。
6.1.5.8 Hadoop Metrics插件
Hadoop Metrics插件是基于JMX(Java Management Extensions,即Java管理扩展)实现的一个统计集群运行数据的工具,能让用户在不重启集群的情况下重新进行配置。从Hadoop0.20开始metrics功能就默认启用了,目前使用的都是Hadoop-Metrics 2。DataNode和NameNode启动后都会向metrics系统注册metrics源,并在运行时把相关数据提供给该系统。集群中所有的metrics数据都可以通过标准的JMX MBean接口查询,也可以使用jconsole查看。
免责声明:以上内容源自网络,版权归原作者所有,如有侵犯您的原创版权请告知,我们将尽快删除相关内容。