Hadoop

一、Hadoop概述

hadoop之父(Doug Cutting) 道格·卡丁

Hadoop本身是一个项目,该项目由多个模块组成

Hadoop Common: 为hadoop的其他模块提供支持。是一个通用的工具模块
Hadoop Distributed File System (HDFS): 存数据的。高吞吐访问。
Hadoop YARN: 是一个作业调度和集群资源管理的框架
Hadoop MapReduce:基于yarn的一个大数据并行处理框架。做数据计算的

狭义的hadoop:就是hadoop本身

广义的hadoop:是指hadoop的生态圈,就是一系列的大数据技术。

 

二、HDFS

1、HDFS配置

(1)、配置预备事项

1、创建hadoop用户,配置hadoop的sudo权限
2、使用hadoop登录
3、在hadoop的家目录下创建以下目录
  installPkg #上传程序
  apps #安装程序
  data #测试数据
  scripts #脚本目录
4、准备3台及以上的虚拟机

(2)、jdk安装

#1.解压并指定安装目录
tar -zxvf jdk-8u144-linux-x64.tar.gz -C ../apps/

#2.进入apps目录找到jdk1.8.0_144/,创建软连接
ln -s jdk1.8.0_144/ jdk

#3.配置环境变量
#编辑环境变量文件
vim /etc/profile
#创建java变量,jdk是软连接名
export JAVA_HOME=/home/hadoop/apps/jdk
#向PATH中追加JAVA_HOME/bin目录
export PATH=$PATH:$JAVA_HOME/bin

#4.运行配置文件,使命令生效
. /etc/profile

(3)、配置hdfs

#1.解压并指定安装目录
tar -zxvf hadoop-2.7.3.tar.gz -C ../apps/

#2.进入apps目录找到hadoop-2.7.3/,创建软连接
ln -s hadoop-2.7.3/ hadoop

#3.配置环境变量
#编辑环境变量文件
vim /etc/profile
#创建hadoop变量,hadoop是软连接名
export HADOOP_HOME=/home/hadoop/apps/hadoop
#向PATH中追加HADOOP_HOME/bin目录
export PATH=$PATH:$HADOOP_HOME/bin

#4.运行配置文件,使命令生效
. /etc/profile

#5.修改hadoop-env.sh文件
vim /home/hadoop/apps/hadoop/etc/hadoop/hadoop-env.sh
#把JAVA_HOME配置为绝对路径
export JAVA_HOME=/home/hadoop/apps/jdk

#6.删除文件中所有.cmd后缀的文件(windows系统的,不要),删除/home/hadoop/apps/hadoop/share下的doc文件夹

#7.修改core-site.xml文件
vim /home/hadoop/apps/hadoop/etc/hadoop/core-site.xml
#在<configuration></configuration>标签中加入以下标签
  <!--配置NameNode的地址-->
  <property>
    <name>fs.defaultFS</name>
    <value>hdfs://hadoop1010:9000</value>
  </property>
  <!--配置NN和DN的数据目录-->
  <property>
    <name>hadoop.tmp.dir</name>
    <value>/home/hadoop/apps/hadoop/data</value>
  </property>
 
#8.修改slaves,配置DataNode的地址
vim /home/hadoop/apps/hadoop/etc/hadoop/slaves
#添加主机名
hadoop1010
hadoop1020
hadoop1030

#9.分发apps/目录及配置文件给所有datanode主机
#批量免密 /home/hadoop/nodes目录下运行nopasswd.sh文件
./nopasswd.sh 用户名
#分发apps/目录到各datanode主机,/home/hadoop/nodes目录下运行nodes.sh文件
./nodes.sh apps/
#分发配置文件到/etc/profile,单独分发
sudo scp /etc/profile root@各主机名

#10.在data目录下,格式化hdfs
[hadoop@hadoop10 data]$ hdfs namenode -format
#出现......has been successfully formatted.则成功

#11.在sbin目录下,启动hdfs
启动NameNode:
[hadoop@hadoop10 sbin]$ ./hadoopdaemon.sh start namenode
启动DataNode:
[hadoop@hadoop20 sbin]$ ./hadoopdaemon.sh start datanode

#12.查看NameNode的web端口
#查询NameNode的进程号
[hadoop@hadoop10 sbin]$ jps
#查询NameNode的端口
[hadoop@hadoop10 sbin]$ netstat -nltp | grep 进程号

#13.浏览器访问bin监控datanode
http://Namenode主机名:端口号/
## 9000:内部通信的RPC端口       50070:hdfs webui端口

