1. HDFS的架构 *

HDFS主要包括三个部分,namenode,datanode以及secondary namenode。这里主要讲一下他们的作用:namenode主要负责存储数据的元数据信息,不存储实际的数据块,而datanode就是存储实际的数据块,secondary namenode主要是定期合并FsImage和edits文件(这里可以进行扩展,讲一下为什么有他们的存在?首先namenode存储的元数据信息是会放在内存中,因为会经常进行读写操作,放在磁盘的话效率就太低了,那么这时候就会有一个问题,如果断电了,元数据信息不就丢失了吗?所以也需要将元数据信息存在磁盘上,因此就有了用来备份元数据信息的FsImage文件,那么是不是每次更新元数据信息,都需要操作FsImage文件呢?当然不是,这样效率不就又低了吗,所以我们就引入了edits文件,用来存储对元数据的所有更新操作,并且是顺序写的方式,效率也不会太低,这样,一旦重启namenode,那么首先就会进行FsImage文件和edits文件的合并,形成最新的元数据信息。这里还会有一个问题,但是如果一直向edits文件进行写入数据,这个文件就会变得很大,那么重启的时候恢复元数据就会很卡,所以这里就有了secondary namenode在namenode启动的时候定期来进行fsimage和edits文件的合并,这样在重启的时候就会很快完成元数据的合并)

2. HDFS的读写流程 *

写流程:hadoop fs -put a.txt /user/sl/​
首先客户端会向namenode进行请求,然后namenode会检查该文件是否已经存在,如果不存在,就会允许客户端上传文件;​

客户端再次向namenode请求第一个block上传到哪几个datanode节点上,假设namenode返回了三个datanode节点;​

那么客户端就会向datanode1请求上传数据,然后datanode1会继续调用datanode2,datanode2会继续调用datanode3,那么这个通信管道就建立起来了,紧接着dn3,dn2,dn1逐级应答客户端;​

然后客户端就会向datanode1上传第一个block,以packet为单位(默认64k),datanode1收到后就会传给datanode2,dn2传给dn3​

当第一个block传输完成之后,客户端再次请求namenode上传第二个block。【写的时候,是串行的写入 数据块】

读流程:hadoop fs -get a.txt /opt/module/hadoop/data/​

首先客户端向namenode进行请求,然后namenode会检查文件是否存在,如果存在,就会返回该文件所在的datanode地址,这些返回的datanode地址会按照集群拓扑结构得出 datanode与客户端的距离,然后进行排序;然后客户端会选择排序靠前的datanode来读取block,客户端会以packet为单位进行接收,先在本地进行缓存,然后写入目标文件中。【读的时候,是并行的读取 数据块】

3. HDFS中,文件为什么以block块的方式存储

主要是减少硬盘寻道时间​

  • 不设置block:因为数据是分散的存放磁盘上的,读取数据时需要不停的进行磁盘寻道,开销比较大。​
  • 使用block: 一次可以读取一个block中的数据,减少磁盘寻道的次数和时间。

4. 小文件过多有什么危害,你知道的解决办法有哪些 *

危害:​

  • 存储大量的小文件,会占用namenode大量的内存来存储元数据信息​
  • 在计算的时候,每个小文件需要一个maptask进行处理,浪费资源​
  • 读取的时候,寻址时间超过读取时间​

解决方法:​

  • 在上传到hdfs之前,对小文件进行合并之后再上传​
  • 采用har归档的方式对小文件进行存储,这样能够将多个小文件打包为一个har文件​
  • 在计算的时候,采用combineinputformat的切片方式,这样就可以将多个小文件放到一个切片中进行计算。​
  • 开启uber模式,实现JVM的重用,也就是说让多个task共用一个jvm,这样就不必为每一个task开启一个jvm

