NameNode:存储了文件系统上的文件名和元数据,文件和数据块的对应关系
DataNode:用于存储数据节点
Client:客户端,主要包括了一些访问HDFS的接口
注:一个分布式文件系统可以有多个Client,多个DataNode,但只能有一个NameNode

HDFS默认一个块64MB,也可以是128MB。一个文件被分成多个块,以块作为存储单位。块可以分散存储在各个节点之上。
块的大小远远大于普通文件系统,可以最小化寻址开销。
抽象的块概念可以支持大规模文件存储,简化系统设计,而且可以数据备份
注:我们说的节点通常指的是一台计算机。总所周知一台计算机的文件系统是有限的,我们的目标就是找到一个能扩容的文件系统来存放海量的大数据。HDFS就是这样的文件系统,他通过廉价的机器简单连接便可以形成多个节点组成的分布式文件系统。由于HDFS中的文件由多个块组成,块又可以不在某一台机器上,可以分散在多台机器存储,故文件的大小不受单个计算机节点容量的影响。假设现在来了个文件1024MB,你的某个节点计算机只有512MB不够放,没关系,将这个文件拆分为多个块,分散的块存储在不同计算机节点上即可。
我们可以采用冗余的方式去存储块,这样当文件的一部分发生缺失,冗余的块立马作为备份来恢复缺失的数据。
名称节点(NameNode):负责管理NameSpace,并且记录了数据块和DataNode的对应关系。NameNode将自己的数据块处于Linux操作系统的文件系统中。其包含了两个重要的数据结构:FSImage和Editlog。
数据节点(DataNode):根据NameNode和Client的调度对文件进行检索和存储。

HDFS的命名空间包含目录、文件和块
HDFS使用的是传统的分级文件体系,因此用户可以像使用普通文件系统一样创建、删除目录和文件,在目录间转移文件,重命名文件等
NameNode维护文件系统命名空间。对文件系统命名空间或其属性的任何更改均由NameNode记录(NameNode的EditLog记录)。
HDFS是一个部署在集群上的分布式文件系统,因此,很多数据需要通过网络来传输
所有的HDFS通信协议都是构建在TCP/IP协议基础之上的
客户端通过一个可配置的端口向名称节点主动发起TCP连接,并使用客户端协议与名称节点进行交互
名称节点和数据节点之间则使用数据节点协议进行交互
客户端和数据节点的交互是通过RPC(Reote Procedure Call)来实现的。在设计上,名称节点不会主动发起RPC,而是响应来自客户端和数据节点的RPC请求。
客户端是用户操作HDFS最常用的方式,HDFS在部署时都提供了客户端
HDFS客户端是一个库,包含HDFS文件系统接口,这些接口隐藏了HDFS实现的底层
严格来说,客户端不算是HDFS的一部分
客户端可以支持打开、读取、写入等常见操作,并且提供了类似shell的命令行方式来访问HDFS中的数据
HDFS也提供了JavaAPI,作为应用程序访问文件系统的客户端编程接口
HDFS只设置一个名称节点这样会带来局限性:
心跳机制。Slave通过心跳给master汇报自身消息,master通过心跳下达命令。在Hadoop1.x中,由于HDFS是单名称节点结构,当名称节点故障时,需手动停止HDFS的运行,并把FSImage和EditLog的备份传给名称节点让其重新启动,这样的话在停止的时候HDFS是不可用的。
在Hadoop2.x中,HDFS采用了双名称节点模式,即存在active名称节点和stand by名称节点。stand by名称节点分担了1.x版本中名称节点存储HDFS元数据的功能,这样缓解了命名空间的限制问题,还可以保重集群的可用性问题,一旦active名称节点故障,ZooKeeper会监测到其心跳异常,此时通知stand by名称节点暂且代替主名称节点的位置进行工作,直至active名称节点被修复。

