Hadoop相关

问题1: 为什么要用分布式?

答案: 解决单机存储容量有限的问题, 可以通过分布式解决(即: 横向扩展, 加机器).

问题2: HDFS是什么, 有几种角色, 各自作用是什么?

答案:
HDFS全称叫Hadoop Distributed FileSystem, 分布式文件存储系统, 采用分布式的方式来存储数据.
HDFS是主从架构, 主要角色有3个:
NameNode: 主节点管理整个HDFS集群,维护和管理元数据.
SecondaryNameNode: 辅助节点,辅助namenode管理元数据的.
DataNode: 从节点,负责数据的读写操作,负责存储具体的数据(Block块).

问题3: HDFS的默认副本是是几, 默认的块大小是多少?

答案: 默认副本是是 3, 每个Block块的大小为: 128MB.
实际开发中, 副本数一般是2-5, 副本数越高带来的好处是容错率越高, 带来的弊端是磁盘的利用率降低.
块的大小 和 副本数都是可以设置的, 即: /export/server/hadoop/etc/hadoop/hdfs-site.xml 文件即可.

dfs.replication
3 # 副本数

  <property>
    <name>dfs.blocksize</name>
    <value>134217728</value>        # 设置HDFS块大小,单位是字节
  </property>

– Hadoop 3.3.0版本 配置说明文档, URL地址为: https://hadoop.apache.org/docs/r3.3.0/

问题4:HDFS写数据流程是什么?

关键字: 1,Client

​ 2,namenode(权限校验)

​ 3,Client切块

​ 4,Client请求

​ 5,namenode(返回列表)

​ 6,Client&DataNode(建立连接形成管道)

​ 7,传输数据(64KB)ACK

​ 8,第二个块

答案:
1. Client请求namenode, 上传文件.
2. namenode接收到请求后, 校验权限, 然后告知Client是否可以写数据.
3. 假设可以写数据, 此时, Client对文件进行切块(默认: 128MB/块)
4. Client重新请求namenode, 第1个Block的上传位置.
5. namenode返回第1个块的上传位置, 即: datanode列表, 例如: node1, node2, node3
6. Client和最近的那个datanode建立连接, 并依次和其它的datanode建立连接, 形成 传输管道(pipeline)
7. 采用数据报包(默认: 64KB)的方式传输数据, 并建立反向应答机制(Ack).
8. 依次传输, 直至第1个Block块传输完毕.
9. 回到第4步, Client重新请求第2个Block的上传位置, 重复后续动作, 直至所有的Block传完.
10. 至此, HDFS写数据流程结束.

问题5:HDFS读数据流程是什么?

提示: 1,Client请求Namenode

​ 2,Namenode校验

​ 3,Client连接DataNode

​ 4,向Namenode请求,获取剩下的块

​ 5,合并

答案: # 核心词: 并行.
1. Client请求namenode, 读取文件数据.
2. namenode校验权限合法后, 返回该文件的部分或者全部的Block块信息(即: 这些块在哪些datanode上存储)
3. Client连接这些datanode, 并行的从中读取这些Block块的信息.
4. 当上述的块信息读取完毕后, Client会请求namenode获取剩下的全部或者部分的块信息, 直至所有的块读取完毕.
5. 按照块的编号, 对读取到的数据做合并, 获取最终结果文件, 至此HDFS读数据流程完毕.

问题6:NameNode是如何管理元数据的?

另一种问法是namenode如何管理Block块?

提示: 1,edits文件

​ 2,新edits文件

​ 3,FSImage文件

1. namenode通过管理 Edits文件 和 FsImage文件来实现管理元数据的目的.
2. Edits文件, 相对较小, 修改起来速度较快, 记录的是最近一段时间的元数据信息.
3. FSImage文件, 相对较大, 记录的是HDFS的所有元数据.
4. HDFS集群启动的时候, namenode会去加载FsImage文件 和 最近的那个 Edits文件的元数据进内存.

Edits文件 和 FsImage文件的存储位置在: /export/data/hadoop/dfs/name/current

问题7: SecondaryNameNode如何辅助namenode管理元数据?

提示:

​ 1,实时监听Edits

​ 2,合并FSImage和Edits形成新的FSImage文件

​ 3,推送给Namenode

​ 4,小细节

答案:

  1. SecondaryNameNode会实时监听(间隔60秒)Edits文件的状态, 当其(Edits文件)达到一定的阈值(1个小时或者100W次),
    SecondaryNameNode就会通知namenode禁用该Edits文件, 然后创建1个新的Edits文件, 继续往里写入.

  2. SecondaryNameNode会通过Http协议将namenode中的Edits文件 和 FsImage文件拉取到本地进行合并, 形成新的FsImage文件.合并全程, namenode不参与.

  3. 然后SecondaryNameNode会将合并后的新的FsImage文件推送给namenode, 用来替代旧的FsImage文件

  4. namenode上会有大量的Edits文件和一堆的FsImage文件, 这些文件不会被立马删除, 而是在服务重启的时候, 或者达到一定阈值的时候, namenode才会删除.

问题8: namenode如何管理datanode?

答案: 副本机制(默认是3), 心跳机制(3秒, 630秒, 6个小时), 负载均衡.

  • 1.副本机制:为了保证数据安全和效率,block块信息存储多个副本,第一副本保存在客户端所在服 务器,第二副本保存在和第一副本不同机架服务器上,第三副本保存在和第二副本相同机架不同服 务器
  • 2.负载均衡机制: namenode为了保证不同的datanode中block块信息大体一样,分配存储任务的 时候会优先保存在余量比较大的datanaode上
  • 3.心跳机制:datanode每隔3秒钟向namenode汇报自己的状态信息,如果某个时刻,datanode连 续10次不汇报了,namenode会认为datanode有可能宕机了,namenode就会每5分钟(300000毫秒) 发送一次确认消息,连续2次没有收到回复,就认定datanode此时一定宕机了

