HDFS学习总结----面试必须掌握

为什么要用HDFS

  • 一台服务器存不下数据,需要多台服务器。多台服务器上的数据需要一个系统来组织和管理。

tip:HDFS、NTFS是不同的文件管理系统

HDFS的定义

  • HDFS是一个分布式的文件系统,通过目录树来定位文件

HDS的使用场景

  • 一次写入,多次读出,不支持文件的修改,并且数据读取慢
  • 适合做数据分析的存储

优点

  • 高容错

    自动保存多个副本,当节点数足够的时候,会自动保持副本份数。如10个节点,3个副本,一台挂掉,那么这台节点上的数据会被转存到其他节点,保证副本份数。

  • 适合做大数据,大文件规模,GB,TB,PB

缺点

  • 不适合低延时的数据访问,毫秒级的响应不适合
  • 无法高效的对大量小文件存储
    1. 每一个小文件,在NameNode中会消耗150字节的内存,小文件多,会占用大量NameNode 的内存存储
    2. 小文件的存储寻址的时间超过了读取时间,违背设计原则
  • 不支持并发写入数据,即两个客户端无法同时写入相同的文件,不同文件可以并发写入
  • 不支持随机写操作,即无法修改文件

组成架构

NameNode

  • 管理HDFS名称空间
  • 管理数据块的映射信息
  • 处理客户端的读写请求

DataNode

  • 存储实际的数据块
  • 执行数据块的读写请求

客户端

  • 文件切块:上传文件的时候,客户端将文件切分成Block,然后上传
  • 与NameNode交互,获取文件位置信息
  • 与DataNode交互,读取或写入数据
  • 提供命令管理、访问HDFS

2ndNameNode

  • 辅助NameNode工作,合并fsimage和edits
  • 紧急情况下,可辅助恢复NameNode

块大小设置

设置方法

  • 默认大小Hadoop 2.x是128MB(),1.x是64MB。
  • hdfs-site中,dfs.blocksize设置(字节)

设置原则

  • 块的寻址约10ms,1%,1s,磁盘速率100MB/s,所以一个块大约128MB,
  • 当磁盘速率较高的时候,可以设置为256MB。
  • HDFS块大小取决于磁盘传输速率。

为什么块的大小不能太大或太小?

  • 太小:块数太多,增加块的寻址时间同时增加内存消耗
  • 太大:并行度减小

HDFS的shell操作

hadoop fs和hdfs dfs的关系,后者是前者的实现类。

# 查看HDFS节点状态
hdfs dfsadmin -report

# 帮助命令
hadoop  fs -help rm

# 地柜查看目录
hadoop fs -ls -R /

# 创建多及目录
hadoop fs -mkdir -p /sanguo/shuguo

# 剪切本地文件到HDFS,本地文件会消失
hadoop fs -moveFromLocal 本地文件   目标地址

# 复制本地文件到HDFS
hadoop fs -copyFromLocal 本地文件 目标地址

# 复制HDFS文件到本地
hadoop fs -copyToLocal 目标文件 本地地址

# 追加
hadoop fs -appendToFile 源文件  目标文件

