Hadoop基础之HDFS

HDFS

Hadoop基础之HDFS

什么是HDFS

  • Hadoop   Distributed   File   System
  • hadoop的分布式文件系统
  • 文件系统:
    • 个人理解:在磁盘(只能做存储)的基础上,使用软件对所存储的内容进行管理的,这个软件就叫做文件系统
    • 百度百科:文件系统是操作系统用于明确存储设备(常见的是磁盘,也有基于NAND Flash的固态硬盘)或分区上的文件的方法和数据结构;即在存储设备上组织文件的方法。操作系统中负责管理和存储文件信息的软件机构称为文件管理系统,简称文件系统。文件系统由三部分组成:文件系统的接口,对对象操纵和管理的软件集合,对象及属性。从系统角度来看,文件系统是对文件存储设备的空间进行组织和分配,负责文件存储并对存入的文件进行保护和检索的系统。具体地说,它负责为用户建立文件,存入、读出、修改、转储文件,控制文件的存取,当用户不再使用时撤销文件等。

分布式存储

  • 对于一个容量超大的文件进行存储,在一个单独的位置很难完成,所以要按照某种规则,对这个文件进行切块,把每个块分别存储在集群中的不同节点里,分散了海量文件的存储压力

文件系统的表现形式

  • 本地文件系统,普通操作系统里的文件系统
    • windows:   file:\C:\   --  盘符:\路径
    • linux:   file:///   --   根目录/路径
  • 非本地文件系统,在操作系统之外的文件系统
    • hdfs:   hdfs://[ip:端口port]/路径
    • ftp:   ftp://

三个角色

  • NameNode(NN)
    • 集群领导者,全局唯一
    • 任何节点都可以赋予NN角色
    • 如果有其他机器配置了NN,其他机器会处于准备状态,如果此NN宕机,会顶替上来,但是,在同一时间只会有一个NN处于存活
  • DataNode(DN)
    • 工具人节点
    • 存储真实数据
    • 任何节点都可以赋予DN角色,一般不与NN和2NN在一起
    • 为了保证数据的安全性和可靠性,数据在不同节点存三份
  • SeondaryNameNode(2NN)
    • 为了保证元数据的安全可靠,有2NN角色对NN进行备份
    • 存储的数据与NN一样,定时与NN同步数据
    • 为了保证数据的安全性,不与NN放置在同一节点,全局唯一

优缺点

  • 优势
    • 存储量大
    • 可以容错,让数据更安全
    • 适合一次写入,多次读出
  • 劣势
    • 速度慢
    • 不适合做实时运算
    • 可以添加,但是不可以修改(可以追加,但是不建议使用)

HDFS的存储方式

  • 一个超大文件,按照128M为一个block块进行拆分,最后不足128M的部分自成一个block块
  • 块大小
    • 1版本是64M,2版本是128M
  • 原因:最优化寻址时间