2、HDFS客户端

(1)、启动客户端

HDFS自带的群起脚本

# 注意:群起脚本必须配置免密
[hadoop@hadoop10 sbin]$ ./start-dfs.sh
[hadoop@hadoop10 sbin]$ ./stop-dfs.sh

(2)、shell客户端

hdfs dfs #run a filesystem command on the file systems supported in Hadoop.

#上传文件到hdfs
[hadoop@hadoop10 installPkg]$ hdfs dfs -put 1.txt /
[hadoop@hadoop10 installPkg]$ hdfs dfs -copyFromLocal 1.txt /
#下载hdfs文件到本地
[hadoop@hadoop12 ~]$ hdfs dfs -get /jdk-8u144-linux-x64.tar.gz ./
[hadoop@hadoop12 ~]$ hdfs dfs -copyToLocal /1.txt ./
#查看hdfs上的文件
[hadoop@hadoop12 ~]$ hdfs dfs -ls /
#查看hdfs文件内容
[hadoop@hadoop12 ~]$ hdfs dfs -cat /1.txt
[hadoop@hadoop12 ~]$ hdfs dfs -text /1.txt
#追加内容
[hadoop@hadoop10 data]$ hdfs dfs -appendToFile 2.txt /1.txt
#获取校验和
[hadoop@hadoop10 data]$ hdfs dfs -checksum /1.txt
#更改文件权限
[hadoop@hadoop10 data]$ hdfs dfs -chmod 777 /1.txt
[hadoop@hadoop10 data]$ hdfs dfs -chmod o-x /1.txt
#复制文件
[hadoop@hadoop10 data]$ hdfs dfs -cp /1.txt /21.txt
[hadoop@hadoop10 data]$ hdfs dfs -cp /a /aa
#创建目录
[hadoop@hadoop10 data]$ hdfs dfs -mkdir -p /a/b
#移动
[hadoop@hadoop10 data]$ hdfs dfs -mv /a /aa
#查看磁盘使用量
[hadoop@hadoop10 opt]$ hdfs dfs -du -h /
11 /1.txt
5 /aaa
185515842 /jdk-8u144-linux-x64.tar.gz
#查看磁盘剩余大小
[hadoop@hadoop10 opt]$ hdfs dfs -df -h /
#查找文件
[hadoop@hadoop10 opt]$ hdfs dfs -find / -name 1.txt
#hdfs和本地文件系统之间移动文件
[hadoop@hadoop10 data]$ hdfs dfs -moveFromLocal 1.txt /x.txt
#目前2.7.3不支持-moveToLocal
#删除空目录
[hadoop@hadoop10 data]$ hdfs dfs -rmdir /aa
#递归强制删除目录
[hadoop@hadoop10 data]$ hdfs dfs -rm -rf /aa
#设置副本数
[hadoop@hadoop10 data]$ hdfs dfs -setrep 2 /1.txt
#创建空文件
[hadoop@hadoop10 data]$ hdfs dfs -touchz /a.txt

3、HDFS Architecture

HDFS应用程序需要一个写一次读多的文件访问模型。文件一旦创建、写入和关闭,除了追加和截断之外,不允许更改。
Moving Computation is Cheaper than MovingData 移动计算比移动数据更划算

1598774534319

生产部署中,NameNode部署在一台专属的服务器上,和DataNode不在一台节点上。

(1)、The File System Namespace

HDFS支持传统的分层文件组织、支持用户配额和访问权限,HDFS不支持硬链接或软链接。

HDFS的根目录是 / ,用户或应用程序可以创建目录,并在这些目录中存储文件。文件系统名称空间层次结构类似于大多数其他现有的文件系统。可以创建和删除文件,将文件从一个目录移动到另一个目录,或者重命名文件。

元数据的持久性

HDFS名称空间由NameNode存储。NameNode使用一个称为EditLog的事务日志持久地记录对文件系统元数据发生的每个更改。例如,在HDFS中创建一个新文件会导致NameNode向EditLog中插入一条记录,以表明这一点。类似地,更改文件的复制因子会导致将新记录插入到EditLog中。NameNode在其本地主机OS文件系统中使用一个文件来存储编辑日志。整个文件系统名称空间,包括块到文件和文件系统属性的映射,存储在一个名为FsImage的文件中。FsImage也作为文件存储在NameNode的本地文件系统中。

FsImage存储的内容:整个文件系统名称空间,包括块到文件和文件系统属性的映射。
为什么FsImage没有存储block到DN的映射 ?

