HDFS入门(二)

三、HDFS写数据流程

 

(1)客户端通过Distributed FileSystem模块向NameNode请求上传文件,NameNode检查目标文件是否已存在,父目录是否存在。

(2)NameNode返回是否可以上传。

(3)客户端请求第一个 Block上传到哪几个DataNode服务器上。

(4)NameNode返回3个DataNode节点,分别为dn1、dn2、dn3。

(5)客户端通过FSDataOutputStream模块请求dn1上传数据,dn1收到请求会继续调用dn2,然后dn2调用dn3,将这个通信管道建立完成。

(6)dn1、dn2、dn3逐级应答客户端。

(7)客户端开始往dn1上传第一个Block(先从磁盘读取数据放到一个本地内存缓存),以Packet为单位,dn1收到一个Packet就会传给dn2,dn2传给dn3;dn1每传一个packet会放入一个应答队列等待应答。

(8)当一个Block传输完成之后,客户端再次请求NameNode上传第二个Block的服务器。(重复执行3-7步)。

四、HDFS读数据流程

 (1)客户端通过DistributedFileSystem向NameNode请求下载文件,NameNode通过查询元数据,找到文件块所在的DataNode地址。

(2)挑选一台DataNode(就近原则,然后随机)服务器,请求读取数据。

(3)DataNode开始传输数据给客户端(从磁盘里面读取数据输入流,以Packet为单位来做校验)。

(4)客户端以Packet为单位接收,先在本地缓存,然后写入目标文件。

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataInputStream;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
​
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.net.URI;
​
​
public class HDFSDemo2 {
  // IO流
​
  //  上传
  //  本地文件  --输入流->  HDFS Java客户端  --输出流->   HDFS
​
  //  下载
  //  本地文件  <-输出流--  HDFS Java客户端  <-输入流-   HDFS
​
  public static void main(String[] args) throws Exception {
    Configuration conf = new Configuration();
    conf.set("dfs.replication", "2");
​
    FileSystem fs = FileSystem.get(URI.create("hdfs://192.168.235.10:8020"), conf, "root");
​
​
//    upload(fs);
​
//    download(fs);
​
​
  }
​
  private static void download(FileSystem fs) throws IOException {
    FileOutputStream outputStream = new FileOutputStream("G:\\");
​
    FSDataInputStream inputStream = fs.open(new Path("/a2.txt"));
​
    IOUtils.copyBytes(inputStream, outputStream, 4096);
​
    inputStream.close();
    outputStream.close();
    fs.close();
  }
​
  private static void upload(FileSystem fs) throws IOException {
    // 创建输入流读取本地文件
    FileInputStream inputStream = new FileInputStream("G:\\aaa.txt");
​
    // 创建输出流 将数据写到HDFS
    FSDataOutputStream outputStream = fs.create(new Path("/a2.txt"));
​
    // 对接 输入输出流  流的对拷
    IOUtils.copyBytes(inputStream, outputStream, 4096);
​
    inputStream.close();
    outputStream.close();
    fs.close();
  }
}

五、NameNode工作机制

 1)第一阶段:NameNode启动

(1)第一次启动NameNode格式化后,创建Fsimage和Edits文件。如果不是第一次启动,直接加载编辑日志和镜像文件到内存。

(2)客户端对元数据进行增删改的请求。

(3)NameNode记录操作日志,更新滚动日志。

(4)NameNode在内存中对元数据进行增删改。

2)第二阶段:Secondary NameNode工作

(1)Secondary NameNode询问NameNode是否需要CheckPoint。直接带回NameNode是否检查结果。

(2)Secondary NameNode请求执行CheckPoint。

(3)NameNode滚动正在写的Edits日志。

(4)将滚动前的编辑日志和镜像文件拷贝到Secondary NameNode。

(5)Secondary NameNode加载编辑日志和镜像文件到内存,并合并。

(6)生成新的镜像文件fsimage.chkpoint。

(7)拷贝fsimage.chkpoint到NameNode。

(8)NameNode将fsimage.chkpoint重新命名成fsimage。

六、安全模式

namenode启动时,首先将映像文件(fsimage)载入内存,并中兴编辑日志中的各项操作。一旦在内存中成功建立文件系统元数据的映像,则创建一个新的fsimage文件(该操作不需要借助namenode)和一个空的编辑日志。此时,namenode开始监听RPC和http请求。但是此刻namenode运行在安全模式,即namenode的文件系统对于客户端来说是只读的。(只有访问文件系统元数据的文件系统操作时肯定成功执行的,对于读文件操作,只有集群中当前datanode上的块可用时,才能工作。但文件修改操作,包括写、删或重命名均会失败)