工作机制

  • NameNode
    • dfs/name/current所存储的元数据默认一个小时存储一次
      • edits_0000000000000000001-000000000000000000N
        • 这个文件的数值不是连续的
        • 中间的数值间隔表示一个小时内所进行的操作的次数
        • 查看方式:oev
          • hdfs   oev   [-p   xml]   -i(input   file)   -o(output   file) 
      • edits_inprogress文件存储的是当前正在进行的操作,他的编号是最大的,当此操作完成进行新操作,会将原本的文件重命名,然后重新创建一个新的文件用来保存当前正在进行的操作
      • fsimage文件是edits文件和上一次inprogerss文件合并而来,只保存最近两个版本(镜像文件)
        • 在fsimage在合并的时候,会首先将edits_inprogress保存成edits,并创建一个新的inprogress,然后将上一个fsimage和在它之后全部的edits合并在一起
        • 合并工作由SecondaryNameNode来做
        • fsimage.md5是fsimage的md5校验文件
        • 查看方式:oiv
          • hdfs   oiv -p   XML  -i   -o
          • fsimage文件分为两部分
            • 对文件和目录的单纯描述
            • 根据文件或目录的ID赋予层次关系
      • seen.txid这里保存的是当前inprogerss的id的最大值
      • VERSION文件是默认生成的版本号
      • 注意:造成日志滚动的的原因不仅仅是时间达到一个小时
        • 强制滚动日志:hdfs   dfsadmin  -rollEdits
        • 可以等到edits.inprogress满64M生成edits文件
        • 操作数量达到一百万次会滚动
        • 集群在启动、关闭时,会有日志滚动
        • 手动滚动日志文件SecondoryNmeNode不改变,会在下一次自动同步的时候同步过去
        • 手动合并: hdfs   dfsadmin   -saveNamespace -- 手动合并的时候需要在安全模式下进行
      • 条件对应的配制项
        • 时间周期
          • dfs.namenode.checkpoint.period -- 默认3600
        • 操作记录数
          • dfs.namenode.checkpoint.txns -- 默认1000000
        • 检查合并时间间隔
          • dfs.namenode.checkpoint.chick.period -- 默认60
  • HDFS开机启动NameNode过程
    • 第一次启动namenode格式化后,创建HDFS镜像文件fsimage和编辑日志文件edits
      • 每个block占元数据150byte
    • 非第一次启动集群时
      • namenode在启动的时候fsimage的内容会加载到内存中,然后执行editlog的各项操作,保证内存的元数据保持最新的
      • 当上述操作完成后,创建新的edits文件和fsimage文件
      • 同时产生新的edits.inprogerss
    • 正常运行状态
      • 当各节点都启动成功并且正常运行之后,HDFS中的更新都会写入到editlog中,不是直接写入fsimage中。
      • 对于分布式系统而言,fsimage文件是非常庞大的,直接往fsimage文件写入数据效率非常低下,非常缓慢
      • 相对而言,最大只有64MB大小的editlog文件,写入数据是十分高效的
    • 启动时安全模式
      • 在集群启动的过程中处于安全模式,此时只能读,不能取,当集群成功启动之后,系统会退出安全模式,开始对外进行完成服务支持
  • DataName
    • DataNode节点文件是存放真实数据的
    • blk_xxx文件作为总文件的块文件,属于真实文件
    • 路径中两层subdir0与我们的目录层次没有关系
    • 工作原理
      • DataNode在启动的时候向NameNode注册自己
      • NameNode接收注册,把DataNode的数据信息记录下来,反馈回去
      • DataNode每隔3秒钟与NameNode进行一次交互,目的为了证明当前DataNode可以使用
      • 如果NameNode5分钟没有收到心跳,会主动寻找DataNode,达到两个周期(10分钟),没有找到则认为该节点不可用
      • DataNode每隔一小时主动向NameNode报告一次,同步数据
      • 断连超时时间计算公式
        • TimeOut = 2*dfs.namenode.heartbeat.recheck[5min]-interval+10*dfs.heartbeat.interval[3s]
  • HDFS写数据原理
    • 客户端与NameNode发送连接请求,请求上传文件
    • NameNode给客户端一个响应,可以上传文件
    • 客户端分别对每个block块发送请求,请求存储数据的节点
    • NameNode给客户端响应有可存储数据的节点
    • 客户端与NameNode返回的所有节点建立连接
    • 客户端把数据存储到每一个节点
      • 客户端只将数据发送到一个节点
      • 内部副本同步方式为集群内部传输
    • 传输成功之后,再次请求NameNode,通知上传完毕
    • NameNode保存相应的元数据信息
  • HDFS读数据原理
    • 客户端向NameNode请求下载文件
    • NameNode向客户端返回这个文件的元数据
    • 客户端根据获取的元数据,向具体的DataNode请求真实数据
    • DataNode向客户端返回真实数据
    • 所有block块获取完毕,在本地内存合并,写入文件

