哪个网站可以搭建网页,在线旅游网站,百度网站提交收录入口,番禺响应式网站建设文章目录 HDFS介绍HDFS体系HDFS的Shell介绍HDFS的常见Shell操作 HDFS案例实操Java操作HDFS配置环境 HDFS的回收站HDFS的安全模式实战#xff1a;定时上传数据至HDFSHDFS的高可用和高扩展HDFS的高可用(HA)HDFS的高扩展(Federation) HDFS介绍
HDFS是一个分布式的文件系统
假设… 文章目录 HDFS介绍HDFS体系HDFS的Shell介绍HDFS的常见Shell操作 HDFS案例实操Java操作HDFS配置环境 HDFS的回收站HDFS的安全模式实战定时上传数据至HDFSHDFS的高可用和高扩展HDFS的高可用(HA)HDFS的高扩展(Federation) HDFS介绍
HDFS是一个分布式的文件系统
假设让我们来设计一个分布式的文件系统我们该如何设计呢 这个统一由文件系统进行管理我们只需要和文件系统进行交互就可以了。 这样是不是就实现了分布式存储了这种方案在实际应用中可行吗 现在这种设计是我们去找一个中介公司这里的主节点就可以理解为一个中介公司 这里的从节点就可以理解为是房源中介公司会在每块房源都安排一个工作人员当我们找房子的时候 先联系中介公司中介公司会告诉我们哪里有房子并且把对应工作人员的信息告诉我们我们就可以直接去找对应的工作人员去租房子。这样对于中介公司而言就没什么压力了。这个就是HDFS这个分布式文件系统的设计思想。
HDFS的全称是Hadoop Distributed File System Hadoop的 分布式 文件 系统。它是一种允许文件通过网络在多台主机上分享的文件系统可以让多台机器上的多个用户分享文件和存储空间。其实分布式文件管理系统有很多。HDFS只是其中一种实现而已还有 GFS(谷歌的)、TFS(淘宝的)、S3(亚马逊的)。 为什么会有多种分布式文件系统呢这样不是重复造轮子吗 不是的因为不同的分布式文件系统的特点是不一样的HDFS是一种适合大文件存储的分布式文件系统不适合小文件存储什么叫小文件例如几KB几M的文件都可以认为是小文件。
HDFS体系
HDFS支持主从结构主节点称为 NameNode 支持多个从节点称为 支持多个HDFS中还包含一个 进程 HDFS的Shell介绍
针对HDFS我们可以在shell命令行下进行操作就类似于我们操作linux中的文件系统一样但是具体命 令的操作格式是有一些区别的格式如下 使用hadoop bin目录的hdfs命令后面指定dfs表示是操作分布式文件系统的这些属于固定格式。 如果在PATH中配置了hadoop的bin目录那么这里可以直接使用hdfs就可以了 这里的xxx是一个占位符具体我们想对hdfs做什么操作就可以在这里指定对应的命令了 大多数hdfs 的命令和对应的Linux命令类似
HDFS的常见Shell操作
直接在命令行中输入hdfs dfs可以查看dfs后面
-ls查询指定路径信息-put从本地上传文件-cat查看HDFS文件内容-get下载文件到本地-mkdir [-p]创建文件夹-rm [-r]删除文件/文件夹
HDFS案例实操
需求统计HDFS中文件的个数和每个文件的大小
1 我们先向HDFS中上传几个文件把hadoop目录中的几个txt文件上传上去
[rootbigdata01 hadoop-3.2.0]# hdfs dfs -put LICENSE.txt /
[rootbigdata01 hadoop-3.2.0]# hdfs dfs -put NOTICE.txt /
[rootbigdata01 hadoop-3.2.0]# hdfs dfs -put README.txt /统计根目录下文件的个数
[rootbigdata01 hadoop-3.2.0]# hdfs dfs -ls / |grep /| wc -l
3/LICENSE.txt 150569
/NOTICE.txt 22125
/README.txt 1361Java操作HDFS
shell中操作hdfs是比较常见的操作但是在工作中也会遇到一些需求是需要通过代码操作hdfs的
配置环境
1在这里我们使用apache-maven-3.0.5-bin.zip 当然了其它版本也可以没有什么本质的区别 把apache-maven-3.0.5-bin.zip解压到某一个目录下面在这里我解压到了D:\Program Files (x86)\apache-maven-3.0.5目录解压之后建议修改一下maven的配置文件把maven仓库的地址修改到其它盘例如D盘默认是在C盘的用户目录下修改D:\Program Files (x86)\apache-maven-3.0.5\conf下的settings.xml文件将localRepository标签从注释中移出来然后将值改为 D:.m2 效果如下
localRepositoryD:\.m2/localRepository 这样修改之后maven管理的依赖jar包都会保存到D:.m2目录下了。
2接下来需要配置maven的环境变量和windows中配置JAVA_HOME环境变量是一样的。 先在环境变量中配置M2_HOMED:\Program Files (x86)\apache-maven-3.0.5 然后在PATH环境变量中添加%M2_HOME%\bin即可 环境变量配置完毕以后打开cmd窗口输入mvn命令只要能正常执行就说明windows本地的maven环境配置好了。还需要在idea中指定我们本地的maven配置 点击idea左上角的File–Settings进入如下界面搜索maven把本地的maven添加到这里面即可。
3 创建一个maven项目 在这里我们需要引入hadoop-client依赖包到maven仓库中去找添加到pom.xml文件中
dependencygroupIdorg.apache.hadoop/groupIdartifactIdhadoop-client/artifactIdversion3.2.0/version
/dependency4 编写代码
package com.imooc.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FSDataOutputStream;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.IOUtils;
import java.io.FileInputStream;
import java.net.URI;
/**
* Java代码操作HDFS
* 文件操作上传文件、下载文件、删除文件
*/
public class HdfsOp {
public static void main(String[] args) throws Exception{
//创建一个配置对象Configuration conf new Configuration();
//指定HDFS的地址conf.set(fs.defaultFS,hdfs://bigdata01:9000);
//获取操作HDFS的对象FileSystem fileSystem FileSystem.get(conf);
//获取HDFS文件系统的输出流FSDataOutputStream fos fileSystem.create(new Path(/user.txt));
//获取本地文件的输入流FileInputStream fis new FileInputStream(D:\\user.txt);
//上传文件通过工具类把输入流拷贝到输出流里面实现本地文件上传到HDFSIOUtils.copyBytes(fis,fos,1024,true);}
}执行代码发现报错提示权限拒绝说明windows中的这个用户没有权限向HDFS中写入数据
解决办法有两个
第一种去掉hdfs的用户权限检验机制通过在hdfs-site.xml中配置dfs.permissions.enabled为false即可第二种把代码打包到linux中执行 在这里为了在本地测试方便我们先使用第一种方式
在主节点上操作
[rootbigdata01 hadoop-3.2.0]# vi etc/hadoop/hdfs-site.xmlconfigurationpropertynamedfs.replication/namevalue2/value/propertypropertynamedfs.namenode.secondary.http-address/namevaluebigdata01:50090/value/propertypropertynamedfs.permissions.enabled/namevaluefalse/value/property
/configuration同步到其他节点
[rootbigdata01 hadoop-3.2.0]# scp -rq etc/hadoop/hdfs-site.xml bigdata02:/d
[rootbigdata01 hadoop-3.2.0]# scp -rq etc/hadoop/hdfs-site.xml bigdata03:/d重新启动集群
[rootbigdata01 hadoop-3.2.0]# sbin/start-all.sh
Starting namenodes on [bigdata01]HDFS的回收站
HDFS会为每一个用户创建一个回收站目录/user/用户名/.Trash/每一个被用户在Shell命令行删除的文件/目录会进入到对应的回收站目录中在回收站中的数据都有一个生存周期也就是当回收站中的文件/目录在一段时间之内没有被用户恢复的话HDFS就会自动的把这个文件/目录彻底删除之后用户就永远也找不回这个文件/目录了。 默认情况下hdfs的回收站是没有开启的需要通过一个配置来开启在core-site.xml中添加如下配置value的单位是分钟1440分钟表示是一天的生存周期
propertynamefs.trash.interval/namevalue1440/value
/property注意如果删除的文件过大超过回收站大小的话会提示删除失败。需要指定参数 -skipTrash 指定这个参数表示删除的文件不会进回收站
HDFS的安全模式
平时操作HDFS的时候有时候可能会遇到这个问题特别是刚启动集群的时候去上传或者删除文 件会发现报错提示NameNode处于safe mode。
这个属于HDFS的安全模式因为在集群每次重新启动的时候HDFS都会检查集群中文件信息是否完整例如副本是否缺少之类的信息所以这个时间段内是不允许对集群有修改操作的如果遇到了这个情况可以稍微等一会等HDFS自检完毕就会自动退出安全模式。
通过hdfs命令也可以查看当前的状态
[rootbigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode get
Safe mode is ON如果想快速离开安全模式可以通过命令强制离开正常情况下建议等HDFS自检完毕自动退出
[rootbigdata01 hadoop-3.2.0]# hdfs dfsadmin -safemode leave
Safe mode is OFF实战定时上传数据至HDFS
需求分析 在实际工作中会有定时上传数据到HDFS的需求我们有一个web项目每天都会产生日志文件日志文件的格式为access_2020_01_01.log这种格式的每天产生一个我们需要每天凌晨将昨天生成的日志文件上传至HDFS上按天分目录存储HDFS上的目录格式为20200101
针对这个需求我们需要开发一个shell脚本方便定时调度执行
第一步我们需要获取到昨天日志文件的名称第二步在HDFS上面使用昨天的日期创建目录第三步将昨天的日志文件上传到刚创建的HDFS目录中第四步要考虑到脚本重跑补数据的情况第五步配置crontab任务
开始开发shell脚本脚本内容如下
[rootbigdata01 ~]# mkdir -p /data/shell
[rootbigdata01 ~]# cd /data/shell
[rootbigdata01 shell]# vi uploadLogData.sh
#!/bin/bash
# 获取昨天日期字符串
yesterday$1
if [ $yesterday ]
then
yesterdaydate %Y_%m_%d --date1 days ago
fi
# 拼接日志文件路径信息
logPath/data/log/access_${yesterday}.log
# 将日期字符串中的_去掉
hdfsPath/log/${yesterday//_/}
# 在hdfs上创建目录
hdfs dfs -mkdir -p ${hdfsPath}
# 将数据上传到hdfs的指定目录中
hdfs dfs -put ${logPath} ${hdfsPath}生成测试数据注意文件名称中的日期根据昨天的日期命名
[rootbigdata01 shell]# mkdir -p /data/log
[rootbigdata01 shell]# cd /data/log
[rootbigdata01 log]# vi access_2020_04_08.log
log1执行脚本
[rootbigdata01 log]# cd /data/shell/
[rootbigdata01 shell]# sh -x uploadLogData.shyesterday[ ]date %Y_%m_%d --date1 days agoyesterday2020_04_08logPath/data/log/access_2020_04_08.loghdfsPath/log/20200408hdfs dfs -mkdir -p /log/20200408hdfs dfs -put /data/log/access_2020_04_08.log /log/20200408
[rootbigdata01 shell]# hdfs dfs -ls /log/20200408
Found 1 items
-rw-r--r-- 2 root supergroup 15 2020-04-09 16:05 /log/20200408/acce注意如果想要指定日期上传数据可以通过在脚本后面传递参数实现
这样后期如果遇到某天的数据漏传了或者需要重新上传就可以通过手工指定日期实现上传操作在实际工作中这种操作是不可避免的所以我们在开发脚本的时候就直接考虑好补数据的情况别等需要用的时候了再去增加这个功能。
最后配置crontab定时任务每天凌晨1点执行
[rootbigdata01 shell]# vi /etc/crontab
0 1 * * * root sh /data/shell/uploadLogData.sh /data/shell/uploadLogData.logHDFS的高可用和高扩展
NameNode负责接收用户的操作请求所有的读写请求都会经过它如果它挂了怎么办
这个时候集群是不是就无法正常提供服务了是的那现在我们这个集群就太不稳定了因为NameNode只有一个是存在单点故障的咱们在现实生活中例如县长是有正的和副的这样就是为了解决当正县长遇到出差的时候副县长可以顶上去。
所以在HDFS的设计中NameNode也是可以支持多个的一个主的 多个备用的当主的挂掉了备用的可以顶上去这样就可以解决NameNode节点宕机导致的单点故障问题了也就实现了HDFS的高可用。 还有一个问题是前面我们说了NameNode节点的内存是有限的只能存储有限的文件个数那使用一个主NameNode多个备用的NameNode能解决这个问题吗 不能 一个主NameNode多个备用的NameNode的方案只能解决NameNode的单点故障问题无法解决单个NameNode内存不够用的问题那怎么办呢不用担心官方提供了Federation机制可以翻译为联邦它可以解决单节点内存不够用的情况具体实现思路我们稍后分析这个就是HDFS的高扩展
HDFS的高可用(HA) HDFS的HA指的是在一个集群中存在多个NameNode分别运行在独立的物理节点上。在任何时间点只有一个NameNode是处于Active状态其它的是处于Standby状态。 Active NameNode简写为Active NN负责所有的客户端的操作而Standby NameNode简写为Standby NN用来同步ActiveNameNode的状态信息以提供快速的故障恢复能力。 为了保证Active NN与Standby NN节点状态同步即元数据保持一致。除了DataNode需要向这些NameNode发送block位置信息外还构建了一组独立的守护进程”JournalNodes”简写为JN,用来同步Edits信息。当Active NN执行任何有关命名空间的修改它需要持久化到一半以上的JNs上。而Standby NN负责观察JNs的变化读取从Active NN发送过来的Edits信息并更新自己内部的命名空间。一旦Active NN遇到错误Standby NN需要保证从JNs中读出了全部的Edits然后切换成Active状态如果有多个Standby NN还会涉及到选主的操作选择一个切换为Active 状态。
需要注意一点为了保证Active NN与Standby NN节点状态同步即元数据保持一致
这里的元数据包含两块一个是静态的一个是动态的
静态的是fsimage和edits其实fsimage是由edits文件合并生成的所以只需要保证edits文件内容的一致性。这个就是需要保证多个NameNode中edits文件内容的事务性同步。这块的工作是由JournalNodes集群进行同步的动态数据是指block和DataNode节点的信息这个如何保证呢当DataNode启动的时候上报数据信息的时候需要向每个NameNode都上报一份。这样就可以保证多个NameNode的元数据信息都一样了当一个NameNode down掉以后立刻从Standby NN中选择一个进行接管没有影响因为每个NameNode 的元数据时刻都是同步的。
注意:使用HA的时候不能启动SecondaryNameNode会出错。 之前是SecondaryNameNode负责合并edits到fsimage文件 那么现在这个工作被standby NN负责了。
NameNode 切换可以自动切换也可以手工切换如果想要实现自动切换需要使用到zookeeper集群。 使用zookeeper集群自动切换的原理是这样的当多个NameNode 启动的时候会向zookeeper中注册一个临时节点当NameNode挂掉的时候这个临时节点也就消失了这属于zookeeper的特性这个时候zookeeper就会有一个watcher监视器监视到就知道这个节点down掉了然后会选择一个节点转为Active把down掉的节点转为Standby。注意下面的配置步骤建议大家有空闲时间了再来操作就行作为一个课外扩展因为在工作中这个配置是不需要我们做的我们只需要知道这种特性即可
HDFS的高扩展(Federation)
HDFS Federation可以解决单一命名空间存在的问题使用多个NameNode每个NameNode负责一个命令空间
这种设计可提供以下特性 1HDFS集群扩展性。多个NameNode分管一部分目录使得一个集群可以扩展到更多节点不再因内存的限制制约文件存储数目。 2性能更高效。多个NameNode管理不同的数据且同时对外提供服务将为用户提供更高的读写吞吐率。 3良好的隔离性。用户可根据需要将不同业务数据交由不同NameNode管理这样不同业务之间影响很小。 这里面用到了4个NameNode和6个DataNode NN-1、NN-2、NN-3、NN-4 DN-1、DN-2、DN-3、DN-4、DN-5、DN-6、 其中NN-1、和NN-3配置了HA提供了一个命令空间/share其实可理解为一个顶级目录 NN-2和NN-4配置了HA提供了一个命名空间/user 这样后期我们存储数据的时候就可以根据数据的业务类型来区分是存储到share目录下还是user目录下此时HDFS的存储能力就是/share和/user两个命名空间的总和了。
注意由于FederationHA需要的机器比较多大家本地的机器开不了那么多虚拟机所以暂时在这就不再提供对应的安装步骤了大家主要能理解它的原理就可以了在工作中也不需要我们去配置。