因为block到DN的映射是通过DataNode汇报得到的,不需要持久化。但是内存中的元数据信息是存储了block到DN的映射的。

数据复制

HDFS被设计为在大型集群中跨机器可靠地存储非常大的文件。它将每个文件存储为一系列的块。复制文件的块以实现容错。每个文件都可以配置块大小和复制因子。应用程序可以指定文件副本的数量。复制因子可以在文件创建时指定,也可以在以后更改。HDFS中的文件是写一次的(除了追加和截断),并且在任何时候都只有一个写入器。
NameNode做出关于块复制的所有决策。它定期从集群中的每个DataNode接收一个心跳和一个块报告,接收到心跳意味着DataNode运行正常。Blockreport包含DataNode上所有块的列表。

 

(2)、NameNode and DataNodes

HDFS是一个主从master-slave结构的集群,由一个NameNode和N个DataNode组成。

分布式:将一个完整的系统,拆分成多个子系统,这些子系统分布在不同的节点上,共同完成系统的功能。
集群:相同功能的多个节点组成一个集群
racks:机架     Cluster:集群

NameNode的职责

1、管理文件系统的名称空间
2、管理客户端对文件的访问
3、NameNode执行文件系统名称空间操作,如打开、关闭和重命名文件和目录
4、决定了block到DataNode的映射
5、存储文件的副本因子
   一个文件的拷贝数称为该文件的复制因子。

DataNode的职责

1、存储数据
存储在HDFS的文件会被分隔成一个一个的block(默认大小128M)。这些block存储在DataNode上。
2、负责为客户端的读和写请求提供服务
3、根据NameNode的指令执行块(block)的创建、删除和复制。

副本放置策略

1598775964057

(3)、Secondary namenode

为什么需要Secondary

NameNode职责是管理元数据信息,DataNode的职责是负责数据具体存储。

1、如果edit logs文件会变的很大,怎么去管理这个文件是一个挑战。
2、NameNode重启会花费很长时间,因为有很多改动要合并到fsimage文件上。
3、如果NameNode挂掉了,那就丢失了一些改动。因为此时的fsimage文件非常旧。

为了克服这个问题,我们需要一个易于管理的机制来帮助我们减小edit logs文件的大小和得到一个最新的fsimage文件,这样也会减小在NameNode上的压力。这跟Windows的恢复点是非常像的,Windows的恢复点机制允许我们对OS进行快照,这样当系统发生问题时,我们能够回滚到最新的一次恢复点上。

Secondary配置

[hadoop@hadoop10 hadoop]$ vim hdfs-site.xml
<property>
	<name>dfs.namenode.secondary.httpaddress</name>
	<value>hadoop11:50090</value>
</property>

Secondary主要工作

secondarynamenode的主要工作,是将fsimage和edits文件合并。

每达到checkpoint触发条件,会由secondarynamenode将namenode上积累的所有edits和一个最新的fsimage文件下载到本地,并加载到内存进行merge(这个过程称为checkpoint)

1597298251183

(4)、checkpoint

NameNode在内存中保存整个文件系统名称空间和文件块映射的映像。这个关键的元数据项被设计得很紧凑,这样一个有4 GB RAM的NameNode就足够支持大量的文件和目录了。

当NameNode启动时,它从磁盘读取FsImage和EditLog,将来自EditLog的所有事务应用到FsImage的内存表示中,并将这个新版本刷新到磁盘上的新FsImage中。然后,它可以截断旧的编辑日志,因为它的事务已经应用到持久到FsImage,这个过程称为检查点。

1598775449647

在当前实现中,检查点只在NameNode启动时发生。

checkpoint触发条件

1、namenode启动时,会自动触发
2、secondary namenode每小时会进行一次checkpoint(配置文件)
3、secondary namenode每分钟会检测txid的数量,当txid达到100W时,触发checkpoint。(配置文件)

Checkpoint操作受两个参数控制,可以通过core-site.xml进行配置:

两次连续的checkpoint之间的时间间隔,默认1小时

<property>
  <name>dfs.namenode.checkpoint.period</name>
  <value>3600</value>
</property>

最大的没有执行checkpoint事务的数量 默认为100万。满足将强制执行紧急checkpoint,即使尚未达到检查点周期。

<property>
 <name>dfs.namenode.checkpoint.txns</name>
 <value>1000000</value>
</property>

checkpoint执行步骤

