大家还记得我们如何向 Hadoop cluster 提交任务吗?是通过 Hadoop client 进行的。
同样,我们和 HDFS 打交道也是通过一个 client library. 无论读取一个文件或者写一个文件,我们都是把数据交给 HDFS client,它负责和 Name nodes 以及 Data nodes 联系并传输数据。
Name Nodes
我们在之前的文章中简要提及过 HDFS 把文件存在多个机器上,并且不把“在哪些机器上存的”,“如何存的”这些内部的信息暴露给使用者,而是只显示给用户一个像普通 linux 文件结构的文件系统。
那么,是谁在管理这些信息的呢?这就是 Name nodes.
在 HDFS 里, Name node 保存了整个文件系统信息,包括文件和文件夹的结构。其实和 linux 上的真的很像, HDFS 也是把文件和文件夹表示为 inode, 每个 inode 有自己的所有者,权限,创建和修改时间等等。HDFS 可以存很大的文件,所以每个文件都被分成一些 data block,存在不同机器上, name node 就负责记录一个文件有哪些 data block,以及这些 data block 分别存放在哪些机器上。
Name nodes 还负责管理文件系统常用操作,比如创建一个文件,重命名一个文件,创建一个文件夹,重命名一个文件夹等。
当我们通过 HDFS client 向 HDFS 读取或者写文件时,所有的读写请求都是先发给 Name nodes, 它负责创建或者查询一个文件,然后再让 HDFS client 和 Data nodes 联系具体的数据传输。
Data Nodes
存储 data block 的机器叫做 Data nodes. 在读写过程中,Data nodes 负责直接把用户读取的文件 block 传给 client,也负责直接接收用户写的文件。
当我们读取一个文件时:
HDFS client 联系 Name nodes,获取文件的 data blocks 组成、以及每个 data block 所在的机器以及具体存放位置;
HDFS client 联系 Data nodes, 进行具体的读写操作;
重要的事情说三遍。在读写一个文件时,当我们从 Name nodes 得知应该向哪些 Data nodes 读写之后,我们就直接和 Data node 打交道,不再通过 Name nodes.
大家猜猜企业存储数据时最头疼的事情是什么?
实际操作中最头疼的事,不是数据量太大或者读写速度不够快,而是数据丢失。
有很多企业存储着客户重要信息,尤其是和钱打交道的信息,一旦丢失,会造成很坏的经济和声誉影响。而实际中,一个中等大小的数据中心就有上千台机器存储数据,这些机器每天都在高负荷运转,所以发生故障,比如硬盘损毁,或者电源故障,经常发生。有多经常?Google 做过统计,Google 全世界运行的数据中心中,每年有1000台机器要出故障,几千个硬盘会出错,一个电源分配设备出故障,造成500到1000台机器停止运行6小时。
那么 HDFS 是如何保证在机器故障情况下文件数据依然不丢失的呢?如题,就是数据备份,说白了就是多存几份。那究竟多存几份呢?这是一个可以配置的参数,从1到很大;如果我们不去配置,HDFS 默认3份。
不知道大家有没有去过数据中心,就是存放运行 Hadoop 和 HDFS 的机器的地方,那里的计算机和我们平常用的 PC 不太一样,有若干台机器垂直地组成一个 Rack,像一个书架一样。
通常,一个 rack 共享一个电源,一条网线,一个交换机;据统计,很多数据中心里的故障都是一整个 rack 出问题。出于这个原因,HDFS 备份数据的时候,(假设还是3份),通常在同一个 rack 上储存一份,然后在另一个 rack 上储存另两份。这样就保证数据有更高的安全性。
别忘了 HDFS 存储文件是以 block 为单位的,所以备份也是以 block 为单位的。
Name nodes 也需要知道每个 Data node 所在的 rack, 这样才能给 client 提供准确信息 。这个知识是 HDFS 启动时数据中心管理员配置给 Name nodes 的。
问题来了:如果 HDFS 为每一个 block 存三份,那 client 如何来写呢?同时向三个 data node 写吗?
不是的。当 client 写文件创建新 block 的时后,Name nodes 会为这个 block 创建一个整个 HDFS cluster 里独有的 block ID,并且决定哪些 Data nodes l来存储这个 block 的所有备份。这些被选择的 Data nodes 组成一个队列,client 向队列的第一个 Data node 写,那么第一个 Data node 除了把数据存在自己的硬盘上以外,还要把数据传给队列里的下一个 data node,如此这般,直到最后一个 data node 接到数据完毕。如下图所示
同样的,当 HDFS client 读取一个文件时,它首先从 Name nodes 获得这个文件所有 blocks 和每个 block 的所有备份所在机器位置。当 client 开始读取 block 时,client 会选择从“最近”的一台机器读取备份(“最近”指的是网络延迟最短),如果第一个备份出现问题,比如网络突然中断,或者硬盘出故障,那 client 就从第二个备份读,以此类推。
综上,这篇文章洋洋洒洒为大家介绍了 HDFS 的架构和如何实现读写容错。其实容错性对于所有分布式系统都是个重要问题,下篇文章我们就为大家介绍 Hadoop MapReduce 是如何实现容错的,这也是 Hadoop 被称为业界良心的重要原因之一,欢迎大家继续关注我们。