在安全模式下namenode并不向datanode发出任何块复制或删除的指令。如果满足“最小副本条件”,namenode会在30秒钟后就退出安全模式,启动一个刚格式化的HDFS集群时,因系统中还没任何块,所以namenode不会进入安全模式。

进入和离开安全模式

# 显示是否处于安全模式
hdfs dfsadmin -safemode get   
​
# 一直等到某条命令到来前才退出安全模式
hdfs dfsadmin -safemode wait  
​
# 以下可以随时进入或离开安全模式
# 进入安全模式
hdfs dfsadmin -safemode enter  
​
#离开安全模式
hdfs dfsadmin -safemode leave  

02

安全模式相关的属性

dfs.replication.min(默认1),成功执行写操作所需创建的最小副本数(也称最小副本级别)

dfs.safemode.threshold.pct(默认值0.999),在namenode退出安全模式之前,系统中满足最小副本级别(由dfs.replication.min定义)的块的比例。将这项值设为0或更小会令namenode无法启动安全模式,设为高于1则永远不会退出安全模式。

七、DataNode 工作机制

 (1)一个数据块在DataNode上以文件形式存储在磁盘上,包括两个文件,一个是数据本身,一个是元数据包括数据块的长度,块数据的校验和,以及时间戳。

(2)DataNode启动后向NameNode注册,通过后,周期性(6小时)的向NameNode上报所有的块信息。

DN向NN汇报当前解读信息的时间间隔,默认6小时

<property>
    <name>dfs.blockreport.intervalMsec</name>
    <value>21600000</value>
    <description>Determines block reporting interval in milliseconds.</description>
</property>

DN扫描自己节点块信息列表的时间,默认6小时

<property>
    <name>dfs.datanode.directoryscan.interval</name>
    <value>21600s</value>
    <description>Interval in seconds for Datanode to scan data directories and reconcile the difference between blocks in memory and on the disk.
    Support multiple time unit suffix(case insensitive), as described
    in dfs.heartbeat.interval.
    </description>
</property>

(3)心跳是每3秒一次,心跳返回结果带有NameNode给该DataNode的命令如复制块数据到另一台机器,或删除某个数据块。如果超过10分钟没有收到某个DataNode的心跳,则认为该节点不可用。

(4)集群运行中可以安全加入和退出一些机器。

7.1、掉线时参数设置

 需要注意的是hdfs-site.xml 配置文件中的heartbeat.recheck.interval的单位为毫秒dfs.heartbeat.interval的单位为

<property>
  <name>dfs.namenode.heartbeat.recheck-interval</name>
  <value>300000</value>
</property>
​
<property>
  <name>dfs.heartbeat.interval</name>
  <value>3</value>
</property>

7.2数据完整性(crc校验算法)

如下是DataNode节点保证数据完整性的方法。

(1)当DataNode读取Block的时候,它会计算CheckSum。

(2)如果计算后的CheckSum,与Block创建时值不一样,说明Block已经损坏。

(3)Client读取其他DataNode上的Block。

(4)常见的校验算法crc(32),md5(128),sha1(160)

(5)DataNode在其文件创建后周期验证CheckSum。

备注:追加文件

将本地文件追加到集群文件末尾 appendToFile

只需要将hdfs-site.xml中的以下属性修改为true就行

<property>
     <name>dfs.support.append</name>
     <value>true</value>
</property>
hdfs dfs appendToFile 本地文件路径 集群路径

八、快照管理

  • 快照是一种数据备份机制,相比较直接复制数据,快照是一种增量备份

  • 如果数据有改动,则快照会记录改动的内容,如果数据没有改动,快照不占用多余的存储空间

# HDFS所有目录默认不开启快照功能
# 将目录设置为允许创建快照
hdfs dfsadmin -allowSnapshot /dir2
# 创建自动命名的快照
hdfs dfs -createSnapshot /dir2
# 创建自定义名称的快照
hdfs dfs -createSnapshot /dir2  ss1
# 对比多个快照之间的差异
#                  👇快照文件夹  👇快照名称1             👇快照名称2
hdfs snapshotDiff /dir2        s20211118-144021.107  ss1
# 删除指定快照
hdfs dfs -deleteSnapshot /dir2  ss1
# 包含快照的文件夹不能被直接删除
# 关闭文件夹的快照功能
hdfs dfsadmin -disallowSnapshot
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值