命令
- hdfs文件的相关操作主要使用hadoop fs、hadoop dfs、hdfs dfs 命令
- hadoop fs -ls 显示当前目录结构,-ls -R 递归显示目录结构
- hadoop fs -mkdir 创建目录
- hadoop fs -rm 删除文件,-rm -R 递归删除目录和文件
- hadoop fs -put [localsrc] [dst] 从本地加载文件到HDFS
- hadoop fs -get [dst] [localsrc] 从HDFS导出文件到本地
- hadoop fs - copyFromLocal [localsrc] [dst] 从本地加载文件到HDFS,与put一致
- hadoop fs -copyToLocal [dst] [localsrc] 从HDFS导出文件到本地,与get一致
- hadoop fs -test -e 检测目录和文件是否存在,存在返回值$?为0,不存在返回1
- hadoop fs -text 查看文件内容
- hadoop fs -du 统计目录下各文件大小,单位字节。-du -s 汇总目录下文件大小,-du -h 显示单位
- hadoop fs -tail 显示文件末尾
- hadoop fs -cp [src] [dst] 从源目录复制文件到目标目录
- hadoop fs -mv [src] [dst] 从源目录移动文件到目标目录
数据块(block)概念
- HDFS(Hadoop Distributed File System)默认的最基本的存储单位是128M的数据块。
- 和普通文件系统相同的是,HDFS中的文件是被分成128M一块的数据块存储的。
- 不同于普通文件系统的是,HDFS中,如果一个文件小于一个数据块的大小,并不占用整个数据块存储空间。
- 块大小设置为128m的原因:为了最小化寻址开销。如设置过大,会导致map数过少,集群利用率过低。如设置过小,要维护的元数据信息过多,由于元数据信息是存储在内存中的,所以可能会造成内存溢出。
设置文件副本数
hadoop fs -setrep -R 4 /path
查看文件的块信息
hdfs fsck /path -files -blocks -locations
HDFS体系架构
- 主从架构,一主多从
元数据节点(NameNode)
- 其将所有的文件和文件夹的元数据保存在一个文件系统树中
- 元数据中存放着文件包括哪些数据块以及这些数据分布到哪些DataNode数据节点上
- VERSION——java properties文件,保存了HDFS的版本号。
- fsimage——元数据的镜像文件,可以理解为元数据保存在磁盘上的一个副本
- edits——修改日志文件,记录引发元数据改变的操作。
- fstime——合并fimage和edits的时间
数据节点(DataNode)
- 文件系统中真正存储数据的地方
- 客户端(client)或者元数据信息(namenode)可以向数据节点请求写入或者读出数据块。
- 其周期性的向元数据节点回报其存储的数据块信息
从元数据节点(secondary namenode)
- 从元数据节点并不是元数据节点出现问题时候的备用节点,它和元数据节点负责不同的事情。
- 其主要功能就是周期性将元数据节点的fsimage和edits合并,以防edits修改日志文件过大。
- 合并过后的命名空间镜像文件也在从元数据节点保存了一份,以防元数据节点失败的时候,可以恢复。
文件系统命名空间映像文件及修改日志
- 当文件系统客户端(client)进行写操作时,首先把它记录在修改日志中(edit log)
- 元数据节点在内存中保存了文件系统的元数据信息。在记录了修改日志后,元数据节点则修改内存中的数据结构。
- 每次的写操作成功之前,修改日志都会同步(sync)到文件系统。
- fsimage文件,也即命名空间映像文件,是内存中的元数据在硬盘上的checkpoint,它是一种序列化的格式,并不能够在硬盘上直接修改。
- 同数据的机制相似,当元数据节点失败时,则最新checkpoint的元数据信息从fsimage加载到内存中,然后逐一重新执行修改日志中的操作。
- 从元数据节点就是用来帮助元数据节点将内存中的元数据信息checkpoint到硬盘上的
- checkpoint的过程如下:
- 从元数据节点通知元数据节点生成新的日志文件,以后的日志都写到新的日志文件中。
- 从元数据节点用http get从元数据节点获得fsimage文件及旧的日志文件。
- 从元数据节点将fsimage文件加载到内存中,并执行日志文件中的操作,然后生成新的fsimage文件。
- 从元数据节点奖新的fsimage文件用http post传回元数据节点
- 元数据节点可以将旧的fsimage文件及旧的日志文件,换为新的fsimage文件和新的日志文件(第一步生成的),然后更新fstime文件,写入此次checkpoint的时间。
- 这样元数据节点中的fsimage文件保存了最新的checkpoint的元数据信息,日志文件也重新开始,不会变的很大了。
心跳机制
- 介绍: hdfs是主从架构,所有为了实时的得知dataNode是否存活,必须建立心跳机制,在整个hdfs运行过程中,dataNode会定时的向nameNode发送心跳报告已告知nameNode自己的状态。
- 心跳内容:
- 报告自己的存活状态,每次汇报之后都会更新维护的计数信息
- 向nameNode汇报自己的存储的block列表信息
- 心跳报告周期:
- nameNode判断一个dataNode宕机的基准:连续10次接收不到dataNode的心跳信息,和2次的检查时间。
- 检查时间:表示在nameNode在接收不到dataNode的心跳时,此时会向dataNode主动发送检查
安全机制
- 介绍:hdfs在启动的时候,首先会进入的安全模式中,当达到规定的要求时,会退出安全模式。在安全模式中,不能执行任何修改元数据信息的操作。
- hdfs的元数据的介绍(三个部分):
- 抽象目录树
- 数据与块的对应关系(文件被切分成多少个块)
- block块存放的位置信息
- hdfs元数据的存储位置:
- 内存:内存中存储了一份完整的元数据信息(抽象目录树、数据与块的对应关系、 block块存放的位置信息)
- 硬盘:抽象目录树、数据与块的对应关系
注意:其中内存中的元数据的block块存放的位置信息,是通过dataNode向nameNode汇报心跳时获取的,硬盘中的元数据,是因为内存中的元数据在机器宕机时就自动消失,所以需要将内存中的元数据持久化到硬盘
而硬盘中的元数据只有抽象目录树、数据与块的对应关系,没有block块存放的位置信息
- nameNode在启动的所作的操作:
集群的启动顺序:nameNode—-》dataNode—-》secondaryNameNode
将硬盘中的元数据信息加载内存,如果是第一次启动集群,此时会在本地生成一个fsimage镜像文件,接收dataNode汇报的心跳,将汇报中的block的位置信息,加载到内存。当然就在此时hdfs会进入安全模式。
- 退出安全模式的条件:
- 如果在集群启动时dfs.namenode.safemode.min.datanodes(启动的dataNode个数)为0时,并且,数据块的最小副本数dfs.namenode.replication.min为1时,此时会退出安全模式,也就是说,集群达到了最小副本数,并且能运行的datanode节点也达到了要求,此时退出安全模式
- 启动的dataNode个数为0时,并且所有的数据块的存货率达到0.999f时,集群退出安全模式(副本数达到要求)
手动退出或者进入安全模式
hdfs dfsadmin -safemode enter 进入 hdfs dfsadmin -safemode leave 退出 hdfs dfsadmin -safemode get 查看
负载均衡
- hdfs的负载均衡:表示每一个dataNode存储的数据与其硬件相匹配,即占用率相当
- 如何手动调整负载均衡:
- 集群自动调整负载均衡的带宽:(默认为1M)
- 告诉集群进行负载均衡:start-balancer.sh -t 10% 表示节点最大占用率与节点的最小的占用率之间的差值当超过10%时,此时集群不会立刻进行负载均衡,会在集群不忙的时候进行。
文件下载
- 客户端对nameNode发送下载的指令,hadoop fs -get /a.txt
- nameNode做一系列的校验(是否权限、文件是否存在..)
- nameNode向client发送block的位置信息,根据情况发送一部分或者全部
- client计算出最进行DN,然后建立连接,进行文件下载
- client每下载一个块就会做CRC校验,如果下载失败,client会向nameNode汇报,然后从其他的DN相应的块的副本,此时nameNode会记录这个可能故障的DN,在下次上传或者下载的时候,尽量不使用它。
- 当所有的块下载成功的时候,client向nameNode汇报成功信息
文件上传
- 使用hdfs提供的客户端client,向远程的namenode发起RPC请求。
- namenode会检查要创建的文件是否已经存在、创建者是否有权限,成功则会为文件创建一个记录,否则向客户端抛出异常。
- 当客户端开始写入文件的时候,客户端会将文件切分成多个packets,并在内部以数据队列“data queue(数据队列)”的形式管理这些packet,并向namenode申请blocks,获取用来存储replicas的合适的datanode列表,列表的大小根据namenode中的replication个数来设定。
- client获取block列表之后,开始以pipeline(管道)的形式,将packet写入所有的replicas中,客户端把packet以流的形式写入到第一个datanode中,该datanode把packet存储之后,在将其传递到此pipeline中的下一个datanode,直到最后一个 datanode。
- 最后一个 datanode 成功存储之后会返回一个 ack packet(确认队列),在 pipeline 里传递至客户端,在客户端的开发库内部维护着”ack queue”,成功收到 datanode 返回的 ackpacket 后会从”data queue”移除相应的 packet。
- 如果传输过程中,有某个datanode出现了故障,那么当前pipeline会被关闭,出现故障的节点,会被剔除此pipeline,剩余的block会继续剩下的的 datanode 中继续以 pipeline 的形式传输,同时 namenode 会分配一个新的 datanode,保持 replicas 设定的数量。
- 客户端完成数据的写入后,会对数据流调用close方法,关闭数据流
- 只要写入了 dfs.replication.min(最小写入成功的副本数)的复本数(默认为 1),写操作就会成功,并且这个块可以在集群中异步复制,直到达到其目标复本数(dfs.replication的默认值为 3),因为namenode已经知道文件由哪些块组成,所以他在返回成功前只需要等待数据块进行最小量的复制。
- 最后当这个文件上传成功后,此时namenode会将预写如日志的操作,同步到内存中
元数据的合并
- 合并时机:
A:间隔多长时间合并一次
B:操作日志记录超过多少条合并一次
- 集群启动时,加载fsimage镜像文件到内存,如果是第一启动集群或者集群正常关闭之后重启此时nameNode会在硬盘中合并一个fsimage镜像
- seconddaryNameNode定时(1分钟)发送检验给nameNode,查看是否需要进行合并
- 得知nameNode需要进行元数据合并
- seconddaryNameNode向nameNode发送合并请求
- nameNode将edits_inprogress_000095 根据seen_txid进行回滚,并且生成一个新的空的edits_inprogress_000096,继续记录操作日志
- secondaryNameNode将回滚的edits和最新的fsiamge进行本地拉去
- secondaryNameNode将edits和最新的fsiamge进行合并,在内存中根据edits修改fsiamge
- secondaryNameNode将合并后的fsiamge推送回namenode。并在本地保存一份。
小文件治理
archive
- 创建archive文件
hadoop archive -archiveName test.har -p /testhar -r 3 th1 th2 /outhar
- 查看archive文件
hdfs dfs -ls -R har:///outhar/test.har
- 解压archive文件
hdfs dfs -cp har:///outhar/test.har/th1 th2 hdfs:/unarchivef
hadoop fs -ls /unarchivef
hadoop distcp har:///outhar/test.har/th1 th2 hdfs:/unarchivef
Sequence Files
SequenceFile本质上是一种二进制文件格式,类似key-value存储,通过map/reducer的input/output format方式生成。文件内容由Header、Record/Block、SYNC标记组成,根据压缩的方式不同,组织结构也不同,主要分为Record组织模式和Block组织模式。