HDFS的安全模式

  • 安全模式是HDFS处于一种特殊状态,这种状态下只能读不能改,换句话说,只能进行对数据不进行改变的操作
  • 原因
    • 当NameNode启动的时候,会将fsimage的数据加载到内存中,同时逐条执行editlog中的命令,在这期间,内存中成功建立文件系统元数据的映像后,就会创建一个新的fsimage文件和一个空的editlog文件
    • 在这个过程中namenode是在安全模式下运行的,在安全模式中,DataNode会向NameNode发送块列表信息,当最小块副本满足的时候,NameNode会在三十秒后退出安全模式,开始提供完整服务
  • 最小副本条件
    • 整个文件系统中99.99%的块满足最小副本级别
  • 系统离开安全模式的条件
    • namenode收到DataNode的状态报告后确定
      • 可用的block块占总数的比例
      • 可用的数量节点满足要求
      • 满足条件后维持的时间达到要求
    • 可以用命令强制离开安全模式
  • 安全模式的配制
    • 安全模式主要配制在hdfs-site.xml
    • 当没有额外配制的情况下,会采用默认值
    • dfs.namenode.replication.min
      • 最小的文件block副本数量,默认为1
    • dfs.namenode.safemode.threshold-pct
      • 副本数达到最小要求的block占系统总block数的百分比
      • 只有实际比例大于默认比例,才能离开安全模式
      • 如果小于等于0,则不会等待任何副本达到要求即可离开,如果大于1,永远处于安全模式
    • dfs.namenode.safemode.extension
      • 当条件满足后所需要维持的时间
      • 如果在满足条件的情况下,同时所规定的时间内,没有出现不满足的情况下,即可离开安全模式
      • 单位时毫秒
  • 安全模式的命令
    • hdfs dfsadmin -safemode[get/enter/leave/wait]
    • get:查看是否处于安全模式
    • enter:进入安全模式
    • leave:退出安全模式
    • wait:等待安全模式,让安全模式进入等待模式(适用于一直处于安全模式时,等待安全模式退出后执行)

HDFS脚本

  • hadoop/hdfs
    • hdfs   dfs   等价于hadoop   fs
    • hadoop中包含但不限于hdfs命令,hdfs中只有dhfs命令
    • hadoop/hdfs里面的每个命令都对应一个Java实现类
    • [如果没有参数/参数为--help/参数为-help]--打印帮助信息

hdfs操作

  • shell操作(通过命令直接操作文件系统)
    • -help/--help/-h   --获取帮助信息
    • -ls   --显示目录信息
      • hdfs   dfs   -ls  --显示目录信息
    • -mkdir   --创建目录
      • hdfs   dfs   -mkdir  [-p]   路径/目录名
    • -moveFromLocal/-moveToLocat   --从本地/hdfs剪切到hdfs/本地
      • hdfs   dfs   -moveFromLocal/-moveToLocal   本地路径/hdfs路径   hdfs路径/本地路径
    • -mv   在hdfs中移动文件
      • hdfs   dfs   原文件   目标文件
    • -appendToFile   --追加一个文件到文件末尾
      • hdfs   dfs   -appendToFile   原文件   追加文件
    • -cat   --显示文件内容
      • hdfs   dfs   -cat   文件名
    • -tail   --显示一个文件的末尾
      • hdfs   dfs   -tail   文件名
    • -chgrp/-chmod/-chown   --修改文件权限
      • hdfs   dfs  -chgrp/-chmod/-chown   权限类型(rwx)   文件/目录名
    • -copyFromLocal/-copyToLocal   --从本地/hdfs拷贝到hdfs/本地
      • hdfs   dfs   -copyFromLocal/-copyToLocal   本地/hdfs   hdfs/本地
    • -cp   --从一个hdfs的路径拷贝到另一个路径
      • hdfs   dfs -cp   原路径   目标路径
    • -get   --从hdfs下载文件到本地
      • hdfs   dfs   -get 原文件   目标路径
    • -getmerge   --合并下载多个文件(可以理解为级联)
      • hdfs   dfs   -getmerge   原目录   目标路径
    • -put   --等同于copyFromLocal
      • hdfs   dfs -put 本地   hdfs
    • -rm   --删除文件或目录
      • hdfs   dfs   -rm   文件/路径
    • -rmdir   --删除空目录
      • hdfs   dfs   -rmdir   目录
    • -df   --统计文件系统可用空间信息
      • hdfs   dfs   -df   -h
    • -du   --统计一个指定目录下的大小信息
      • hdfs   dfs   -do   -s   -h   目录
    • -ccount   --统计一个指定目录下的文件节点数量
      • hdfs   dfs   -count   路径
    • -setrep   --设置hdfs中文件的副本数量
      • hdfs  dfs   -setrep   [number]   路径(number数量要小于等于DataName节点数)

