优秀是一种习惯
- 知识点01:回顾
- 知识点02:目标
- 知识点03:HDFS数据安全:元数据安全
- 知识点04:HDFS数据安全:SNN的功能
- 知识点05:HDFS数据安全:元数据查看
- 知识点06:HDFS Java API:应用场景及环境配置
- 知识点07:HDFS Java API:构建连接
- 知识点08:HDFS Java API:获取集群信息
- 知识点09:HDFS Java API:创建目录及列举
- 知识点10:HDFS Java API:上传及下载
- 知识点11:HDFS Java API:合并上传及权限
- 知识点12:HDFS辅助功能:Distcp
- 知识点13:HDFS辅助功能:Archive
- 知识点14:HDFS辅助功能:Snapshot
- 知识点15:Hadoop HA:架构的问题及解决方案
- 知识点16:Hadoop HA:HA实现问题分析
- 知识点17:Hadoop HA:HA环境搭建
- 知识点18:Hadoop HA:HA环境测试
- 附录一:HDFS Maven依赖
知识点01:回顾
-
Hadoop集群的部署一共有几种模式以及每种模式的应用场景是什么?
- 本地:测试代码逻辑、只有MapReduce,将整个代码运行在一个JVM进程中
- 伪分布式:只有一台机器分布式,所有进程都在一台机器上
- 完全分布式:多台机器构建分布式,不同进程运行在不同的节点上
-
Hadoop搭建中修改了哪些配置文件?
-
下载解压:tar
-
修改配置
-
xxx-env.sh:环境变量配置文件
- hadoop-env.sh:hadoop全局环境变量配置文件
- mapred-env.sh:MapReduce环境变量配置文件
- yarn-env.sh:YARN环境变量配置文件
- ||
- JAVA_HOME
-
xxx-site.xml:用户自定义属性配置文件
-
Hadoop配置管理
- 先加载所有*-default.xml:默认配置
- JAR包:自动加载
- 再加载所有*-site.xml:自定义配置
- Hadoop会自动从配置文件目录中加载
- 先加载所有*-default.xml:默认配置
-
core-site.xml:Hadoop全局属性配置文件
- fs.defaultFS:指定了HDFS的请求地址,代表了NameNode地址
-
hdfs-site.xml:HDFS属性配置文件
- dfs.replications:指定块的副本数
- dfs.block.size:指定块的大小
-
mapred-site.xml:MapReduce属性配置文件
- mapreduce.xxx.xxx
-
yarn-site.xml:YARN属性配置文件
- yarn.xxx.xx
-
-
slaves:从节点机器配置文件
-
填写每一台机器名称:DataNode和NodeManager地址
-
问题:为什么DataNode要和NodeManger
-
设计:本地优先计算
-
-
-
节点分发:scp
-
格式化:初始化
hdfs namenode -format
- 整个集群的唯一ID,初始元数据的生成
-
-
HDFS的功能是什么?什么场景下可以使用HDFS来实现存储?
- 功能:实现分布式存储,提供分布式读写
- Zookeeper:分布式协调服务
- Hbase:分区:Region
- Kafka:分区:Partition
- Redis:分区:Shard
- ElasticSearch:分区:Shard
- Kudu
- ……
- 场景
- 大数据数据文件
- 离线:读写速度要求不高
- 一次写入,多次读取
- 功能:实现分布式存储,提供分布式读写
-
HDFS如何实现分布式存储的以及HDFS如何保证数据存储安全?
- 分布式机制:分块机制
- 按照文件大小划分:每128M划分
- 数据安全机制:副本机制
- 每个块构建多个副本:默认每个块存储3份
- 分布式机制:分块机制
-
HDFS的架构及每个角色的功能是什么?
- 分布式主从架构
- NameNode:管理节点
- 管理所有DataNode状态:心跳机制
- 管理所有数据安全:汇报块机制
- 管理元数据
- 接客
- DataNode:存储节点
- 负责接收NameNode管理
- 负责处理客户端读写块的请求
- 读写
-
HDFS如何通过客户端实现数据的增删改查?
- 客户端:命令客户端:bin/hdfs
- 文件管理:dfs
- hdfs dfs -ls
- hdfs dfs -mkdir -p
- hdfs dfs -cat
- hdfs dfs -get
- hdfs dfs -put
- hdfs dfs -cp
- hdfs dfs -rm -r
- ……
- 集群管理:dfsadmin
- hdfs dfsadmin -safemode
- 强制退出:leave
知识点02:目标
- 元数据安全【重点】
- 存储
- 内存:NameNode维护的内存中
- 磁盘:fsimage文件,格式化的时候生成的文件,NameNode启动时加载到内存
- 问题:每次NameNode接受写、删除、修改的请求,只修改内存的元数据,磁盘中的元数据没有发生变化,下次NameNode启动再读取fsimage,之前的内存中元数据就丢失了?
- 问题:SecondaryNameNode进程的功能?
- 存储
- HDFS Java API客户端
- 工作中所有分布式读写都是通过Java API客户端来实现的
- 所有分布式计算的API中将HDFS的读写API封装了,只需要调用类的方法即可
- 重点
- 如何构建一个HDFS连接对象
- 如何删除以及如何创建目录
- 如何打开一个文件,如何读取一个文件
- HDFS其他辅助性功能
- 快照
- 集群迁移
- 归档
- Hadoop HA
- 怎么实现有两个NameNode和两个ResourceManager?
- 重点
- 实现原理
- 实现搭建以及测试
知识点03:HDFS数据安全:元数据安全
-
**引入:**HDFS的数据通过副本机制保证安全,那元数据怎么保证安全?
-
目标:掌握HDFS中元数据的安全机制
-
路径
- step1:HDFS元数据的产生
- step2:HDFS元数据的存储
- step3:HDFS元数据的安全
-
实施
-
HDFS元数据的产生
-
格式化的时候,产生磁盘元数据:fsimage文件
dfs.namenode.name.dir
-
-
-
HDFS元数据的存储
- 磁盘:fsimage文件,磁盘元数据,持久化元数据文件
- 问题:NameNode需要经常读写元数据,如果元数据在文件中,会导致读写性能非常差?
- 解决:每次NameNode启动时会读取fsiamge文件加载到内存中
- 内存:内存元数据,用于提供NameNode进行读写
-
HDFS元数据的安全
- 问题1:如果NN只修改内存元数据,NN一旦故障重启,内存元数据丢失?
- 解决:将元数据的变化写入edits文件,每次启动将edits与fsimage合并加载到内存中
-
小结
- HDFS的元数据存储位置?
- 磁盘:fsimage
- 内存:NameNode维护的内存元数据
- HDFS的元数据怎么保证安全?
- 将内存元数据的变化写入edits文件
- 每次NameNode启动将fsimage与edits文件合并,生成原来的元数据
- HDFS的元数据存储位置?
知识点04:HDFS数据安全:SNN的功能
-
引入:如果edits文件很大,其中包含了很多无用的数据,NameNode每次启动合并非常慢怎么办?
-
目标:掌握SecondaryNameNode的功能和作用
-
路径
- step1:Secondary的功能
- step2:辅助合并过程
-
实施
-
Secondary的功能
- 帮助NameNode阶段性的合并fsimage和edits文件,生成最新的fsimage文件
- 下一次NameNode启动,只要加载最新的fsimage文件和少量的edits文件的内容就可以快速的恢复元数据
-
辅助合并过程
-
edits文件的存储位置
dfs.namenode.edits.dir
-
-
- 实现过程
-
小结
- SecondaryNameNode的功能是什么?
- 阶段性将老的fsimage文件与老的edits文件进行合并,生成最新的fsimage元数据文件
- 下一次NameNode启动只要加载最新的fsimage与最新的edits文件即可
- SecondaryNameNode的功能是什么?
知识点05:HDFS数据安全:元数据查看
-
目标:了解如何查看HDFS中的fsimage与edits文件
-
路径
- step1:查看fsimage文件
- step2:查看edits文件
-
实施
-
查看fsimage文件
hdfs oiv -i hadoopDatas/namenodeDatas/current/fsimage_0000000000000000505 -p XML -o fsimage.xml
-
-
查看edits文件
hdfs oev -i hadoopDatas/nn/edits/current/edits_0000000000000000504-0000000000000000505 -p XML -o edits.xml
-
小结
- 了解即可
知识点06:HDFS Java API:应用场景及环境配置
-
目标:了解HDFS Java API的应用场景及实现本地环境配置
-
路径
- step1:HDFS Java API的应用场景
- step2:模块构建及依赖导入
- step3:本地开发环境配置
-
实施
-
HDFS Java API的应用场景
- 命令行客户端:管理类的操作
- JavaAPI客户端:读写类的操作
- HDFS:分布式计算的程序实现对HDFS数据的读写
- 分布式计算程序中封装了HDFS Java API
- 学习
- 构建连接:FileSystem、Configuration
- 删除和创建目录:delete方法、mkdir方法、Path类
- 读取文件和生成文件
- open方法:InputStream
- create方法:OutputStream
- HDFS:分布式计算的程序实现对HDFS数据的读写
-
模块构建及依赖导入
-
-
本地开发环境配置
-
因为Windows上没有安装Hadoop,在Windows的IDEA中运行Hadoop的代码,会报错
-
step1:将提供的Hadoop目录放入一个没有中文的路径下
-
step2:配置Hadoop的环境变量
-
添加一个环境变量
HADOOP_HOME=D:\hadoop\hadoop2.7.5
-
将Hadoop的bin目录添加到path中
path=之前的path后面加上;D:\hadoop\hadoop2.7.5\bin
-
-
- **step3**:重启IDEA,如果不行,就重启笔记本
- **step4**:如果step3执行完以后,运行程序代码依旧报错,请执行这一步
- 将hadoop的bin目录下hadoop.dll这个文件放入Windows的System32目录
- 重启笔记本,重新运行代码
- **step5**:如果step4执行完成以后,还不可以,直接联系老师
-
小结
- 按照配置实现即可
知识点07:HDFS Java API:构建连接
-
目标:使用HDFS Java API构建服务端文件系统连接
-
实施
/** * @ClassName HDFSJavaClientTest * @Description TODO 实现自定义开发JavaAPI操作HDFS * @Date 2021/4/24 11:08 * @Create By Frank */ public class HDFSJavaClientTest { //构建一个文件系统连接对象 FileSystem fs = null; //构建连接实例 @Before public void getFS() throws Exception { //构建Configuration对象:每个Hadoop都需要对象,用于管理当前程序的所有配置 Configuration conf = new Configuration(); //如何让conf读取HDFS地址 //方案一:将core-site.xml文件放入resources目录中 // conf.addResouce("core-site.xml"); //方案二:直接在conf中配置 conf.set("fs.defaultFS","hdfs://node1:8020"); //构建文件系统实例 fs = FileSystem.get(conf);//给定配置,必须指定服务端地址 // fs = FileSystem.get(new URI("hdfs://node1:8020"),conf);//给定配置以及服务端地址 // fs = FileSystem.get(new URI("hdfs://node1:8020"),conf,"root");//给定配置、服务端地址、用户身份 } //释放连接 @After public void closeFS() throws IOException { fs.close(); } }
-
小结
- 如何构建HDFS连接?
- 类
- FileSystem:文件系统的类
- Configuration:配置管理
- 方法
- FileSystem.get(Configuration):构建实例
- 类
- 如何构建HDFS连接?
知识点08:HDFS Java API:获取集群信息
-
目标:使用HDFS Java API获取集群信息
-
实施
//打印每个DN节点的状态信息 @Test public void printDNInfo() throws IOException { //集群管理,必须构建分布式文件系统对象 DistributedFileSystem dfs = (DistributedFileSystem) this.fs; //调用方法 DatanodeInfo[] dataNodeStats = dfs.getDataNodeStats(); //遍历输出 for (DatanodeInfo dataNodeStat : dataNodeStats) { System.out.println(dataNodeStat.getDatanodeReport()); } }
-
小结
- 如何获取集群信息?
- 必须构建DistributedFileSystem分布式文件系统对象
- 调用方法实现集群管理类的操作
- 如何获取集群信息?
知识点09:HDFS Java API:创建目录及列举
-
目标:使用HDFS Java API创建目录及列举文件
-
实施
//创建目录以及列举查看 @Test public void mkdirAndList() throws IOException { //构建创建的路径对象 Path path = new Path("/bigdata"); //判断目录是否存在 if(fs.exists(path)){ //如果存在就删除 fs.delete(path,true); } //创建 fs.mkdirs(path); //列举 // FileStatus[] fileStatuses = fs.listStatus(new Path("/")); // //输出每个文件或者目录的状态 // for (FileStatus fileStatus : fileStatuses) { // System.out.println(fileStatus.getPath().toString()); // } //只能列举文件 RemoteIterator<LocatedFileStatus> listFiles = fs.listFiles(new Path("/wordcount"), true); while(listFiles.hasNext()){ System.out.println(listFiles.next().getPath().toString()); } }
-
小结
- 如何创建目录?
- mkdir(path,boolean)
- delete(path,boolean)
- 如何列举文件?
- listStatus:可以列举目录或者文件
- listFiles:只能列举文件
- 如何创建目录?
知识点10:HDFS Java API:上传及下载
-
目标:使用Java API实现文件的上传与下载
-
实施
//实现文件的上传和下载 @Test public void uploadAndDownload() throws IOException { //上传:将本地文件放入HDFS // Path localPath = new Path("file:///F:\\hdfs\\hello.txt"); // Path hdfsPath = new Path("/bigdata/"); // fs.copyFromLocalFile(localPath,hdfsPath); //下载:将HDFS文件放入本地 Path localPath = new Path("file:///F:\\hdfs"); Path hdfsPath = new Path("/wordcount/input/wordcount.txt"); fs.copyToLocalFile(hdfsPath,localPath); }
-
小结
- 如何实现上传?
- copyFromLocalFile(localPath,hdfsPath)
- 如何实现下载?
- copyToLocalFIle(HDFSPATH,localPath)
- 如何实现上传?
知识点11:HDFS Java API:合并上传及权限
-
目标:使用Java API实现合并上传及使用root用户权限操作
-
实施
-
合并上传
//合并小文件实现上传 @Test public void mergeFile() throws IOException { //打开要合并的所有文件,构建输入流 LocalFileSystem local = FileSystem.getLocal(new Configuration()); //构建一个HDFS输出流,生成文件 FSDataOutputStream outputStream = fs.create(new Path("/bigdata/merge.txt")); //遍历文件 FileStatus[] fileStatuses = local.listStatus(new Path("F:\\hdfs\\merge")); for (FileStatus fileStatus : fileStatuses) { //打开每一个文件,构建一个输入流 FSDataInputStream inputStream = local.open(fileStatus.getPath()); //将输入流的数据放入输出流 IOUtils.copyBytes(inputStream,outputStream,4096); //关闭输入流 inputStream.close(); } //循环结束,关闭输出流 outputStream.close(); //关闭文件系统 local.close(); }
-
权限的配置
-
默认HDFS是开启了权限检查的
<property> <name>dfs.permissions</name> <value>false</value> </property>
-
如果开启了权限检查,怎么在代码测试的时候实现操作?
fs = FileSystem.get(new URI("hdfs://node1:8020"),conf,"root")
-
-
-
小结
- 如何实现合并上传?
- 打开:open(path) ==> 输入流
- 生成:create(Path) ==> 输出流
- 如何解决权限问题?
- 工作中通过统一的权限管理平台来管理所有工具的权限分配
- 在构建连接时可以指定使用什么用户的身份来操作HDFS
- 如何实现合并上传?
知识点12:HDFS辅助功能:Distcp
-
目标:了解HDFS集群中distcp的使用
- 什么是distcp?
- distcp怎么用?
-
路径
- step1:distcp的功能
- step2:distcp的用法
-
实施
-
distcp的功能
-
cp:用于实现单个文件系统内的拷贝
-
scp:用于实现两个同类的Linux系统间的拷贝
-
distcp:用于两个HDFS系统之间的数据拷贝
-
-
distcp的用法
hadoop distcp source target hadoop distcp hdfs://cluster1:8020/test hdfs://cluster2:8020/test
-
-
小结
-
什么是distcp?
- 功能:用于实现两个HDFS集群之间的数据拷贝
-
distcp怎么用?
hadoop distcp source target
-
知识点13:HDFS辅助功能:Archive
-
引入:HDFS不适合存储小文件,如何解决这个问题?
- 每个小文件占着一条元数据
-
目标:了解HDFS中的Archive的功能及使用?
- 什么是Archive?
-
路径
- step1:Archive的功能
- step2:Archive的使用
-
实施
-
Archive的功能
- 将多个小文件从逻辑上合并为一个整体文件,减少元数据存储
-
Archive的使用
-
创建归档文件:.har
hdfs dfs -mkdir -p /hartest/test1 hadoop archive -archiveName wc.har -p /wordcount /hartest/test1
-
查看归档文件
hdfs dfs -ls -R /hartest/test1/wc.har hdfs dfs -ls -R har:///hartest/test1/wc.har hdfs dfs -cat /hartest/test1/wc.har/part-0
-
-
-
小结
- 什么是Archive?
- 将多个小文件从逻辑上进行合并为一个文件,减少了HDFS元数据的存储
- 什么是Archive?
知识点14:HDFS辅助功能:Snapshot
-
目标:了解HDFS中Snapshot的功能
-
实施
-
功能:用于对某个目录构建快照,实现状态备份
-
创建测试目录
-
hdfs dfs -mkdir /test
hdfs dfs -put /export/data/wordcount.txt /test/
- 允许构建快照
hdfs dfsadmin -allowSnapshot /test
- 创建快照
hdfs dfs -createSnapshot /test
- 查看快照
/test/.snapshot/
- 对比、恢复快照
hdfs dfs -put cron.txt /test/
hdfs snapshotDiff /test . .snapshot/s20210424-145744.748
hdfs dfs -cp /test/.snapshot/s20210424-145744.748/* /test/
- 删除快照
hdfs dfs -deleteSnapshot /test s20210424-145744.748
- 禁止构建快照
hdfs dfsadmin -disallowSnapshot /test
-
小结
- 了解Snapshot的功能即可
知识点15:Hadoop HA:架构的问题及解决方案
-
引入
- Hadoop集群中HDFS的NameNode和YARN的ResourceManager都只有一个,如何解决单点故障问题?
-
HDFS如果存储的数据过多,负载过高怎么办?
-
目标:了解Hadoop中的架构的问题及解决方案
-
路径
- step1:Hadoop HA
- step2:Hadoop Federation
-
实施
-
Hadoop1与Hadoop2的区别
- 模块
- Hadoop1:HDFS、MapReduce
- Hadoop2:HDFS、MapReduce、YARN
- 架构
- Hadoop1:支持单个主节点,存在主节点单点故障问题
- Hadoop2:支持两种架构
- HA:高可用机制
- Federation:联盟机制
- 模块
-
Hadoop HA
- 高可用机制:启动两个主节点,一个为Active状态,另外一个为Standby
- 如果Active出现故障,Standby会切换为Active状态
- 特点:一个工作,一个不工作
- 高可用机制:启动两个主节点,一个为Active状态,另外一个为Standby
-
Hadoop Federation
- 联盟机制
-
- 启动两个NameNode,两个NameNode都工作
-
小结
-
主节点单点故障问题怎么解决?
- 高可用机制:启动多个主节点,Hadoop2中只支持启动两个,一个Active一个是Standby
- |
高可用容错机制
-
单个NameNode负载较高怎么解决?
-
联盟机制:启动多个主节点,多个主节点一起工作,分摊负载
-
|
负载均衡:load_balance
-
-
知识点16:Hadoop HA:HA实现问题分析
-
目标:掌握HA实现过程中的一些细节问题
-
实施
- 问题1:两个NameNode,谁是Active,谁是Standby?
- 解决:由Zookeeper来实现解决
- 实现
- 两个NameNode通过ZKFC向ZK注册一个临时节点
- 谁创建成功,谁就是Active,另外一个监听这个临时节点
- 如果这个临时节点消失,表示Active的NameNode故障,Standby要切换为Active
- 特殊的进程:ZKFC【Zookeeper Failover Controller】
- 监听NameNode状态,实现状态指令的发布
- 辅助NameNode向ZK中进行注册,创建临时节点或者监听临时节点
- 每一个NameNode会有一个ZKFC进程
- 问题2:两个NameNode,DataNode会向哪个NameNode发送心跳和汇报块?
- 解决:每个DataNode会向所有的NameNode注册,发送心跳和汇报块
- 问题3:两个NameNode,其中一个是Active的,客户端只能将请求给Active的NameNode,客户端如何知道谁是Active的?
- 解决:挨个请求,只有Active能接受对应的请求
- 问题4:如何保证两个NameNode的内存元数据是一致的,只有这样,Active宕机或者故障,Standby才能完整的接替原来的Active?
- 目标:要实现共享edits文件
- 实现:JournalNode集群:设计类似于ZK,公平节点,属于Hadoop内部的一个组件,可以存储大数据文件
- Active的NameNode将edits写入JournalNode
- Standby的NameNode从JournalNode中读取Edits
- 问题1:两个NameNode,谁是Active,谁是Standby?
-
小结
- Zookeeper的功能是什么?
- 辅助选举
- ZKFC的功能是什么?
- 监听NameNode的状态
- 辅助NameNode向Zookeeper创建节点和监听节点
- JournalNode的功能是什么?
- 实现edits文件共享,保证元数据一致
- Zookeeper的功能是什么?
知识点17:Hadoop HA:HA环境搭建
-
目标:实现HA环境的配置搭建
-
实施
-
step1:拍摄三台虚拟机的快照
-
关闭所有进程
sbin/stop-dfs.sh sbin/stop-yarn.sh
-
关机
- 不关机拍摄的快照比较大,占磁盘空间
-
拍摄三台机器的快照【用于恢复当前状态,后续学习过程中不用HA】
-
启动三台机器
-
节点规划
进程/机器 node1 node2 node3 NameNode *【Active】 *【Standby】 ZKFC * * JN * * * DataNode * * * ResourcecManager *【StandBy】 *【Active】 NodeManager * * *
-
-
step2:修改配置文件
-
删除三台机器原来的临时目录,重新创建,三台机器都要执行
cd /export/server/hadoop-2.7.5/ rm -rf hadoopDatas/ #创建hadoop的临时存储目录:存储数据块、fsimage等 mkdir datas #用于journal进程存储edits文件的目录 mkdir journalnode
-
修改第一台机器的配置
-
core-site.xml
<property> <name>fs.defaultFS</name> <value>hdfs://mycluster</value> </property> <property> <name>hadoop.tmp.dir</name> <value>/export/server/hadoop-2.7.5/datas</value> </property> <property> <name>fs.trash.interval</name> <value>10080</value> </property> <property> <name>ha.zookeeper.quorum</name> <value>node1:2181,node2:2181,node3:2181</value> </property>
- fs.defaultFS:指定HDFS地址
-
-
ha.zookeeper.quorum:指定zk的地址
-
-
hdfs-site.xml
```xml <property> <name>dfs.permissions.enabled</name> <value>false</value> </property> <property> <name>dfs.nameservices</name> <value>mycluster</value> </property> <property> <name>dfs.ha.namenodes.mycluster</name> <value>nn1,nn2</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn1</name> <value>node1:8020</value> </property> <property> <name>dfs.namenode.rpc-address.mycluster.nn2</name> <value>node2:8020</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn1</name> <value>node1:50070</value> </property> <property> <name>dfs.namenode.http-address.mycluster.nn2</name> <value>node2:50070</value> </property> <property> <name>dfs.namenode.shared.edits.dir</name> <value>qjournal://node1:8485;node2:8485;node3:8485/mycluster</value> </property> <property> <name>dfs.journalnode.edits.dir</name> <value>/export/server/hadoop-2.7.5/journalnode</value> </property> <property> <name>dfs.client.failover.proxy.provider.mycluster</name> <value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value> </property> <property> <name>dfs.ha.fencing.methods</name> <value>sshfence</value> </property> <property> <name>dfs.ha.fencing.ssh.private-key-files</name> <value>/root/.ssh/id_rsa</value> </property> <property> <name>dfs.ha.automatic-failover.enabled</name> <value>true</value> </property>
- dfs.nameservices:将两个NN从逻辑上合并为一个整体的名称 - 一定要对应core-site中fs.defaultFS的配置 - dfs.ha.namenodes.mycluster:指定逻辑名称中有几个NN,每个NN的名称是什么 - dfs.namenode.rpc-address.mycluster.nn1/nn2:配置两个NameNode具体的RPC和HTTP协议地址 - dfs.namenode.shared.edits.dir:JournalNode的地址 - dfs.journalnode.edits.dir:edits文件的存储位置 - dfs.client.failover.proxy.provider.mycluster:客户端请求服务端的方式 - dfs.ha.fencing.methods:隔离机制,解决脑裂问题的 - dfs.ha.automatic-failover.enabled:自动切换 * **yarn-site.xml** ```xml <property> <name>yarn.resourcemanager.ha.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.cluster-id</name> <value>cluster1</value> </property> <property> <name>yarn.resourcemanager.ha.rm-ids</name> <value>rm1,rm2</value> </property> <property> <name>yarn.resourcemanager.ha.id</name> <value>rm1</value> </property> <property> <name>yarn.resourcemanager.hostname.rm1</name> <value>node3</value> </property> <property> <name>yarn.resourcemanager.hostname.rm2</name> <value>node2</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm1</name> <value>node3:8088</value> </property> <property> <name>yarn.resourcemanager.webapp.address.rm2</name> <value>node2:8088</value> </property> <property> <name>yarn.resourcemanager.zk-address</name> <value>node1:2181,node2:2181,node3:2181</value> </property> <property> <name>yarn.resourcemanager.recovery.enabled</name> <value>true</value> </property> <property> <name>yarn.resourcemanager.store.class</name> <value>org.apache.hadoop.yarn.server.resourcemanager.recovery.ZKRMStateStore</value> </property> <property> <name>yarn.nodemanager.aux-services</name> <value>mapreduce_shuffle</value> </property>
3、分发并修改
-
分发给第二台和第三台机器
cd /export/server/hadoop-2.7.5/etc/hadoop/ scp core-site.xml hdfs-site.xml yarn-site.xml node2:$PWD scp core-site.xml hdfs-site.xml yarn-site.xml node3:$PWD
-
修改第一台机器的yarn-site.xml
-
编辑yarn-site.xml
cd /export/server/hadoop-2.7.5/etc/hadoop/ vim yarn-site.xml
-
删除以下内容
<!--在node3上配置rm1,在node2上配置rm2--> <!--注意:这个在YARN的另一个机器上一定要修改,非RM的其他机器上不配置此项--> <property> <name>yarn.resourcemanager.ha.id</name> <value>rm1</value> </property>
-
-
修改第二台机器的yarn-site.xml
-
编辑yarn-site.xml
cd /export/server/hadoop-2.7.5/etc/hadoop/ vim yarn-site.xml
-
更改以下内容:将rm1修改为rm2
<!--在node3上配置rm1,在node2上配置rm2--> <!--注意:这个在YARN的另一个机器上一定要修改,非RM的其他机器上不配置此项--> <property> <name>yarn.resourcemanager.ha.id</name> <value>rm2</value> </property>
-
-
三台机器安装 psmisc
yum install psmisc -y
4、启动
-
启动zookeeper
/export/server/zookeeper-3.4.6/bin/start-zk-all.sh
-
第一次启动需要进行格式化:以后不需要执行
-
启动三台机器的journalnode,三台机器都要执行
cd /export/server/hadoop-2.7.5/ sbin/hadoop-daemon.sh start journalnode
-
第一台机器的NameNode进行格式化
bin/hdfs namenode -format
-
第一台机器同步元数据到第二台机器
scp -r datas node2:$PWD
-
-
第一台机器关联zookeeper,进行初始化
bin/hdfs zkfc -formatZK
-
三台机器关闭journalnode
sbin/hadoop-daemon.sh stop journalnode
-
第一台机器启动HDFS
start-dfs.sh #会自动启动所有HDFS的进程
-
第三台机器启动YARN
start-yarn.sh #只启动当前机器的RM和所有的NM
-
第二台机器启动ResourceManager
yarn-daemon.sh start resourcemanager
-
小结
- 按照配置实现即可
知识点18:Hadoop HA:HA环境测试
-
目标:实现HA环境的测试
-
实施
-
查看Web监控
-
node1:50070
-
node2:50070
-
-
- node3:8088
- node2:8088
-
测试HDFS的HA
-
关闭第一台NameNode
sbin/hadoop-daemon.sh stop namenode
-
查看第二台NameNode的状态
-
‘
- 重新启动第一台的NameNode
```
sbin/hadoop-daemon.sh start namenode
```
- 查看第一台NameNode的状态
-
测试YARN的HA
-
关闭第三台ResourceManager
yarn-daemon.sh stop resourcemanager
-
查看第二台ResourceManager的状态
-
重新启动第三台ResourceManager
yarn-daemon.sh start resourcemanager
-
查看第三台ResourceManager的状态
-
-
手动切换Active
hdfs haadmin -getServiceState nn1 hdfs haadmin -getServiceState nn2 hdfs haadmin -failover nn2 nn1 语法:hdfs haadmin -failover active standby
-
小结
- 实现测试即可
- 注意:如果要实现客户端访问HDFS 的HA模式,怎么访问?
- 必须包含core-site.xml和hdfs-site.xml中所有属性
- 数据采集:将数据写入HDFS
- 数据采集工具必须包含这两个配置文件
- 数据计算:读取HDFS数据
- 数据计算的程序的环境变量中,必须包含这两个配置文件
附录一:HDFS Maven依赖
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>4.13</version>
</dependency>
</dependencies>