文件系统
所谓传统常见的文件系统更多指的的单机的文件系统,也就是底层不会横跨多台机器实现
比如windows操作系统上的文件系统、Linux上的文件系统、FTP文件系统等等
这些文件系统的共同特征包括:
- 带有抽象的目录树结构,树都是从/根目录开始往下蔓延
- 树中节点分为两类:目录和文件
- 从根目录开始,节点路径具有唯一性
数据
指存储的内容本身,比如文件、视频、图片等,这些数据底层最终是存储在磁盘等存储介质上的
一般用户无需关心,只需要基于目录树进行增删改查即可,实际针对数据的操作由文件系统完成
元数据
元数据(metadata)又称之为解释性数据,记录数据的数据
文件系统元数据一般指文件大小、最后修改时间、底层存储位置、属性、所属用户、权限等信息
问题
- 性能低
- 单节点I/O性能瓶颈无法逾越,难以支撑海量数据的高并发高吞吐场景。
- 可扩展性差
- 无法实现快速部署和弹性扩展,动态扩容、缩容成本高,技术实现难度大
分布式存储
分布式存储系统核心属性:
分布式存储
- 无限扩展,支撑海量数据存储
元数据记录
- 快速定位文件位置,便于查找
- 副本数,数据块,存储位置
分块存储
- 分块存储在不同机器上
- 针对块
并行操作
, 提高效率
副本机制
- 不同机器设置备份
- 冗余存储,保障数据安全
HDFS
- Hadoop Distributed File System,Hadoop分布式文件系统
- Apache Hadoop 核心组件之一,作为
大数据生态圈最底层
的分布式存储服务而存在 - 可以说大数据,首要解决的问题就是海量数据的存储问题
架构
- 解决大数据如何存储,分布式意味着HDFS很快在多台计算机上
- 高度容错,适合存储大型数据(TB、PB)
- 提供统一访问接口
设计目标
- 故障检测和自动快速恢复
- 用于批处理,更注重数据访问的高吞吐量
- 支持大文件
应用场景
- 适合
- 大文件
- 数据流式访问
- 一次写入多次读取
- 低成本部署,廉价PC
- 高容错
- 不适合
- 小文件
- 数据交互式访问
- 频繁任意修改
- 低延迟处理
重要特性
- 标准的 master/slave 主从架构集群
- 一般一个HDFS集群是有一个Namenode和一定数目的Datanode组成
Namenode是HDFS主节点,Datanode是HDFS从节点,两种角色各司其职,共同协调
完成分布式的文件存储服务- 官方架构图中是一主五从模式,其中五个从角色位于两个机架(Rack)的不同服务器上
分块存储
- HDFS中的文件在物理上是分块存储(block)的,默认大小是128M(134217728),不足128M则本身就是一块
- 块的大小可以通过配置参数来规定,参数位于hdfs-default.xml中:dfs.blocksize
副本机制
- 文件的所有block都会有副本
- 副本系数可以在文件创建的时候指定,也可以在之后通过命令改变
- 副本数由参数dfs.replication控制,默认值是3,也就是会额外再复制2份,连同本身总共3份副本
元数据记录
在HDFS中,Namenode管理的元数据具有两种类型:
- 文件自身属性信息:文件名称、权限,修改时间,文件大小,复制因子,数据块大小。
- 文件块位置映射信息:记录文件块和DataNode之间的映射信息,即哪个块位于哪个节点上
namespace
抽象统一的目录树结构(namspace)
- HDFS支持传统的层次型文件组织结构,用户可以创建、删除、移动或重命名文件
- Namenode负责维护文件系统的namespace,任何对文件系统名称空间或属性的修改都将被记录下来
- HDFS会给客户端提供一个统一的抽象目录树
- 客户端通过路径来访问文件,形如:hdfs://namenode:port/dir-aa/dir-b/dir-c/file.data。
HDFS Shell
命令行界面,commadn-line interface,CLI
hadoop fs [gen eric options]
- HDFS Shell CLI 支持多种文件系统
- 本地:file:///
- 分布式文件系统:hdfs://node:8020
- 取决于命令中文件路径
URL中的前缀协议
- 没有前缀则会读取环境变量中的
fs.defaultFS属性
,以该属性值作为默认文件系统
# 操作本地文件系统
hadoop fs -ls file:///
# 操作HDFS分布式文件系统
hadoop fs -ls hdfs://node-211:8020/
# 直接根目录,没有指定协议 将加载读取fs.defaultFS值
hadoop fs -ls /
不同区别
- hadoop dfs 只能操作HDFS文件系统(包括与Local FS间的操作),不过已经Deprecated
- hdfs dfs 只能操作HDFS文件系统相关(包括与Local FS间的操作),常用
- hadoop fs 可操作任意文件系统,不仅仅是hdfs文件系统,使用范围更广
常用操作
# 创建文件夹
hadoop fs -mkdir [-p] <path>
# 查看文件
hadoop fs -put [-f] [-p] <localsrc> ... <dst>
path 指定目录路径
-h 人性化显示文件size
-R 递归查看指定目录及其子目录
# 上传文件到HDFS指定目录下
hadoop fs -put [-f] [-p] <localsrc> ... <dst>
-f 覆盖目标文件(已存在下)
-p 保留访问和修改时间,所有权和权限
localsrc 本地文件系统(客户端所在机器)
dst 目标文件系统(HDFS)
# 查看HDFS文件内容
hadoop fs -cat <src> ...
读取指定文件全部内容,显示在标准输出控制台。
注意:对于大文件内容读取,慎重。
# 下载HDFS文件
hadoop fs -get [-f] [-p] <src> ... <localdst>
下载文件到本地文件系统指定目录,localdst必须是目录
-f 覆盖目标文件(已存在下)
-p 保留访问和修改时间,所有权和权限
# 拷贝HDFS文件
hadoop fs -cp [-f] <src> ... <dst>
-f 覆盖目标文件(已存在下)
# 追加数据到HDFS文件中
hadoop fs -appendToFile <localsrc> ... <dst>
将所有给定本地文件的内容追加到给定dst文件。
dst如果文件不存在,将创建该文件。
如果<localSrc>为-,则输入为从标准输入中读取
# 数据移动
hadoop fs -mv <src> ... <dst>
移动文件到指定文件夹下
可以使用该命令移动数据,重命名文件的名称
HDFS 架构
角色划分
主角色 namenode
- Hadoop
分布式文件系统的核心
,架构中的主角色 维护和管理文件系统元数据
,包括名称空间目录树结构、文件和块的位置信息、访问权限等信息- 基于此,NameNode成为了
访问HDFS的唯一入口
。
- 内部通过内存和磁盘文件两种方式管理元数据
- 其中磁盘上的元数据文件包括Fsimage内存元数据镜像文件和edits log(Journal)编辑日志
从角色 datanode
- Hadoop HDFS中的从角色,负责具体的数据块存储
- DataNode的数量决定了HDFS集群的整体数据存储能力
- 通过和NameNode配合维护着数据块
主角色辅助角色 secondarynamenode
- 充当NameNode的辅助节点,但不能替代NameNode
- 主要是帮助主角色进行元数据文件的合并动作。可以通俗的理解为主角色的“秘书”。
职责划分
namenode
- 仅存储HDFS的元数据:文件系统中所有文件的目录树,并跟踪整个集群中的文件,不存储实际数据
- NameNode知道HDFS中任何给定文件的块列表及其位置。使用此信息NameNode知道如何从块中构建文件
不持久化存储每个文件中各个块所在的datanode的位置信息
,这些信息会在系统启动时从DataNode重建- NameNode是Hadoop集群中的
单点故障
- NameNode所在机器通常会
配置有大量内存(RAM)
datanode
- DataNode负责
最终数据块block的存储
,是集群的从角色,也称为Slave - DataNode启动时,会
将自己注册到NameNode并汇报
自己负责持有的块列表 - 某个DataNode关闭时,不会影响数据的可用性。 NameNode将安排由其他DataNode管理的块进行副本复制
- DataNode所在机器通常
配置有大量的硬盘空间
,因为实际数据存储在DataNode中。
核心概念
Pipeline 管道
客户端将数据块写入第一个数据节点
第一个数据节点保存数据之后再将块复制到第二个数据节点
后者保存后将其复制到第三个数据节点
为什么datanode之间采用pipeline线性传输,而不是一次给三个datanode拓扑式传输呢?
- 因为数据以管道的方式,
顺序的沿着一个方向传输
- 这样能够
充分利用每个机器的带宽,避免网络瓶颈和高延迟时的连接,最小化推送所有数据的延时
- 在线性推送模式下,每台机器所有的出口宽带都用于以最快的速度传输数据,而不是在多个接受者之间分配宽带
ACK 应答响应
- 即确认字符,在数据通信中,接收方发给发送方的一种传输类控制字符。表示发来的数据已确认接收无误
- 在HDFS pipeline管道传输数据的过程中,传输的反方向会进行ACK校验,确保数据传输安全
默认 3 副本存储
默认副本存储策略是由
BlockPlacementPolicyDefault
指定
- 第一块副本:优先客户端本地,否则随机
- 第二块副本:不同于第一块副本的不同机架
- 第三块副本:第二块副本相同机架不同机器
上传文件
1、HDFS客户端创建对象实例DistributedFileSystem
, 该对象中封装了与HDFS文件系统操作的相关方法
2、调用DistributedFileSystem对象的create()方法,通过RPC请求
NameNode创建文件
NameNode执行各种检查判断:目标文件是否存在、父目录是否存在、客户端是否具有创建该文件的权限
检查通过,NameNode就会为本次请求记下一条记录,返回FSDataOutputStream输出流
对象给客户端用于写数据
3、客户端通过FSDataOutputStream输出流开始写入数据
4、客户端写入数据时,将数据分成一个个数据包(packet 默认64k
), 内部组件DataStreamer
请求NameNode挑选出适合存储数据副本的一组DataNode地址,默认是3副本存储
DataStreamer将数据包流式传输到pipeline
的第一个DataNode,该DataNode存储数据包并将它发送到pipeline的第
二个DataNode
同样,第二个DataNode存储数据包并且发送给第三个(也是最后一个)DataNode
5、传输的反方向上,会通过ACK机制校验数据包传输是否成功
6、客户端完成数据写入后,在FSDataOutputStream输出流上调用close()方法关闭
7、DistributedFileSystem联系NameNode告知其文件写入完成,等待NameNode确认
因为namenode已经知道文件由哪些块组成(DataStream请求分配数据块),因此仅需等待最小复制块即可成功返回
最小复制是由参数dfs.namenode.replication.min指定,默认是1
下载文件
1、HDFS客户端创建对象实例DistributedFileSystem
, 调用该对象的open()方法来打开希望读取的文件
2、DistributedFileSystem使用RPC调用namenode来确定文件中前几个块的块位置(分批次读取)信息
对于每个块,namenode返回具有该块所有副本的datanode位置地址列表,并且该地址列表是排序好的,与客户端的网络拓扑距离近的排序靠前
评论区