1.为什么需要分布式存储
-
数据量太大,单机存储能力有上限,需要靠数量来解决问题
-
数量的提升带来的是网络传输、磁盘读写、CPU、内存等各方面的综合提升。 分布式组合在一起可以达到1+1>2的效果
2.分布式的基础架构分析
1.分布式系统常见的组织形式?
-
去中心化模式:没有明确中心,大家协调工作
-
中心化模式:有明确的中心,基于中心节点分配工作
2. 什么是主从模式?
主从模式(Master-Slaves)就是中心化模式,表示有一个主节点来作为管理者,管理协调下属一批从节点工作。
3.Hadoop是哪种模式?
主从模式(中心化模式)的架构
3.HDFS的基础架构
1.什么是HDFS?
-
HDFS全称:Hadoop Distributed File System
-
是Hadoop三大组件(HDFS、MapReduce、YARN)之一
-
可在多台服务器上构建集群,提供分布式数据存储能力
2. HDFS中的架构角色有哪些?
-
NameNode:主角色,管理HDFS集群和DataNode角色
-
DataNode:从角色,负责数据的存储
-
SecondaryNameNode:辅助角色,协助NameNode整理元数据
3. HDFS的基础架构
4.HDFS集群环境部署(VMware虚拟机中部署)
1.Hadoop安装包下载(版本3.3.4,没找到只好用3.4版本)
【官方网址】Apache Hadoop
【清华镜像网址】Index of /apache/hadoop/common/hadoop-3.4.0 (tsinghua.edu.cn)
2.集群规划
在前置准备章节,我们准备了基于VMware的三台虚拟机,其硬件配置如下。
3.上传安装包并解压
注意:请确认已经完成前置准备中的服务器创建、固定IP、防火墙关闭、Hadoop用户创建、SSH免密、JDK部署等操作
以下操作都在node1完成,以root身份登录
-
上传Hadoop安装包到node1节点中
直接将文档拖拽到FinalShell或者使用rz命令
-
解压缩安装包到/export/server/中
tar -zxvf hadoop-3.4.0.tar.gz -C /export/server/
-
构建软链接
ln -s /export/server/hadoop-3.4.0 hadoop
-
进入hadoop安装包内
cd hadoop
4.Hadoop安装包目录结构
各个文件夹含义如下
-
bin,存放Hadoop的各类程序(命令)
-
etc,存放Hadoop的配置文件
-
include,C语言的一些头文件
-
lib,存放Linux系统的动态链接库(.so文件)
-
libexec,存放配置Hadoop系统的脚本文件(.sh和.cmd)
-
licenses-binary,存放许可证文件
-
sbin,管理员程序(super bin)
-
share,存放二进制源码(Java jar包)
5.修改配置文件,应用自定义设置
配置HDFS集群,我们主要涉及到如下文件的修改:
-
workers: 配置从节点(DataNode)有哪些
-
hadoop-env.sh: 配置Hadoop的相关环境变量
-
core-site.xml: Hadoop核心配置文件
-
hdfs-site.xml: HDFS核心配置文件
这些文件均存在与$HADOOP_HOME/etc/hadoop
文件夹中。
ps:$HADOOP_HOME
是后续我们要设置的环境变量,其指代Hadoop安装文件夹即/export/server/hadoop
workers中的localhost删去
export JAVA_HOME=/export/server/jdk export HADOOP_HOME=/export/server/hadoop export HADOOP_CONF_DIR=$HADOOP_HOME/etc/hadoop export HADOOP_LOG_DIR=$HADOOP_HOME/logs
<property> <name>fs.defaultFS</name> <value>hdfs://node1:8020</value> </property> <property> <name>io.file.buffer.size</name> <value>131072</value> </property>
-
hdfs://node1:8020
为整个HDFS内部的通讯地址,应用协议为hdfs://(Hadoop内置协议) -
表明DataNode将和node1的8020端口通讯,node1是NameNode所在机器
-
此配置固定了node1必须启动NameNode进程
-
配置hdfs-site.xml文件
<configuration> <property> <name>dfs.datanode.data.dir.perm</name> <value>700</value> </property> <property> <name>dfs.namenode.name.dir</name> <value>/data/nn</value> </property> <property> <name>dfs.namenode.hosts</name> <value>node1,node2,node3</value> </property> <property> <name>dfs.blocksize</name> <value>268435456</value> </property> <property> <name>dfs.namenode.handler.count</name> <value>100</value> </property> <property> <name>dfs.datanode.data.dir</name> <value>/data/dn</value> </property> </configuration>
6.准备数据目录
7.分发Hadoop文件夹
目前,已经基本完成Hadoop的配置操作,可以从node1将hadoop安装文件夹远程复制到node2、node3
-
分发
# 在node1执行如下命令 cd /export/server scp -r hadoop-3.4.0 node2:`pwd`/ scp -r hadoop-3.4.0 node3:`pwd`/
-
在node2执行,为hadoop配置软链接
# 在node2执行如下命令 ln -s /export/server/hadoop-3.4.0 /export/server/hadoop
-
在node3执行,为hadoop配置软链接
# 在node3执行如下命令 ln -s /export/server/hadoop-3.4.0 /export/server/hadoop
8.配置环境变量
为了方便我们操作Hadoop,可以将Hadoop的一些脚本、程序配置到PATH中,方便后续使用。
在Hadoop文件夹中的bin、sbin两个文件夹内有许多的脚本和程序,现在来配置一下环境变量
-
vim /etc/profile
# 在/etc/profile文件底部追加如下内容 export HADOOP_HOME=/export/server/hadoop export PATH=$PATH:$HADOOP_HOME/bin:$HADOOP_HOME/sbin
运行:source /etc/profile
-
在node2和node3配置同样的环境变量
9.授权为hadoop用户
hadoop部署的准备工作基本完成
为了确保安全,hadoop系统不以root用户启动,我们以普通用户hadoop来启动整个Hadoop服务
所以,现在需要对文件权限进行授权。
ps:请确保已经提前创建好了hadoop用户(前置准备章节中有讲述),并配置好了hadoop用户之间的免密登录
以root身份,在node1、node2、node3三台服务器上均执行如下命令
# 以root身份,在三台服务器上均执行 chown -R hadoop:hadoop /data chown -R hadoop:hadoop /export
10.格式化整个文件系统
前期准备全部完成,现在对整个文件系统执行初始化
-
格式化namenode
# 确保以hadoop用户执行 su - hadoop # 格式化namenode hadoop namenode -format
-
启动
# 一键启动hdfs集群 start-dfs.sh # 一键关闭hdfs集群 stop-dfs.sh # 如果遇到命令未找到的错误,表明环境变量未配置好,可以以绝对路径执行 /export/server/hadoop/sbin/start-dfs.sh /export/server/hadoop/sbin/stop-dfs.sh
jps查看当前运行的java进程有哪些
11.查看HDFS WEBUI
启动完成后,可以在浏览器打开:
http://node1公网IP:9870,即可查看到hdfs文件系统的管理网页。
5.HDFS的Shell操作
1.进程启停管理
一键启停脚本
Hadoop HDFS组件内置了HDFS集群的一键启停脚本。
-
$HADOOP_HOME/sbin/start-dfs.sh,一键启动HDFS集群
执行原理:
-
在执行此脚本的机器上,启动SecondaryNameNode
-
读取core-site.xml内容(fs.defaultFS项),确认NameNode所在机器,启动NameNode
-
读取workers内容,确认DataNode所在机器,启动全部DataNode
-
$HADOOP_HOME/sbin/stop-dfs.sh,一键关闭HDFS集群
执行原理:
-
在执行此脚本的机器上,关闭SecondaryNameNode
-
读取core-site.xml内容(fs.defaultFS项),确认NameNode所在机器,关闭NameNode
-
读取workers内容,确认DataNode所在机器,关闭全部NameNode
单进程启停
除了一键启停外,也可以单独控制进程的启停。
-
$HADOOP_HOME/sbin/hadoop-daemon.sh,此脚本可以单独控制所在机器的进程的启停
用法:hadoop-daemon.sh (start|status|stop) (namenode|secondarynamenode|datanode)
-
$HADOOP_HOME/bin/hdfs,此程序也可以用以单独控制所在机器的进程的启停
用法:hdfs --daemon (start|status|stop) (namenode|secondarynamenode|datanode)
2.文件系统操作命令
HDFS文件系统基本信息
创建文件夹
-
hadoop fs -mkdir [-p] <path> ...
-
hdfs dfs -mkdir [-p] <path> ...
path 为待创建的目录
-p选项的行为与Linux mkdir -p一致,它会沿着路径创建父目录。
hadoop fs -mkdir -p /itcast/bigdata hdfs fs -mkdir -p /itheima/hadoop
在hadoop中创建,所以本地看不到
查看指定目录下内容
-
hadoop fs -ls [-h] [-R] [<path> ...]
-
hdfs dfs -ls [-h] [-R] [<path> ...]
path 指定目录路径
-h 人性化显示文件size -R 递归查看指定目录及其子目录
上传文件到HDFS指定目录下
-
hadoop fs -put [-f] [-p] <localsrc> ... <dst>
-
hdfs dfs -put [-f] [-p] <localsrc> ... <dst>
-f 覆盖目标文件(已存在下)
-p 保留访问和修改时间,所有权和权限。 localsrc 本地文件系统(客户端所在机器) dst 目标文件系统(HDFS)
hdfs dfs -put ./words.txt / hdfs dfs -put file:///etc/profile hdfs://node1:8020/
在hadoop下创建一个文件test.txt输入一些内容
查看HDFS文件内容
-
hadoop fs -cat <src> ...
-
hdfs dfs -cat <src> ...
读取指定文件全部内容,显示在标准输出控制台。
读取大文件可以使用管道符配合more
-
hadoop fs -cat <src> | more
-
hdfs dfs -cat <src> | more
hdfs dfs -cat /test.txt hdfs dfs -cat /itcast/profile
下载HDFS文件
-
hadoop fs -get [-f] [-p] <src> ... <localdst>
-
hdfs dfs -get [-f] [-p] <src> ... <localdst>
下载文件到本地文件系统指定目录,localdst必须是目录
-f 覆盖目标文件(已存在下)
-p 保留访问和修改时间,所有权和权限。
拷贝HDFS文件
-
hadoop fs -cp [-f] <src> ... <dst>
-
hdfs dfs -cp [-f] <src> ... <dst>
-f 覆盖目标文件(已存在下)
hdfs dfs -cp /test.txt /home/ hdfs dfs -cp /test.txt /home/abc.txt
追加数据到HDFS文件中
-
hadoop fs -appendToFile <localsrc> ... <dst>
-
hdfs dfs -appendToFile <localsrc> ... <dst>
将所有给定本地文件的内容追加到给定dst文件。
dst如果文件不存在,将创建该文件。
如果<localSrc>为-,则输入为从标准输入中读取。
HDFS数据移动操作
-
hadoop fs -mv <src> ... <dst>
-
hdfs dfs -mv <src> ... <dst>
移动文件到指定文件夹下
可以使用该命令移动数据,重命名文件的名称
当前test.txt文件的路径
将test.txt移动到bigdata中
hdfs dfs -mv /itcast/test.txt /itcast/bigdata
HDFS数据删除操作
-
hadoop fs -rm -r [-skipTrash] URI [URI ...]
-
hdfs dfs -rm -r [-skipTrash] URI [URI ...]
删除指定路径的文件或文件夹
-skipTrash 跳过回收站,直接删除
回收站功能默认关闭,如果要开启需要在core-site.xml内配置:
vim /export/server/hadoop/etc/hadoop/core-site.xml
<property> <name>fs.trash.interval</name> <value>1440</value> </property> <property> <name>fs.trash.checkpoint.interval</name> <value>120</value> </property>
无需重启集群,在哪个机器配置的,在哪个机器执行命令就生效。
回收站默认位置在:/user/用户名(hadoop)/.Trash
-
删除test.txt
-
从回收站移动回来
HDFS shell其它命令
-
命令官方指导文档
Apache Hadoop 3.3.4 – Overview
-
提示
常见的操作自己最好能够记住,其他操作可以根据需要查询文档使用。
命令属于多用多会,孰能生巧,不用就忘。
HDFS WEB浏览
除了使用命令操作HDFS文件系统外,在HDFS的WEB UI上也可以查看HDFS文件系统的内容。
使用WEB浏览操作文件系统,一般会遇到权限问题
这是因为WEB浏览器中是以匿名用户(dr.who)登陆的,其只有只读权限,多数操作是做不了的。
如果需要以特权用户在浏览器中进行操作,需要配置如下内容到core-site.xml并重启集群
<property> <name>hadoop.http.staticuser.user</name> <value>hadoop</value> </property>
但是,不推荐这样做
-
HDFS WEBUI,只读权限挺好的,简单浏览即可
-
如果给与高权限,会有很大的安全问题,造成数据泄露或丢失
3.HDFS权限
-
移动test.txt文件,方便操作(不移动也行)
-
修改test.txt文件所属权限,赋权给root用户
hdfs dfs -chown root:supergroup /test.txt
-
修改文件权限
hdfs dfs -chmod 777 /test.txt
4.HDFS客户端 - Jetbrians产品插件
Big Data Tools插件
在Jetbrains的产品中,均可以安装插件,其中:Big Data Tools插件可以帮助我们方便的操作HDFS,比如
-
IntelliJ IDEA(Java IDE)
-
PyCharm(Python IDE)
-
DataGrip(SQL IDE)
均可以支持Bigdata Tool插件。
在设置->Plugins(插件)-> Marketplace(市场),搜索Big Data Tools,点击Install安装即可
配置Windows
需要对Windows系统做一些基础设置,配合插件使用
-
解压Hadoop安装包到Windows系统,如解压到:H:\BigDataDev\hadoop-3.4.0
-
设置$HADOOP_HOME环境变量指向:H:\BigDataDev\hadoop-3.4.0
下载
-
hadoop.dll(https://github.com/steveloughran/winutils/blob/master/hadoop-3.0.0/bin/hadoop.dll)
-
winutils.exe(https://github.com/steveloughran/winutils/blob/master/hadoop-3.0.0/bin/winutils.exe)
-
将hadoop.dll和winutils.exe放入$HADOOP_HOME/bin中
配置Big Data Tools插件
使用Big Data Tools插件
6.HDFS的存储原理
存储原理
分块(256MB)、备份(3)存储
fsck命令
1.了解如何配置HDFS数据块的副本数量
2.掌握fsck命令查看文件系统状态及验证文件的数据副本
HDFS副本块数量的配置
在前面我们了解了HDFS文件系统的数据安全,是依靠多个副本来确保的。
如何设置默认文件上传到HDFS中拥有的副本数量呢?可以在hdfs-site.xml中配置如下属性:
<property> <name>dfs.replication</name> <value>3</value> </property>
这个属性默认是3,一般情况下,我们无需主动配置(除非需要设置非3的数值)
如果需要自定义这个属性,请修改每一台服务器的hdfs-site.xml文件,并设置此属性。
-
除了配置文件外,我们还可以在上传文件的时候,临时决定被上传文件以多少个副本存储。
hadoop fs -D dfs.replication=2 -put test.txt /tmp/
如上命令,就可以在上传test.txt的时候,临时设置其副本数为2
-
对于已经存在HDFS的文件,修改dfs.replication属性不会生效,如果要修改已存在文件可以通过命令
hadoop fs -setrep [-R] 2 path
如上命令,指定path的内容将会被修改为2个副本存储。
-R选项可选,使用-R表示对子目录也生效。
fsck命令检查文件的副本数
同时,我们可以使用hdfs提供的fsck命令来检查文件的副本数
hdfs fsck path [-files [-blocks [-locations]]]
fsck可以检查指定路径是否正常
-
-files可以列出路径内的文件状态
-
-files -blocks 输出文件块报告(有几个块,多少副本)
-
-files -blocks -locations 输出每一个block的详情
block配置
可以看到通过fsck命令我们验证了:
-
文件有多个副本
-
文件被分成多个块存储在hdfs
对于块(block),hdfs默认设置为256MB一个,也就是1GB文件会被划分为4个block存储。
块大小可以通过参数:
<property> <name>dfs.blocksize</name> <value>268435456</value> <description>设置HDFS块大小,单位是b</description> </property>
如上,设置为256MB
NameNode元数据
1.掌握NameNode是如何管理Block块的
edits文件
edits记录每一次HDFS的操作逐渐变得越来越大
所以,会存在多个edits文件确保不会有超大edits的存在保证检索性能
问题在于,当用户想要查看某文件内容
如:/tmp/data/test.txt
就需要在全部的edits中搜索(还需要按顺序从头到尾,避免后期改名或删除)效率非常低
需要合并edits文件,得到最终的结果
fsimage文件
将全部的edits文件,合并为最终结果,即可得到一个FSImage文件
NameNode元数据管理维护
NameNode基于edits和FSImage的配合,完成整个文件系统文件的管理。
-
每次对HDFS的操作,均被edits文件记录
-
edits达到大小上线后,开启新的edits记录
-
定期进行edits的合并操作
-
如当前没有fsimage文件, 将全部edits合并为第一个fsimage
-
如当前已存在fsimage文件,将全部edits和已存在的fsimage进行合并,形成新的fsimage
-
重复123流程
元数据合并控制参数
对于元数据的合并,是一个定时过程,基于:
-
dfs.namenode.checkpoint.period,默认3600(秒)即1小时
-
dfs.namenode.checkpoint.txns,默认1000000,即100W次事务
只要有一个达到条件就执行。
检查是否达到条件,默认60秒检查一次,基于:
-
dfs.namenode.checkpoint.check.period,默认60(秒),来决定
SecondaryNameNode的作用
HDFS数据的读写流程
数据写入流程
-
客户端向NameNode发起请求
-
NameNode审核权限、剩余空间后,满足条件允许写入,并告知客户端写入的DataNode地址
-
客户端向指定的DataNode发送数据包
-
被写入数据的DataNode同时完成数据副本的复制工作,将其接收的数据分发给其它DataNode
-
如上图,DataNode1复制给DataNode2,然后基于DataNode2复制给Datanode3和DataNode4
-
写入完成客户端通知NameNode,NameNode做元数据记录工作
关键信息点:
-
NameNode不负责数据写入,只负责元数据记录和权限审批
-
客户端直接向1台DataNode写数据,这个DataNode一般是离客户端最近(网络距离)的那一个
-
数据块副本的复制工作,由DataNode之间自行完成(构建一个PipLine,按顺序复制分发,如图1给2, 2给3和4)
数据读取流程
1、客户端向NameNode申请读取某文件
2、 NameNode判断客户端权限等细节后,允许读取,并返回此文件的block列表
3、客户端拿到block列表后自行寻找DataNode读取即可
关键点:
1、数据同样不通过NameNode提供
2、NameNode提供的block列表,会基于网络距离计算尽量提供离客户端最近的
这是因为1个block有3份,会尽量找离客户端最近的那一份让其读取