Hadoop应用实战
上QQ阅读APP看书,第一时间看更新

3.2 Hadoop核心基础架构

Hadoop系统上有很多不同的组件,在本节中我们讨论的是对Hadoop起到重要作用的核心组件。

3.2.1 Namenode和Datanode

Namenode又称为MasterNode,主节点;Datanode又称为SlaveNode,从属节点。合在一起,Namenode和Datanode之间有Master和Slave的关系,或者说从属关系在计算机领域,Master和Slave是常用的关系词,用来表示主导和跟随的状态。在数据库领域、网络节点上都经常用到。

对于Namenode和Datanode节点还有各种不同的说法,比如“管理节点”和“工作节点”等,都说明数据节点是不可以脱离主节点单独存在的。

在Datanode上,有一个后台的同名进程(Datanode),用以管理数据节点上所有的数据块。通过这个进程,数据节点会定期和主节点通信,汇报本地数据的状况。

在Hadoop系统进行设计的时候,对数据节点作了以下的假设。

(1)数据节点主要用来作存储,额外的开销越小越好;

(2)对于普通的硬盘来说,任何硬盘都可能会失败;

(3)文件和数据块的任何一个副本都是完全一致的。

因为数据节点上采用的一般是普通硬盘,那么每块硬盘失效的概率大概是每年4%~5%。如果我们的系统上有100个数据节点,而每一个数据节点都有12块硬盘,那么平均每周都会需要更换至少一块硬盘。

正是因为这些假设,默认Hadoop系统上每个文件和数据块都有三个副本,而当中间任何的一个副本出现问题的时候,系统都会把对文件和数据块的访问切换到其他的副本上,并会重新设置使得文件和数据块都保持有三个副本。

对于Hadoop的用户来说,他们并不需要了解数据存储的细节,也不需要知道文件的各个数据块是存储在哪些数据节点上的,他们只需要对文件进行操作,对应的拆分和多个副本的存储是由系统自动完成的。

和Datanode一样,Namenode节点上也有一个同名的后台进程(Namenode),而所有的文件匹配信息则保存在一个名为fsimage的文件中,所有新的操作修改保存在一个名为edits的文件中。edits文件中的内容会定期写入fsimage文件中。

把fsimage和edits文件中的信息综合起来,我们就可以知道所有的数据文件和对应的数据块的具体位置,而这些信息都会保存在Namenode节点的内存中。

主节点和数据节点之间的通信协议如下。

(1)每隔3s,数据节点都会发送心跳(heartbeat)信息在网络上,心跳(heartbeat)也是一个常用的说法。就像人有心跳一样,服务器也要有心跳,如果心跳信息缺失了,就说明这台服务器可能失效了,需要作处理。给Namenode节点,所以Namenode永远都会实时知道哪些数据节点是在线的;

(2)每隔6h,数据节点会发送完整的数据块报告给Namenode,所以Namenode会知道系统上各个文件和相关数据块的准确位置。

这里的3s和6h都可以配置,这两个数值是默认值。

文件和数据存储在数据节点的信息是保存在主节点上的,所以对于众多数据节点来说,主节点就像是一个指挥中心或者地址黄页。换句话说,只有主节点才能准确指引用户对每个文件的访问。

那么Namenode节点一旦失效该怎么办?我们会在第13章中专门讨论Namenode节点的高可用性问题。

最后我们来看一下文件是如何写入系统中的,如图3-2所示。

图3-2 在Hadoop系统上创建文件的流程

图3-2中提到的“合约”是Namenode上的一个小工具,确保文件和副本能够被安全创建。

因为在一个Hadoop系统上只有Namenode节点才知道数据文件是如何存储的,所以所有的读请求都是发送给Namenode节点,由它来进行分配的。

3.2.2 Hadoop底层的文件系统HDFS

在HDFS上,存储的内容可以是任何格式,而描述文件内容的是宏数据或称元数据(MetaData),也就是说,存储在HDFS上的内容是由结构化或者非结构化的文件与宏数据共同组成的,如图3-3所示。

图3-3 HDFS上的存储内容

为了便于存储和管理,HDFS上的文件都被切割成固定大小的数据块,如图3-4所示。

图3-4 HDFS上一个文件的切分

图3-4中HDFS上所有的文件都被切成固定大小128MB的数据块(block),只有最后一个数据块的大小是变化的。而当新的数据写入使得数据块大小超过系统设定值之后,新的数据块会产生。而系统的默认值是64MB。

注意:数据块大小是系统配置的。我们在这里设置的128MB是根据对应的场景而来的。在不同的场景中,数据块的大小设置是不一样的。对于通用场景,128MB一般是可以的,如果整体数据量比较大,这个设定值可能还要提升。

我们下面来看在HDFS上的数据备份方案,如图3-5所示。

图3-5 HDFS上数据块节点的分布

图3-5中所有的数据块被分解到不同的数据节点上,a、b、c、d数据块能够组合成一个完整的数据文件,这些数据块被分解到不同的机架和数据节点上,所以任何数据节点甚至机架的失效都不会影响数据文件的完整性。而这正是Hadoop系统设计的主要目标之一,假设条件是任何的硬盘、计算机和网络设备都可能出错。