元数据持久化的特性在Hadoop1.x版本中就存在,这一特性体现在第二名称节点(SecondaryNamenode)之上。第二名称节点和stand by节点指的不是同一个东西。
HDFS中FSImage维护了文件树和文件树中的文件和文件名元数据。对一个文件进行操作是在客户端进行的,在客户端修改的一瞬间,第二名称节点从名称节点中接手FSImage和EditLog,EditLog产生文件EidtLog.new文件,根据EditLog中对文件执行的操作来更新文件的元数据,我们称之为合并,合并的结果是产生一个FSImage.ckpt文件。合并完成后,FSImage被更新,传回名称节点,名称节点将FSImage回滚为FSimage,并将老版本的FSImage删除,EditLog.new取代EditLog成为新的EidtLog。
在这个过程中,若更新中途名称节点提交数据结构给第二名称节点后宕机,则可以通过第二名称节点的FSImage和EditLog可以进行冷备份(即备份过程中不能使用Hadoop集群)。
这是Hadoop2.x的出现的特性。
在过去只有一个名称节点的情况下,我们常会因为受到内存的限制而使得NameNode保存的文件元数据有限,为此我们受到联邦数据库的启发在HDFS中采用了联邦机制,设立多个名称节点,以增加命名空间,提高HDFS的吞吐量。

在Hadoop1.x就存在。
对于伪分布式式来说HDFS默认冗余复制副本为1个,完全分布HDFS默认的冗余复制副本是3。其中,有两份副本放在同一个机架的不同机器上面,第三个副本放在不同机架的机器上面,这样既可以保证机架发送异常时的数据恢复,也可以提高数据读写性能。
HDFS主要目的是保证存储数据完整性,对于各组件的失效,做了可靠性处理。
空间回收机制:支持回收站机制,以及副本数的动态设置机制。
数据组织:数据存储以数据块为单位,存储在操作系统的HDFS文件系统上。
访问方式:提供Java API、HTTP方式,shell方式访问HDFS数据。
| 命令 | 范例 |
|---|---|
| hdfs dfs 常用文件系统操作命令 | hdfs dfs -cat ~/emp/* |
| hdfs dfsadmin -safemode | 安全模式操作 |
| hdfs dfsadmin -report | 报告服务状态 |


Zookeeper分布式服务框架主要是用来解决分布式应用中经常遇到的一些数据管理问题,提供分布式、高可用性的协调服务能力。
安全模式下的Zookeeper依赖于Kerberos和LdapServer进行安全认证,非安全模式则不依赖。Zookeeper作为底层组件广泛被上层组件使用并依赖,如Kafka,HDFS,HBase,Storm等。
Zookeeper如同Hadoop一样也是采用主从Master/Slave架构。
Zookeeper集群由一组Server节点组成,这一组Server节点只存在一个Leader节点,其他节点都为Follower。
启动时选举出leader,如果某个Server获得半数以上的票数时,则当选为leader。
Zookeeper使用自定义的原子消息协议,保证了整个系统中的节点数据的一致性。
Leader节点在接收到数据变更请求后,先写磁盘再写内存。
对于n个实例的服务,n可以为奇数或偶数。
n为奇数时,假定n =2x+1,则成为leader的节点需获得x+1票,容灾能力为x
n为偶数时,假定n=2x+2,则成为leader的节点需要获得x+2票,容灾能力为x

最终一致性:无论哪个server,对外展示的均是同一个视图。
实时性:保证客户端将在一个时间间隔范围内获得服务器的更新信息,或者服务器失效的信息。
可靠性:一条消息被一个server接收,它将被所有server接收
等待无关性:慢的或者失效的client不会干预快速的client的请求,使得每个client都能有效的等待
原子性:更新只能成功或者失败,没有中间状态。
顺序一致性:客户端所发送的更新会安装它们被发送的顺序进行应用。
由Zookeeper的一致性可知,客户端无论连接哪个server,获取的均是同一个视图。所以,读操作可以在任意客户端与任意节点间完成。
Zookeeper中如果客户端连接到Follower,则需要结果leader转接之后才可写入其他的Follower。
| 命令 | 作用 |
|---|---|
| zkCli.sh -server 服务器ip | 调用ZooKeeper客户端 |
| create /node | 创建节点 |
| ls /node | 列出节点下子节点 |
| set /node data | 创建节点数据 |
| get /node | 删除节点数据 |
| delete /node | 删除节点 |
| deleteall /node | 删除节点及其子节点 |