JavaAPI(通过开发工具写代码与HDFS连接)

    • 构建项目的两种方式
      • 普通方式,手动导包
        • 查找依赖包hadoop.tar.gz解压缩 -->> share-hadoop搜索.jar
        • 去除重名包、资源包、测试包
        • 添加到项目中
      • maven
        • pom.xml添加所需要的依赖包的三点坐标
        • 如果仓库中有需要的依赖包,可以添加
        • 如果仓库中没有需要的依赖包,从网站中查找
    • 代码
      • 连接HDFS
<!-- 
package hdfs;

import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.jupiter.api.Test;

import java.io.IOException;
import java.net.URI;

public class TestHdfsConnection {

    @Test
    public void connectionHdfs() throws Exception {
        Configuration configurations = new Configuration();
//        可以选择不写参数,然后再re目录下导入core-size.xml文件
//        如果没有core-size.xml的同时,Configuration也没有值,会走默认
//        configurations.set("fs.default.name","hdfs://hadoop101:9000");
        FileSystem fileSystem = FileSystem.get(new URI("hdfs://hadoop101:9000"),configurations,"bduser");
        System.out.println(fileSystem);
        fileSystem.copyFromLocalFile(new Path("file:///D:/Tencent/QQManagementDate/461585949/FileRecv/第2章_彻底解决分布式一致性问题.pptx"),new Path("/home/bduser"));

        fileSystem.close();
    }
}
  • 注意
    • 设置属性的加载顺序
      • xxx-default.xml
      • xxx-size.xml
      • 代码中conf.set(key,value)
    • 生效顺序
      • 与加载顺序相反
    • 作用域
      • default和site对于全局有效,conf.site只对当前方法有效
  • 关于windows操作hdfs的权限问题
    • 给更高权限
    • 更改用户,使用当前所属者权限
    • 解决方案
      • hdfs   dfs   chmod   o+w
      • FileSystem.get(URI,conf,userName)
      • run->editConfiguration->VM_options->-DHADOOP_USER_NAME=某某某
      • 修改hdfs用户名与windows一致
      • 修改windows用户名与hdfs一致

Hadoop集群间的复制

  • scp:跨节点之间的数据复制
    • 不管数据是否一致,都复制一遍,比较浪费资源
  • rsync:跨节点之间的数据同步
    • 两个节点之间相同目录下。不一样的数据进行同步
  • hdfs   dfs  -cp:在一个集群之间进行数据的复制
  • distcp:跨集群之间的数据复制
    • hadoop   distcp   < srcurl> < desturl>
    • 没有远程和本地的区别,双方都是远程集群,有的只是原路径和目标路径
    • 复制文件和复制目录一样,没有特殊选项
    • 如果为了保证安全,可以在目录后面加/*

小文件管理

  • 容量小的文件,在hdfs中,不足128M都按照1289M计算
  • 如果这样的文件过多的话,对hdfs来说就是灾难性的影响
  • 解决方案
    • 将多个小文件整合成一个文件来处理
    • 创建存档
      • hadoop   archive   -archiveName  < name.har>     -p   < parent path> < src>*< dest>
      • hadoop   archive   -archiveName   存档名字   -p   父目录   原路径(可以多个)   目的路径
    • 执行创建存档之后,原文件不会自动删除,需要手动删除
    • 查看存档
      • hdfs   dfs   -lsr   路径
        • 正常查看存档内容
      • hdfs   dfs   -lsr   har:///路径
        • 查看存档内的所有内容
      • hdfs   dfs   -cat   路径/part-x
        • 查看存档具体内容
    • 解除存档
      • hdfs   dfs   -cp   har:///路径/*   目标路径

配额管理

  • 可以设置hdfs里目录存储的上限(数量和容量)
  • 使用方式
    • 设置数量限额
      • hdfs   dfsadmin   -setQuota   数量 目录*
    • 取消数量限额
      • hdfs   dfsadmin   -clrQuota   目录*
    • 设置容量限额
      • hdfs   dfsadmin   -setSpaceQuota   容量   目录*
    • 取消容量限额
      • hdfs   dfsadmin   -clrSpaceQuota   目录*
如有问题,请发送邮件至buxiaqingcheng@163.com或者buxiaqingcheng@dingtalk.com
原文地址:https://www.cnblogs.com/zhenzhunaichabujiatang/p/13873575.html