当磁盘或者数据节点发生错误之后,HDFS会发现这个问题,并且把原本在这个磁盘或者数据节点上的副本重新分配到其他的数据节点上。

注意:HDFS并不是一个普通的文件系统,它只能在文件的最后添加数据,而不能搜索到文件的中间去添加内容。

在Hadoop上对文件系统的操作都是通过Hadoop命令来完成的。命令的格式如下:

        Hadoop [--config confdir] [COMMAND] [GENERIC_OPTIONS][COMMAND_OPTIONS]

命令说明:

使用-config confdir选项的时候,默认的配置文件目录(默认在$Hadoop_HOME/conf)会被替换。

和Linux系统类似,HDFS一共提供三类权限模式。

(1)只读权限(r);

(2)写入权限(w);

(3)可执行权限(x)。

一般情况下,如果只涉及读取文件,那么只读权限是足够的。

如果要看HDFS上支持的所有命令,可以使用以下的命令行:

        Hadoop dfs -file_cmd

不用考虑HDFS的具体实现,Hadoop可以很方便地通过shell命令行来完成文件系统的操作。操作方式就是调用Hadoop命令并加上“dfs”参数。比如,可以用下面的命令行来构建一个目录,并查看其中包含的文件内容:

        Hadoop dfs -mkdir/data/weblogs/20160517/data/weblogs/20160517
        Hadoop dfs -ls/data/weblogs

这里,mkdir和ls都是对文件系统直接的操作,前者是创建文件夹,而后者是查看文件夹中的文件。

至于每条命令行参数的详解,有兴趣的读者可以参阅附录D。

3.2.3 Hadoop上的数据库HBase

简单来说,HBase就是一个分布式的数据存储系统,而它的设计思想就是一个字——“大”,因为HBase源于Google公司的BigTable,主要体现在以下三个方面。

(1)数据量可以很大,可以有很多行。

(2)数据维度可以很多,可以有很多列。

(3)HBase可以在很多台服务器上运行。

读者们可能观察到,在上述的描述中,我们用的是“很多”这个词,而不是一个具体的数字,因为数量究竟大到什么地步也是在变化的。在我们看到的实例中,数量在十亿条以上的数据已经不罕见了,数据维度也可以轻松到达几千个,同时在上千台服务器上运行HBase的实例也很常见了。

和普通的数据库不同,HBase是一个面向列的数据库,而正是这个原因,HBase不能直接支持SQL语句。

和传统数据库相比,HBase的不同之处在于:

(1)是NoSQL数据库关于NoSQL数据库,请参见第6章的内容。,不是传统数据库;

(2)不遵从ACID原则ACID是图灵奖获得者Jim Gray提出的概念。关于ACID,请参见第6章。

(3)跨表格的Join操作是不被支持的;

(4)数据可能有重复;

(5)没有真正意义上的索引,所以也不会出现索引膨胀的问题;

(6)可以用普通的硬件,不需要用专业的数据库服务器,HBase的容错性会解决节点的时效性问题。

HBase并没有试图解决所有在数据库层面出现的问题,只是用来解决海量数据的存储,和业务相关的应用是在HBase之上的。那么对于应用程序开发者来说,他们只需要集中处理实际的业务逻辑,而并不需要关心数据库的具体实现。

我们来看一个存储有顾客信息的HBase表格,见表3-1。

表3-1 HBase表格内容示例

在表3-1中的数据有三列,第一列是RowKey(行键),第二列是CustomerName(用户名),第三列是ContactInfo(联系方式),其内容是以Column Qualifier:Version:Value这样的方式存放的,Column Qualifier是列说明,Version是版本号,Value是最终的数值。

说明一下,因为Column Qualifier列说明也是存储在HBase里占用存储空间的,所以我们一般会用缩写而不是完整的词汇。在表3-1中,我们用缩写来表示每一列:

(1)'FN'是First Name的缩写,名;

(2)'LN'是Last Name的缩写,姓;

(3)'MN'是Middle Name的缩写,中间名字;

(4)'MA'是Mailing Address的缩写,邮寄地址;

(5)'EA'是Email Address的缩写,邮件地址。

比如'FN': 1428854563103: 'Cody'说明顾客的名字是Cody,而对应的版本号是1428854563103。

表中00011行MN出现了两次:

        'MN': 1428859183001:'Wu',
        'MN': 1428859182915:'W'

表示MN在两个不同的版本中对应于不同的数值,这里的版本号其实是从1970年1月1日世界标准时间之后经历过的系统时间(以微秒计数)。

每一行的键(key)是所有数据中最关键的,因为选择一个好的键可以帮助我们优化数据库存储和查询。

在HBase的官方参考书中(http://HBase.apache.org/book.html#schema.casestudies)有专门的篇幅来介绍在HBase上如何设计键(key),其中有些关于日志采集、客户订单的案例是很实用的。

在第6章我们还会专门就NoSQL和数据仓库的内容展开更加详细的讨论。