问题9: HDFS的默认副本数是3, 请问这3个副本是如何存储的?

答案:
第1副本: 优先本机, 否则就近随机.
第2副本: 和第1副本相邻的不同机架的某个服务器上.
第3副本: 和第2副本相同的机架的不同服务器上.
如果不满足上述情况, 则 随机存储.

HDFS的安全模式(Safemode)

​ 概述:
​ 安全模式是HDFS的一种保护机制, 其特点是: 在安全模式下, 只能读, 不能更新(因为更新会修改元数据)
​ 问题: 什么时候会进入到安全模式?
​ 答案:
​ 情况1: 启动HDFS集群的时候, namenode会去读取Edits文件 和 FsImage文件的元数据信息到内存中, 该过程中会强制进入到安全模式.过程结束(HDFS自检动作没问题), 会自动退出安全模式.
​ 情况2: 当datanode的数量 小于 副本数的时候, 会强制进入到安全模式.
​ 情况3: 手动进入到安全模式, 一般用于排错.
​ 涉及到的命令如下:
​ hdfs dfsadmin -safemode get 查看安全模式的状态, OFF:关, ON:开
​ hdfs dfsadmin -safemode enter 进入到安全模式
​ hdfs dfsadmin -safemode leave 退出安全模式

HDFS的归档(Archive)

概述:

​ HDFS适用于存储海量的大文件, 那如果要用HDFS存储大量的小文件时, 每个小文件都会占用1个Block块, 就会导致元数据过多, 针对于这种情况,
​ 就可以用 归档 技术来解决.
​ 本质:
​ 归档相当于把大量的小文件放到一起, 形成1个整体, 类似于压缩包的动作, 但是只有压, 没有缩.
​ 好处:
​ n个小文件 = n个Block块 = N份元数据 => 归档后, n个小文件 = 1个归档包(文件) = 1个Block块 = 1份元数据信息

相关操作:

  1. 在HDFS下创建data文件夹, 里边有1.txt, 2.txt, 3.txt三个文件.
    hadoop fs -put *.txt /data
  2. 把 /data目录下的 3个txt文件 合并成 1个归档包, 放到 /output目录下.
    细节: 归档的底层其实是MR程序.
    格式如下:
    hadoop archive -archiveName 归档包名 -p 要归档的文件路径 存放归档包的路径
    例如:
    hadoop archive -archiveName myTest.har -p /data /output
  3. 去 /output目录下查看内容, 发现(直接)看不到 1.txt, 2.txt, 3.txt的信息.
    hadoop fs -ls /output/myTest.har – 看不到 1.txt, 2.txt, 3.txt的信息. 因为文件系统前缀是 hdfs://ndoe1:8020/
    hadoop fs -cat /output/myTest.har/1.txt
  4. 如何去归档包中查看归档前的内容内? 命令如下:
    hadoop fs -ls har:///output/myTest.har – 可以看到, 因为用的是 har:///这个前缀, 全称是: har://hdfs-node1:8020/
    hadoop fs -cat har:///output/myTest.har/1.txt

​ hadoop fs -ls har://hdfs-node1:8020/output/myTest.har
即: 写不同的前缀, 意味着用不同的文件系统来识别该文件.

  1. 删除/data目录下的 3个txt文件, 然后从 /output 的归档包中拷贝 3个txt文件 到 /data目录下.
    hadoop fs -cp /output/myTest.har/ /data – 把归档包拷贝到 /data目录下, 拷贝的是 myTest.har包下的内容, 达不到我们要的效果.

    hadoop fs -cp har:///output/myTest.har/ * /data -- 把归档包拷贝到 /data目录下, 归档拷贝.

结论:

​ 归档操作实际开发中, 一般是一周或者1个月做一次, 把该周或者该月所有的数据放到1个归档包中, 降低元数据, 且后期需要单独使用的时候, 也可以很方便的从归档包拷贝数据出来.

HDFS的垃圾桶(Trash)机制:

概述:

​ 如果没有开启HDFS的垃圾桶机制, 默认是直接删除文件或者文件夹的, 不走垃圾桶(不可恢复, 相当于永久删除).
​ 如果开启了HDFS的垃圾桶机制, 则删除数据(文件或者目录)的时候, 本质是将该 文件/目录 移动到垃圾桶中(可恢复的).
开启垃圾桶的方式:

    1. 修改 /export/server/hadoop/etc/hadoop/core-site.xml 文件, 加入如下内容:
    <property>
            <name>fs.trash.interval</name>
            <value>1440</value>     # 垃圾桶保留多长时间, 单位是: 分钟, 即: 1天.
    </property>
    2. 记得将 core-site.xml文件分发给node2, node3, 即: 三台机器都要修改.
        `scp core-site.xml node2:$PWD`
        `scp core-site.xml node3:$PWD`
       如果你不想拷贝, 就手动逐个机器修改, 修改node1的core-site.xml, 修改node2的, 修改node3的...
    3. 重启Hadoop集群.
        stop-all.sh
        start-all.sh        # 这两个命令均是在 node1中执行的.
    4. 之后就可以测试删除的功能了, 涉及到的HDFS Shell命令如下.
        `hadoop fs -rm /data/2.txt`                                      -- 此时的删除就是 剪切到 垃圾桶中.
        `hadoop fs -mv /user/root/.Trash/Current/data/2.txt /data       -- 从垃圾桶中恢复源文件.`
        `hadoop fs -rm -skipTrash /data/2.txt                           -- 跳过垃圾桶, 相当于永久删除.`