HDFS概述
分布式文件系统特点
- 超大存储
- 流式数据访问
- 适用于一次写入
- 多次读取
- 高吞吐吞吐量
- 不适用于低时间延时的数据访问
- Hbase更低延时
- 不适用于小文件
- 大量小文件会导致太多的元数据
- 可以使用相关容器
基本概念
数据块
- 一个文件被划分为多个块
- 独立存储的单位
- 默认128MB
- 为了最小化寻址开销
- 优势
namenode
- 管理文件系统的命名空间
- 记录每个文集各个块的信息
datanode
- 负责管理用户的文件数据块
客户端
- 与NameNode和DataNode交互
防止单点故障
- hdfs存在单点故障问题
- 持久化内存元数据
- 辅助namenode
- hdfs HA
块缓存
- 频繁读取的文件,会以堆外块缓存的方式缓存
- 用来提高读取速度
计算跟着数据走
掌握程度
- 知道 NameNode Client DataNode之间的交互过程
- 知道客户端读取,写入等操作的流程
- 知道checkpoint原理
- 知道HA原理
- 知道DistributedFileSystem类的源码
HDFS上的文件格式
普通序列化存储
- Writable
- 默认序列化存储
- Avro格式
- 数据序列化的系统
- 语言无关序列化系统
- 目的就是为了解决writable的与语言缺陷
- 支持模式演进
- 读取文件的模式不需要与写入文件的模式严格匹配
- 当需求发生变更时,模式中可以添加新的字段
- 它能够存储元数据,还可以把元数据单独存储到一个文件中
- 支持RPC
- 基于二进制数据传输高性能的中间件
- 三种Record操作方式
- generic: 负责基于Schema(String)的映射操作
- specific: 负责基于代码生成类的映射操作
- reflect: 负责基于java反射的映射操作(这部分没看,不清楚)
- Thrift
- RPC层非常健壮
- Protocol Buffer
- 不支持RPC
sequenceFile
- 二进制的
- 类似一种容器
- K-V对
- 不存储元数据
提供压缩
- 三种级别的压缩
- None
- recored
-记录压缩类型:记录压缩格式与无压缩格式基本相同,不同的是值字节是用定义在头部的编码器来压缩 – 即 Key是不压缩的 - 块压缩一次压缩多个记录,因此它比记录压缩更紧凑
优缺点
- A.支持基于记录(Record)或块(Block)的数据压缩。
- B.支持splitable,能够作为MapReduce的输入分片。
- C.修改简单:主要负责修改相应的业务逻辑,而不用考虑具体的存储格式。
- 需要一个合并文件的过程,且合并后的文件不方便查看
parquet
- 一种存储格式,它是语言、平台无关的
- 真正的列式存储
- 灵活的压缩
- 二进制存储
- 不可以直接读取
- Parquet格式文件是自解析的
- 可以灵活的写入
- Writable
- Avro
- Protocol
- Buffers
列式存储优缺点
- 更高的压缩比
- 相同类型的数据更容易针对不同类型的列使用高效的编码和压缩方式
- 更小的I/O操作
- 于映射下推和谓词下推的使用,可以减少一大部分不必要的数据扫描
- 表结构比较庞大的时候更加明显,由此也能够带来更好的查询性能
- 写速度通常比较慢
RCFile
- 先水平切Row,再垂直切Column
- 是Hadoop中第一个列文件格式
- 优点如parquet
ORCFile
- Optimized,表示优化的RC文件格式。
- 相比RC能够更好的压缩,能够更快的查询,但还是不支持模式演进
- 优点如parquet
Hbase
- 特点
- nosql数据库
- 提供数据随机访问
- 可以理解为一个巨大的hash表
- 优缺点
- 快速
体系结构
client
客户端
namenode
- 负责客户端请求的响应
- 目录管理
- 元数据的管理(查询,修改)
- 内存元数据(NameSystem)
- 磁盘元数据镜像文件
- 数据操作日志文件(可通过日志运算出元数据)
- FsImage和Edits是HDFS的核心数据结构
checkpoint原理
- Checkpoint节点周期性地创建命名空间的检查点
- 它从NameNode下载fsimage和edits,在本地合并它们
- 并将其发回给活动的NameNode
- 应用
- 在非高可用状态
- 存在在secondNameNode中
- 高可用状态下
- 处于standby状态的NameNode来做合并操作
- fsimage
- 镜像文件
- 存储在Namenode上的元数据信息
- 它是最新的已执行检查点的命名空间的信息
- edits
- 操作日志
- 记录对metadata的操作
- 它是执行检查点后命名空间变化的日志文件
datanode
- 存储管理用户的文件块数据
- 定期向namenode汇报自身所持有的block信息
SecondaryNameNode
- 冷备
- 做checkpoint的
- SecondNameNode的主要功能是执行checkpoint功能从而减少NameNode启动时间
- 它不是NameNode的备份,但可以作为NameNode的备份
- 可以用SecondNameNode中已合并的fsimage文件作为备份文件恢复到NameNode上
通信协议
RPC接口
- clientProtocol
- 客户端与NameNode之间
- ClientDataNodeProtocol
- 客户端和数据节点
- DataNodeProtocol
- NameNode和DataNode
- InterDataNodeProtocol
- 数据节点之间
- NameNodeProtocol
- NameNode之间的传输
流式接口
- TCP
- DataTransferProtocol
- HTTP
- HA架构中
HA
QJM/Qurom Journal Manager
基于Paxos算法 存在standby NN 和 active NN
- 用2N+1台 JN 存储EditLog
- SecondaryNameNode这个冷备角色已经不存在
- 任何修改操作在 Active NN上执行时,JN进程同时也会记录修改log到至少半数以上的JN
- 这时 Standby NN 监测到JN 里面的同步log发生变化了会读取 JN里面的修改log,然后同步到自己的的目录镜像树里面
客户端fencing
- 确保只有一个NN能响应客户端请求
- 让访问standby nn的客户端直接失败
- 在RPC层封装了一层,通过FailoverProxyProvider以重试的方式连接NN
ZKFailoverController角色 ZKFC
- 部署在每个NameNode的节点上,作为一个deamon进程,
- 责任
- master选举
- 监控NameNode是否处于unavailable或unhealthy状态
- 管理和监控自己在ZK中的状态
- 它订阅HealthMonitor 和ActiveStandbyElector 的事件,并管理NameNode的状态
- 优势
- 不需要配置额外的高共享存储,降低了复杂度和维护成本
- 消除spof
- 单点故障
- 系统鲁棒性(Robust:健壮)的程度是可配置
- JN不会因为其中一台的延迟而影响整体的延迟,而且也不会因为JN的数量增多而影响性能(因为NN向JN发送日志是并行的)
- 存在的问题
- 如何保持主和备NameNode的状态同步
- 并让Standby在Active挂掉后迅速提供服务
防止脑裂Fencing
确保只有一个NN 指在一个高可用(HA)系统中,当联系着的两个节点断开联系时,本来为一个整体的系统,分裂为两个独立节点,这时两个节点开始争抢共享资源,结果会导致系统混乱,数据损坏
DN在运行过程中维护此序列号,当failover时,新的NN在返回DN心跳时会返回自己的active状态和一个更大的序列号。DN接收到这个返回是认为该NN为新的active
如果这时原来的active(比如GC)恢复,返回给DN的心跳信息包含active状态和原来的序列号,这时DN就会拒绝这个NN的命令。
流程
客户端读取流程
- open方法
- DFSInputStream
- DistributedFileSystem
- DFSClient.open()
- 从NameNode获取DataNode地址
- 获取元数据
- 选取最优的DataNode
- 简历socket流
- 连接到DataNode读取数据
- 若读取出现异常,则切换到下一个节点
HDFS客户端写流程
- create()
- 检查目录文件等
- 创建一个新文件
- NameNode在文件系统目录树下创建新文件
- 建立数据流管道
- 先申请一个新的数据块
- 建立后,写入数据
- 先缓存在数据流中
- 然后发送到其中一台节点
- 这一台再发给所有的数据节点
- 依次写入数据节点的本地存储
- 一个Block传输完成后,再传下一个
追加写流程
- 判断最后一个数据块是否写满了
- 没有的话继续写