5. 在NameNode HA中,会出现脑裂问题吗?怎么解决脑裂

  • 假设 NameNode1当前为 Active 状态,NameNode2 当前为 Standby 状态。如果某一时刻 NameNode1对应的 ZKFailoverController 进程发生了"假死"现象,那么 Zookeeper服务端会认为NameNode1 挂掉了,NameNode2 会替代 NameNode1 进入 Active 状态。但是此时 NameNode1 可能仍然处于 Active 状态正常运行,这样 NameNode1 和 NameNode2 都处于 Active 状态,都可以对外提供服务。这种情况称为脑裂​
  • Zookeeper对这种问题的解决方法叫做 fencing(隔离),也就是想办法把旧的 Active NameNode 隔离起来,使它不能正常对外提供服务​
    • 首先尝试调用这个旧 Active NameNode 的 HAServiceProtocol RPC 接口的transitionToStandby 方法,看能不能把它转换为 Standby 状态。 ​
    • 如果 transitionToStandby方法调用失败,那么就执行 Hadoop 配置文件之中预定义的隔离措施,Hadoop目前主要提供两种隔离措施,通常会选择 sshfence: ​
    • sshfence:通过 SSH 登录到目标机器上,执行命令 fuser 将对应的进程杀死 ​
    • shellfence:执行一个用户自定义的 shell 脚本来将对应的进程隔离

6. 简述hadoop压缩和解压缩的框架

  • gzip压缩:压缩率比较高,而且压缩/解压缩速度也比较快,hadoop本身支持,但是不支持切片​
  • bzip2压缩:比gzip的压缩率更高,hadoop本身支持,而且还支持切片,但是压缩/解压缩速度很慢​
  • lzo压缩:合理的压缩率,压缩/解压缩速度也比较快,而且支持切片,但是hadoop本身不支持,需要安装,压缩率要比gzip低一些,为了支持切片,还需要手动为lzo压缩文件创建索引​
  • snappy压缩:合理的压缩率,压缩/解压缩速度也比较快,但是不支持切片,hadoop本身不支持,需要安装,压缩率要比gzip低一些

7. namenode的安全模式有了解吗?

  • 安全模式是指hdfs对于客户端来说是只读的​
  • 什么时候会进入安全模式?​
    • namenode启动的时候,首先会进行fsimage和edits的合并,然后namenode监听datanode,datanode汇报最新的数据块信息,这个过程namenode就会处于安全模式​
  • 什么时候会退出安全模式?​
    • 如果整个文件系统中99.9%的数据块满足最小的副本级别(默认为1),namenode会在30秒之后退出安全模式。刚初始化HDFS的时候,因为系统中没有任何块,所以namenode不会进入安全模式​
  • 命令:bin/hdfs dfsadmin -safemode get/enter/leave/wait

8. Secondary NameNode 了解吗,它的工作机制是怎样的

secondary namenode主要是用于edit logs和fsimage的合并,edit logs记录了对namenode元数据的增删改操作,fsimage记录了最新的元数据检查点,在namenode重启的时候,会把edit logs和fsimage进行合并,形成新的fsimage文件

  • Secondary NameNode 主要是 用于合并 NameNode 的 edit logs 到 fsimage 文件中​
  • 工作机制:​
    • Secondary NameNode 询问 NameNode 是否需要 checkpoint。直接带回NameNode 是否检查结果 ​
    • Secondary NameNode 请求执行 checkpoint ​
    • NameNode 滚动正在写的 edits 日志 ​
    • 将滚动前的编辑日志和镜像文件拷贝到 Secondary NameNode ​
    • Secondary NameNode 加载编辑日志和镜像文件到内存,并合并 ​
    • 生成新的镜像文件 fsimage.chkpoint​
    • 拷贝 fsimage.chkpoint 到 NameNode​
    • NameNode 将 fsimage.chkpoint 重新命名成 fsimage​
  • 所以如果 NameNode 中的元数据丢失,是可以从 Secondary NameNode 恢复一部分元数据信息的,但不是全部,因为 NameNode 正在写的 edits 日志还没有拷贝到 Secondary NameNode,这部分恢复不了

Logo

码道开发者社区,聚焦华为云码道 CodeArts 代码智能体,沉淀 Agent、Skill、鸿蒙开发实战内容,供开发者查阅资料、交流技术、分享工程实践

更多推荐