设计考量
HDFS设计假设、目标
- 硬件失效
- 硬件的异常比软件的异常更加常见
- 流式数据访问
- Dataflow
- hdfs是量身定制,并非以通用业务为目的
- 关注吞吐量,并非响应时间
存储数据较大
简化的数据一致性模型
- 数据写入之后,不允许再修改了,只允许在后面追加
- 多硬件平台支持
- 易于运行不同的平台上(故用java编写)
- 移动计算能力比移动数据更划算
- 计算和存储采用就近原则,计算离数据最近
- 移动计算就是移动代码,对远程的数据进行计算
如何应对大文件
文件由数据块集合组成
- 通常每块大小为64MB
- 与os的块的区别:
- os的目的:省io的时间、不满还是会占整个block的大小的
- hdfs目的:把大的文件切小、不满是不会占64mb的
索引文件
- 跨机器索引
HDFS 架构
HDFS节点类型
- NameNode 每个集群一个名字节点(master)
- 负责文件系统元数据操作、数据块的复制和定位
- SecondaryNamenode NameNode的备份
- Datanode
NameNode :
- 作用:管理节点、接收用户的操作请求
- 核心数据文件包括:
- 元数据镜像文件fsimage: 维护文件系统树以及文件树中所有的文件/目录的元数据
- 操作日志文件EditLog: 记录所有针对文件的创建、删除、重命名等操作。
- 如果元数据镜像文件可以承受恢复的代价,那么日志也可以不需要了,日志为了减轻元数据镜像文件的负担。
- 元数据保存在内存中
- 做了block和datanode之间的映射关系
SecondaryNameNode
- 执行过程:
- 定期从Namenode上下载fsimage,edits,二者合并,生成新的fsimage
- 在本地保存,并写回NameNode
- 它是“检查点”,而不是“热备份”(即并非实时备份)
DataNode
- 作用:一共文件的存储
- 文件块:一个Linux文件
- HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间
- 数据备份:默认是三个
- 文件内容保存在磁盘
文件访问
文件写入HDFS
- NameNode 告知客户端文件的每一个数据块存储在何处
b. 客户端将数据块直接传输到指定的数据节点数据访问
从HDFS读取文件
- 从NameNode 返回每个数据块的位置给客户端
- 从数据节点上传数据块(不同的数据块可以并行读取)
数据读取策略
文件访问模型
- “一次写入多次读取”
- 修改内容需删除,重新写入
- 仅允许追加append()
- 注: 此为追加一个block,而不是在原来的block追加内容
- 好处:避免读写冲突,无需文件锁
HDFS数据备份
备份与一致性
一个文件有若干备份
备份之间是否可能不一致?
- 同时append两个备份
容错机制
HDFS在设计时就考虑到故障(硬件和软件)会经常出现
DataNode故障:
- “宕机”:节点上面的所有数据都会被标记为“不可读”
- 定期检查备份因子
NameNode故障
- 根据SecondaryNameNode中的Fslmage和Editlog数据进行恢复
其他故障
- 磁盘错误或故障:数据校验
- 交换机/机架故障
- 数据中心故障
HDFS功能
适用:
- 大文件存储、流式数据访问
不合适:
- 大量小文件(无法完美利用数据并行读取)
- 随机读取(因为有固定的代价)
- 低延迟读取