1、当触发checkpoint操作时,namenode会生成一个新的edits文件,同时secondarynamenodeh会主动拉取namenode中的edits文件和fsimage文件(HTTP Get)到本地。

2、secondarynamenode将拉取过来的fsimage载入到内存中,,然后一条条的执行edits文件中的各项更新操作,使内存中的fsimage保持最新状态,这就是fsimage和edits文件的合并,最终会生成一个最新的fsimage文件。

3、secondarynamenode将最新生成的fsimage文件复制到namenode节点。
namenode节点的edits.new文件和fsimage文件则会进行更新操作,删除旧的fsimage文件和edits文件,当然不是整个删除,只是根据配置的fsimage数量和edits文件数量,删除最旧的文件。

4、等待下一次checkpoint触发secondarynamenode进行工作,并以此循环往复。

secondarynamenode合并生成的fsimage文件并不是最新的,因为在它合并生成的同时,新的更新操作以及写到edit.new文件中去了,而这些更新在secondarynamenode中是没有完成同步的。虽然如此,但若namenode真的出现问题了,使用secondarynamenode上的fsimage文件替换掉namenode上fsimage文件,依旧可以减少绝大部分损失。

4、其它

Blockreport块报告

当DataNode启动时,它会扫描本地文件系统,生成与每个本地文件对应的所有HDFS数据块的列表,并将这个报告发送给NameNode:这就是Blockreport。

DataNode不知道HDFS文件。它将每个HDFS数据块存储在本地文件系统的单独文件中。

dfs.blockreport.intervalMsec = 21600000
#DN汇报数据块的时间

Robustness 鲁棒性

鲁棒是Robust的音译,也就是健壮和强壮的意思。它也是在异常和危险情况下系统生存的能力。

故障检测

DataNode定期(默认3s)向NameNode发送心跳包。
收不到心跳超过10分钟,DataNode就会被标记成 Dead DataNode

dfs.datanode.scan.period.hours = 504 
#DN每三周扫描一次本地的数据块,如果有坏块,会删除

需要重新复制的原因有很多:

DataNode可能变得不可用      副本可能损坏
DataNode上的硬盘可能失      文件的复制因子可能增加

数据完整性

从DataNode获取的数据块可能已损坏。

存储设备故障、网络故障或有缺陷的软件都可能导致这种损坏

HDFS客户端软件实现了对HDFS文件内容的校验和检查。

当客户机创建HDFS文件时,它计算文件每个块的校验和,并将这些校验和存储在同一个HDFS名称空间中的单独隐藏文件中。当客户端检索文件内容时,它将验证从每个DataNode接收到的数据是否与存储在相关校验和文件中的校验和匹配。如果没有,那么客户端可以选择从具有该块副本的另一个DataNode检索该块。

数据块

HDFS支持对文件执行一次写读多的语义。HDFS使用的典型块大小是128mb,因此,一个HDFS文件被切成128mb的块,如果可能的话,每个块将驻留在不同的
DataNode上。

分布式存储:HDFS将一个完整的文件,拆分成若干个block,分布在不同的节点上存储。

HDFS是块级文件系统,把文件拆分成了若干个block。为什么需要拆分块?

1、降低磁盘读写IO
2、数据的负载均衡
3、提高并行度

文件上传

创建文件的客户机请求不会立即到达NameNode。实际上,最初HDFS客户机将文件数据缓存到本地缓冲区中。应用程序写入被透明地重定向到这个本地缓冲区。当本地文件累积的数据超过一个块大小时,客户机将与NameNode联系。NameNode将文件名插入到文件系统层次结构中,并为其分配一个数据块。NameNode使用DataNode的标识和目标数据块响应客户机请求。然后,客户端将数据块从本地缓冲区刷新到指定的DataNode。当关闭一个文件时,本地缓冲区中剩余的未刷新数据将被传输到DataNode。然后客户机告诉NameNode文件已关闭。此时,NameNode将文件创建操作提交到持久存储中。如果NameNode在文件关闭前终止,则文件将丢失。
先写入本地缓冲是为了提高吞吐量和性能。

客户端向NN请求上传文件时,NN返回的多个DN组成的列表就是pipeline

