1 HDFS架构
HDFS采用主从架构
主节点 : NameNode 文中简称NN
从节点 : DataNode 文中简称DN
1.1 NameNode
- 存储元数据 , 记录用户操作的日志
- 接收NN节点的注册 , 向DN分配集群ID(clusterID) , 指定存储数据的目录
- 接收客户端的请求 , 向客户端返回元数据或响应
- 维护集群的负载均衡 , 维护数据副本个数
- 监控DN的心跳信号 , 接收DN的汇报 , 更新元数据 , 向DN分配复制副本的任务
- 提供统一的虚拟目录供用户访问
1.2 DataNode
- 将数据以物理切块的形式存储到指定目录
- 接收处理客户端的请求
- 向NN注册 , 汇报
- 通过心跳机制接收NN分配的任务 , 完成副本的复制移动工作
2 NameNode和DataNode之间的通信
- 首次通信时需要DN向NN注册
- NN向DN返回集群ID , 唯一的UUID , 指定的存储数据目录
- DN定期向NN汇报存储情况
- DN每隔3s向NN发送一次心跳信号
- NN监控DN的心跳信号 , 并通过心跳机制向DN分配任务 , 发出指令
- DN10min30s内没有响应 , 会被踢出节点
3 上传数据
- 客户端向NN发送上传数据的请求
- NN返回OK
- 客户端本地按照规则将数据进行物理切块 , 并向NN请求上传第一块数据
- NN记录选好的DN节点元数据信息 , 将元数据信息返回给客户端
- 客户端根据元数据信息向DN发送上传请求
- DN返回OK
- 客户端本地IO流读取第一块数据 , 以分布式输出流向DN传输数据 , DN以分布式输入流读取数据 , 再写入磁盘
- 重复步骤3-8
上传数据时 , DN节点之间连接方式
例如 , 客户端和元数据信息中的第一个DN节点链接 , 请求上传数据
第一个DN节点负责和另外两个节点建立连接 , 客户端只要能和第一台建立连接便认为可以上传数据(即使第一个节点和另外两个节点连接失败) , 第一个节点还负责将数据传输给另外两个节点 , 如果另外两个节点连接失败/故障 , NN会分配复制副本的任务给其他节点
4 下载数据
- 客户端向NN发送下载数据的请求
- NN返回元数据信息给客户端
- 客户端根据元数据信息向DN请求下载数据 , 下载就可以了
4 元数据存储位置和策略
4.1 NameNode和SecondaryNameNode
- NameNode记录元数据信息 , 为了安全 , SecondaryNameNode从NameNode中下载元数据备份
- 但元数据是要写入磁盘的 , 效率太低 , 用户可等不了这么长时间
- 因此采用在内存中创建记录用户操作的日志 , 再回放日志与旧的元数据合并 , 获取新的元数据
- 为了让元数据可靠(当NN宕机时 , 日志会被删除)和减少NN工作压力 , 选择让SNN从NN中下载日志 , 在SNN上回放日志 , 每操作100万次或一小时 , SNN将最新的元数据发送给NN
4.2 单点故障问题和日志实时更新问题
- NN宕机 , 用户需要可供访问的节点 , 集群也需要主节点维护负载均衡 , 因此需要NN2在NN宕机后提供服务
- 此时便产生一个问题 , NN宕机后 , 怎么保证NN2可以及时获得通知 , 变为活跃状态
- 为了解决这个问题引入zookeeper(分布式资源调度和任务监控平台) , zookpper监控NN的状态 , NN时刻向zookeeper汇报状态 , NN没有汇报时 , zookeeper通知NN2成为主节点 , 若此时NN恢复 , NN2便会Kill掉NN(主从结构只需要一个主节点)
- 单点故障解决了 , 此时NN2在取代NN之前和SNN工作是一样的 , 都是下载日志 , 回放日志 , 向NN传输最新的元数据 , 但传输是通过网络进行的 , 当网络波动就可能导致NN2中日志没有及时下载 , NN就宕机了 , NN中的日志丢失 , 部分用户操作无法回放
- 因此引入日志集群 , 由日志集群从NN实时更新日志 , 并保存在集群中 , NN即使宕机了 , NN2依然可以获取最新的日志 , 通过日志回放获取最新的元数据 , 保证元数据的安全