# 合并一个目录下的多个文件,下载到本地,如一个目录下的多个log文件合并,
hadoop fs -getmerge /user/*.log  ./my_log.txt

# 查看文件尾部,查看日志尾部,一般最新的日志都在最后面
hadoop fs -tail /user/2019.log

# 统计目录大小
hadoop fs -du -h -s  目标目录

# 设置文件的副本数量。副本数量>节点数,依然备份节点数个副本
hadoop fs -setrep 2 目标文件

HDFS的客户端操作

客户端配置

  • windows下,解压Hadoop压缩包,配置环境变量(这一步非必须)

  • Java工程中添加maven依赖

    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-common</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-client</artifactId>
        <version>2.7.7</version>
    </dependency>
    <dependency>
        <groupId>org.apache.hadoop</groupId>
        <artifactId>hadoop-hdfs</artifactId>
        <version>2.7.7</version>
    </dependency>
    
  • 配置日志,log4j.properties

客户端操作的问题

问题1:为什么需要解压Hadoop压缩包

不一定需要,只要在Java工程配置好apache.hadoop相关依赖即可

问题2:提示用户名没有权限

  • 出现问题:Permission denied: user=tensory, access=READ_EXECUTE

  • 解决方法

    • 方法一:run的时候,run configurations,设置用户名为集群的用户名

      Run–Edit Configure—在VM options中配置:-DHADOOP_USER_NAME=hadoop

    • 方法二:创建FileSystem对象的时候,传入HDFS的用户名

客户端读取配置的优先级

客户端代码中conf.set > resources/hdfs-site.xml > 集群上的hdfs-site.xml > 默认配置

测试一下上传文件的时候的副本份数

# 三个 优先级逐渐降低

conf.set("dfs.replication", "1")

resources/hdfs-site.xml设置副本份数

集群的hdfs-site.xml中的副本份数

客户端操作

文件下载

设置为false,即不使用本地的文件系统,则存在crc校验,会生成 .zhangsan.txt.crc文件

问题记录

  • 出现问题

    java.io.IOException: (null) entry in command string: null chmod 0644 E:\IdeaProjects\Hadoop-demo\src\main\resources\zhangsan-1.txt中

  • 解决办法:下载对应版本的hadoop.dll放在windows\system32下面

HDFS的IO流操作

不使用API进行文件的读写,如果要修改Hadoop源码,在定制化严重的公司,需要自定义、封装一些框架,就需要IO流读写。

文件定位读取——如何读取指定block

文件分块,如何获取某一块,例如只需要读日志文件的最后一块?

  1. 获取输入流
  2. 设置指定读取的起点,根据块的大小,确定定位点
  3. 获取输出流
  4. 流的对拷(从定位点读到结尾)
  5. 关闭相关资源

HDFS的数据流操作

HDFS写数据流程

  • step1. 客户端向NameNode申请写数据/user/hadoop/ss.avi

  • step2. NameNode判断路径、文件是否存在。相应可以写数据

  • step3. 客户端向NameNode申请上传第一个Block(128MB),请返回DataNode

  • step4. NameNode根据节点距离、负载返回3个DataNode,dn1, dn2, dn3

  • step5. 创建FSDataOutputStream对象,请求数据通道,dn1–dn2–dn3–dn2–dn1

  • step6. 以packet为单位以数据流的方式,传输数据到dn1的内存队列中,dn1的内存数据序列化到磁盘,并传给dn2,dn2将数据存在内存队列,并传给dn3,dn2的内存数据序列化到本地。dn3的内存数据本地化,清空内存,告诉dn2,dn2清空内存告诉dn1,dn1清空内存

如何计算节点的距离

两个节点的最短路径为,两个节点到达最近公共祖先的距离之和。

不同的集群共有一个父节点,一个集群下的不同机架共有一个父节点。

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l2OP84mD-1595422402732)(C:\Users\tensory\AppData\Roaming\Typora\typora-user-images\image-20200517173249877.png)]

机架感知

默认3个副本,存在哪里呢?

  • 第一个:客户端在集群外,随机选一个机架,随机选一个。在集群内,则本地节点。

  • 第二个:和第一个副本相同机架的不同节点。

  • 第三个:其他机架的随机节点。

读数据流程

  • step1. 向NameNode请求读数据/user/hadoop/ss.avi
  • step2. 返回目标数据的元数据信息
  • step3. 向DataNode请求读数据,数据存在哪个节点?
  • step4. 根据距离最近,以block为单位读数据。
  • step5. 等所有的block读取完毕,进行拼接。

NameNode和SecondaryNameNode

NN和2NN工作机制

  • NameNode的元数据存在哪里?

    元数据在内存中,但元数据在磁盘有备份,即fsimage。

  • 磁盘的数据何时更新?

    当内存数据更新或添加元数据,将修改日志追加到edits中,只进行追加操作效率高。fsimage+edit = 内存中的元数据。

  • 长时间向Edits添加日志,越来越大,而且集群重启需要从fsimage+edit恢复文件系统太慢,怎么办?

    2NN将fsimage与edits合并。

NameNode和2ndNameNode的协同工作

  • NameNode启动,加载fsimage和edits存到内存中,每个block的元数据占150Byte。
  • 客户端请求对文件系统进行增删改等更新操作
  • NameNode将操作记录到edits中,再更新内存数据。(为什么?)
  • 2nnNameNode向NameNode请求是否需要checkpoint,checkpoint有两个条件
    1. 定时时间到了(1h)
    2. edits满了(1million条数据)
  • 请求执行checkpoint
  • 滚动正在写的edits_inprogress为edtis_001,
  • 创建新的edits_inprogress_002,后续写入这个文件
  • 将NameNode的fsimage和edits_001,加载到内存中合并,生成新的fsimage.checkpoint,传输给NameNode
  • NameNode将fsimage.checkpoint更名为fsimage,此时fsimage和edits_inprogress_002共同构成内存最新的数据

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-RPJTxZNb-1595422402735)(C:\Users\tensory\AppData\Roaming\Typora\typora-user-images\image-20200517180150665.png)]

fsimage和edits

各自存在哪里?

hdfs oiv / oev 可以查看fsimage和edits序列化文件

# 离线的fsimage文件转化为可读模式
hdfs oiv -p XML -i src  -o dst

# 离线的fsimage文件转化为可读模式
hdfs oev -p XML -i src  -o dst

NameNode

如何确定下次启动合并哪些edits文件?

seen_txtid

CheckPoint

2ndNameNode何时合并edits和fsimage

hdfs-site.xml配置

checkpoint.period,默认1h,

checkpoint.txns,100万条日志

check_period,1分钟检查一次日志的条数

NameNode的故障处理

NameNode挂了,数据如何恢复:

方法一:

  1. 将2ndNameNode的namesecondary目录下的所有数据拷贝到NameNode中dfs中,恢复部分数据,差了edit_inprogress这个部分、
  2. 启动NameNode

方式二:使用 -importCheckpoint启动NameNode,等待

  1. 配置hdfs-site.xml中的检查点,时间由3600s设置为短一点的时间,如120s

  2. 需要将2ndNameNode的namesecondary目录下的数据拷贝到NameNode目录的同级目录,并删除in_use.lock文件

  3. 导入检查点,NameNode启动

    hdfs namenode -importCheckpoint
    
  4. 等待120s,NameNode挂掉

  5. 启动NameNode

方法二更规范,检查的数据更多,但没有大的区别

集群的安全模式

NameNode启动

启动,将fsimage加载内存,执行edit中的操作,更新内存,建立fs的元数据镜像,创新的fsimage和一个空的edit。NameNode监听DataNode的请求,等待想他传递块的信息。这个过程,NameNode运行在安全模式,即NameNode的文件系统对客户端只读。

DataNode启动

启动,数据块以块列表的形式存储在DN中,安全模式下,各个DN向NN发送最新的块信息,NN了解足够多的块信息的时候,即可高效运行。

刚上电,DN要讲块信息山川给NN,这个过程处于安全模式。

安全模式退出判断

最小副本条件:NN会在30秒之后,推出安全模式。集群的99.9%的块满足至少1个副本,dfs.replication.min=1,则推出安全模式。

启动一个刚格式化的NN,由于系统没有块,所以不存在安全模式。

安全模式操作

# 查看安全模式状态,也可以在WebUI的Overview也可以看到
hdfs dfsadmin -safemod get

# 启动安全模式,HDFS只读
hdfs dfsadmin -safemod enter

# 离开安全模式
hdfs dfsadmin -safemod leave

# 等待安全模式离开
hdfs dfsadmin -safemod wait

案例

# 一个终端
# step1
hdfs dfsadmin -safemod enter
# step3
hdfs dfsadmin -safemod leave

# 另一个终端
# step2
#!/bin/bash
hdfs dfsadmin -safemod wait
hdfs dfs -put  ./my.txt /

NameNode添加多个目录

多个目录,存储的是完全相同的内容,但仍然是一个进程,只是一个数据的多副本数据可靠性。

DataNode

工作机制

  1. DN启动,向NN注册,发送块列表。数据:数据、长度、校验和、时间戳
  2. NN将信息写入内存,返回注册成功
  3. 以后DataNode每小时,上报所有块信息
  4. DataNode向NameNode发送心跳,心跳每3秒一次,NameNode返回的心跳带有给DataNode的命令
  5. 超过10分钟,没有收到DN的心跳,则NN认为该DN节点不可用,以后不会在该节点存储。

数据完整性

什么是奇偶校验?

奇偶校验只能校验单点故障,多点故障无法解决。

CRC

16、32、64、128位的CRC

对原始数据尽心CRC计算,与校验位尽心对比。

掉线时限设置

在hdfs-site.xml

心跳超过10分钟+30秒断了,NN认为DN不可用

有一个公式:2*5 分钟 + 30s

服役新数据节点

slaves文件只是为了群起集群,如果是单个节点启动,无需配置slaves。

所以新节点,不需要配置slaves,但是为了今后群起,可以配置。如果只是临时增加节点,后面要删除,不用加入slaves。只要在core-site.xml中配置了namenode,就能识别这个节点为集群的一部分。

添加白名单

服役新节点,没有任何限制,只需要知道NameNode的主机IP,如何解决这个问题?——添加白名单。

只有在白名单的节点,才可以访问NN。

  1. 在etc/hadoop/下创建dfs.hosts文件(随意命名),写入白名单节点

  2. 在hdfs-site.xml中引入这个文件,即dfs.hosts这个条目

  3. 分发配置文件

  4. 刷新NameNode,重新读取配置文件

    hdfs dfsadmin -refreshNodes

    yarn rmadmin -freshNodes

一般在刚搭建集群的时候,配置。如果想踢掉某个节点,采用白名单,数据依然标记在踢掉的节点。即Avalability依然标记被剔除的节点。

数据均衡

退役一个节点之后,负载可能不均衡

start-balancer.sh

黑名单

在黑名单的主机,被强制退出。

白名单和黑名单不能有交集。

  1. 创建dfs.hosts.exclude文件中添加想退役的节点。

  2. 在hdfs-site.xml中配置dfs.hosts.exclude

  3. 刷新hdfs和yarn。等待数据迁移完成。

  4. 在退役节点,关闭DN和NM进程。

这种方式,退役,保证退役节点的数据拷贝到其他节点,保证数据副本数。

重新启动集群的时候,WebUI上对应的几点会消失。

DataNode多目录的配置

DN的多目录的数据不是副本

应该在集群初始时刻配置

  1. 如果不是初始时刻,还原集群到初始时刻
  2. 在hdfs-site.xml配置多个目录
  3. 格式化NN
  4. 群起集群

HDFS 2.x新特性

集群间的数据拷贝

scp拷贝数据的三种方法,推、拉、第三方服务器方式

场景:测试集群的数据拷贝到生产集群。

hadoop distcp  hdfs://源集群的数据      hdfs://目的集群路径

小文件存档

HDFS存储小文件的弊端

NN的内存空间中,任何一个块,无论块的大小,都会占用150 Bytes。

办法之一

HDFS存档文件或HAR文件,是更高效的的存档工具,HDFS存档文件对内还是一个一个独立的文件,对NN来说是一个大文件。即多个小文件,对NN来说是一个文件,*.HAR文件。客户端访问的时候,依然是一个一个小文件。

操作

  1. 确保dfs和yarn

  2. 归档为.har文件(这是一个MR任务)

    hadoop archive -archiveName  归档后的文件名.har  -p  源数据   目的路径
    
  3. 查看原文件,如果不带har://,则查看归档后的文件

    hadoop fs -ls -R har:///user/hadoop/归档后的文件名.rar
    

    用户访问的时候,使用 har:///…这种路径使用,依然是一个个单独的文件,而对于HDFS是一个har文件。

回收站案例

默认关闭,因为很少删除数据,HDFS的最大特点是可以存储海量的数据,很少存储数据。

core-site.xml

fs.transh.interval=0,设置文件存货时间,分钟。

fs.trash.checkpoint.interval,设置检查回收站的数据是否到存活时间,为0表示与存活时间相等

权限问题,权限用户默认为dr.who,在core-site.xml中配置用户,http.staticuser.user

查看

/user/hadoop/.Trash

恢复回收站数据,使用hadoop fs -mv 命令,去回收站直接移动数据

清空

其实不是清空,而是重新命名了一下

快照管理

Linux的快照?

什么是SequenceFile?

SequenceFile是一种通过二进制序列化之后的key/value的字节流组成的文本存储文件。

key为文件位置和文件名,value为文件内容

map输出的临时文件就是以SequenceFile文件存储。

HDFS HA高可用

HA是提高NamNode的可靠性,依赖ZK

猜你喜欢

转载自blog.csdn.net/ten_sory/article/details/107523016