假设HDFS文件的复制因子为3
当客户端向HDFS文件写入数据时,它的数据首先被写入到本地缓冲区中。
当本地缓冲区积累用户数据块时,客户端从NameNode中检索DataNode列表。此列表包含将承载该块副本的DataNode。然后,客户端将数据块刷新到第一个DataNode。第一个DataNode开始小部分地接收数据,将每个部分写入本地存储库,并将该部分传输给列表中的第二个DataNode。第二个DataNode依次开始接收数据块的每个部分,将该部分写入其存储库,然后将该部分刷新到第三个DataNode。最后,第三个DataNode将数据写入其本地存储库。因此,DataNode可以从管道中的前一个DataNode接收数据,同时将数据转发到管道中的下一个DataNode。
因此,数据被pipeline从一个DataNode传输到下一个DataNode。

查看fsImage和editlog

查看fsimage

#查看fsimage
hdfs oiv -i fsimage_0000000000000000131 -o /home/hadoop/data/image.xml -p XML

1598777224748

查看editlog

#查看editlog
hdfs oev -i edits_0000000000000000127-0000000000000000131 -o
/home/hadoop/data/edit.xml -p XML

1598777329661

 

Snapshot快照

路径允许快照与否

允许这个文件路径可以创建snapshots:

hdfs dfsadmin -allowSnapshot <路径>
#[hadoop@hadoop10 dfs]$ hdfs dfsadmin -allowSnapshot /test

不允许创建目录的快照。必须先删除目录的所有快照,然后再禁止快照。

hdfs dfsadmin -disallowSnapshot <路径>

快照的创删改查

创建快照

hdfs dfs -createSnapshot <路径> [<快照名称>]
#[hadoop@hadoop10 test]$ hdfs dfs -createSnapshot /test snapshot02

删除快照

hdfs dfs -deleteSnapshot <路径> <快照名称>
#[hadoop@hadoop10 test]$ hdfs dfs -deleteSnapshot /test snapshot01 

重命名快照

hdfs dfs -renameSnapshot <路径> <旧名称> <新名称>
# hdfs dfs -renameSnapshot /data/mytest mytest-snap mytest-snap-new

获取Snapshottable目录列表

hdfs lsSnapshottableDir

获取快照差异报告

hdfs snapshotDiff <路径> <fromSnapshot> <toSnapshot>
#[hadoop@hadoop10 test]$ hdfs snapshotDiff /test snap01 snap02
M       .
+       ./img.xml
+       ./null

快照文件恢复

将快照snapshot01状态中的文件拿取出来

(快照文件是隐藏的,使用此命令即可将快照文件复制出来)

hdfs dfs -cp -ptopax <快照路径> <恢复路径>
#[hadoop@hadoop10 test]$ hdfs dfs -cp -ptopax /test/.snapshot/snapshot01 /

Hdfs回收站

Hadoop回收站trash,默认是关闭的

1、修改配置文件core-site.xml

    <property>  
      <name>fs.trash.interval</name>  
      <value>1440</value>  
      <description>Number of minutes between trash checkpoints. 
      If zero, the trash feature is disabled.  
      </description>  
    </property>  

2、重启hdfs服务

./stop-dfs.sh
./start-dfs.sh

3、删除文件测试

# [hadoop@hadoop10 hadoop]$ hdfs dfs -rmdir /nosnap
# 如果删除的是空目录的话,会直接被删除掉,不会进入回收站

# [hadoop@hadoop10 hadoop]$ hdfs dfs -rm -f /111.txt
20/08/12 20:05:17 INFO fs.TrashPolicyDefault: Namenode trash configuration: Deletion interval = 1440 minutes, Emptier interval = 0 minutes.
Moved: 'hdfs://hadoop10:9000/111.txt' to trash at: hdfs://hadoop10:9000/user/hadoop/.Trash/Current
# 如果删除的不是空目录的话,则会进入回收站

4、查看回收站

#[hadoop@hadoop10 hadoop]$ hdfs dfs -ls /user/hadoop/.Trash/Current
Found 1 items
-rw-r--r--   2 hadoop supergroup         17 2020-08-11 10:56 /user/hadoop/.Trash/Current/111.txt

5、恢复回收站中的文件

#[hadoop@hadoop10 hadoop]$ hdfs dfs -mv /user/hadoop/.Trash/Current/111.txt /111.txt
## 其实就是将回收站中的文件移出来

6、永久删除文件(跳过回收站)

#[hadoop@hadoop10 hadoop]$ hdfs dfs -rm -skipTrash /111.txt
Deleted /111.txt

5、HDFS流程(重要)

(1)、HDFS写数据流程

1598777537646

(2)、HDFS读数据流程

 

posted @ 2020-09-05 10:52  Kerwin_chyl  阅读(201)  评论(0编辑  收藏  举报