Hadoop——HDFS 3.3.4
星期一, 3月 3, 2025 | 34分钟阅读

关于 Hadoop——HDFS3.3.4 的学习。
大数据思维
分而治之
所谓“分而治之”,就是把一个复杂的算法问题按一定的“分解”方法分为等价的规模较小的若干部分,然后逐个分别找出各部分的解,再把各部分的解组成整个问题的解。这种朴素的思想来源于人们生活与工作的实践经验,如下图。
这里我们主要从海量数据处理作为切入点进行讲解,所谓海量数据处理,其实很简单,海量,海量,何谓海量,就是数据量太大,所以导致要么是无法在较短时间内迅速解决,要么是数据太大,导致无法一次性装入内存。
普通的计算都是基于内存去完成的,前提就是内存能够完整的容纳所有数据。而大数据领域面对的都是TB级别起步的数据量。这就考验了现代计算机的处理能力,于是聪明的人们提出了分布式计算的概念,利用在一个网络中的所有计算机进行并行计算,大大增加了处理效率。这就是分而治之的思想。
查重
接下来我们讨论一些实际问题。在单机且可用内存只有1G的情况下,如何在1T的文件中,找到重复的两行?
最笨的办法就是:每一行都与文件中后面的所有行进行比较。这种方式的时间复杂度很高为0(n2)。有没有更好的解决方案呢?
这个时候我们还有一种思路就是将数据放到HashSet中,运用Hash表不能加入重复的Key的特征来实现需求,可是我们题目的条件是内存不能放下全部足量的数据,因此这个方案不可行。
但是我们可以借鉴哈希表的思想,哈希表是将数据根据HashCode算出对应的Hash值,然后根据Hash值找到序列下标,再将数据存放到对应下标的位置。如果有哈希冲突,一般采用拉链法来解决,看到这里我们是否也能运用哈希表的原理来实现上述需求呢?下面我们来推演一下。
- 读取文件的每一行,然后模仿哈希表算出每一行的HashCode;
- 根据HashCode对1000取模,也就是将文件根据HashCode值分为1000份,每份大小大约1GB。这样就可以将HashCode相同的行存储到同一个文件中;
- 每份文件中的数据再利用HashSet来判断是否重复。
上述的这种思想其实就是一种分治的思想,将文件根据某个规则切分成多份,对每一份进行处理,最终完成需求。
时间复杂度:首先对每一行进行遍历,时间复杂度为0(n),然后根据每个拆分后的小文件,运用HashSet来判断重复行,1000个小文件,每个小文件处理的最坏情况,复杂度为0(n),所有总的时间复杂度为O(n+1000*n)=0(n),这种方式比刚才最笨的方式0(n2)来说快多了。
排序
在单机且可用内存只有1G的情况下,如何对1T的数据进行排序?
外排序。传统的排序算法一般指内排序算法,针对的是数据可以一次全部载入内存中的情况。但是面对海量数据,即数据不可能一次全部载入内存,需要用到外排序的方法。外排序采用的就是分而治之(分块的方法),首先将数据分块,对块内数据按选择一种高效的内排序策略进行排序。然后采用归并排序的思想对于所有的块进行排序,得到所有数据的一个有序序列。
设置一个阈值(500M),按行读取数据,如果读取数据量超过阈值就产生一个新文件。大略算一下一共切分成2048个文件。现在的情况是:文件内部和文件外部全部无序。然后:
-
使用归并算法对每个文件进行排序,让文件内部有序。
-
然后使用归并让多个文件合并到一起。
Hadoop历史
Hadoop进化史
-
Nutch
- Hadoop最早起源于Nutch。
- Nutch的设计目标是构建一个大型的全网搜索引擎,包括网页抓取、索引、查询等功能
- 但随着抓取网页数量的增加,遇到了严重的可扩展性问题–如何解决数十亿网页的存储和索引问题。
-
Google
-
2003年、2004年谷歌发表的两篇论文为该问题提供了可行的解决方案。
-
GFS:Google File System
-
MapReduce:数据计算的方法
-
-
Doug cutting花费了自己的两年业余时间,将论文实现了出来
- 2008年1月,HADOOP成为Apache顶级项目
-
Hadoop
-
狭义上来说,hadoop就是单独指代hadoop这个软件,
-
广义上来说,hadoop指代大数据的一个生态圈,包括很多其他的软件
-
Hadoop官网
Hadoop Model
-
Hadoop Common:Hadoop体系最底层的一个模块,是其他模块的基础设施。
-
Hadoop Distributed File System (HDFSTM):Hadoop 分布式文件系统,是Hadoop的基石。负责存储数据。
-
Hadoop YARN:Hadoop 作业调度和资源管理框架。负责资源调度。
-
Hadoop MapReduce:Hadoop 基于YARN的大数据并行处理程序。负责计算。
分布式文件系统架构
-
FS File System
- 文件系统是基于硬盘之上的一个文件管理的工具
- 我们用户操作文件系统可以和硬盘进行解耦
-
DFS Distributed File System:
-
分布式文件系统
-
将我们的数据存放在多台电脑上存储
-
分布式文件系统有很多,
-
HDFS是mapreduce计算的基础
-
文件切分思想
-
文件存放在一个磁盘上效率肯定是低的
- 读取效率低
- 如果文件特别大会超出单机的存储范围
-
字节数组
-
文件在磁盘真实存储文件的抽象概念
-
数组可以进行拆分和组装,源文件不会受到影响
-
-
切分数据
- 对字节数组进行切分
-
拼接数据
- 按照数组的偏移量将数据连接到一起,将字节数组链接到一起
-
偏移量
-
当前数据在数组中的相对位置,你可以理解为下标
-
数组都有对应的索引(下标),可以快速的定位数据
-
-
数据存储的原理:
-
不管文件的的大小,所有的文件都是由字节数组构成
-
如果我们要切分文件,就是将一个字节数组分成多份
-
我们将切分后的数据拼接到一起,数据可以继续使用
-
我们需要根据数据的偏移量将他们重新拼接到一起
-
Block拆分标准
-
拆分的数据块需要等大
-
数据计算的时候简化问题的复杂度
- 进行分布式算法设计的时候,数据不统一,算法很难设计
-
数据拉取的时候时间相对一致
-
通过偏移量就知道这个块的位置
-
相同文件,分成的数据块大小应该相等
-
-
数据块 Block
-
数据被切分后的一个整体称之为块
-
在H1默认大小为64M,在H2及其以后默认大小为128M
-
同一个文件中,每个数据块大小要一致除了最后一个节点外
-
不同文件中,块的大小可以不一致
-
文件大小不同可以设置不同的块的数量
-
-
真实情况下,会根据文件大小和集群节点的数量综合考虑块的大小
-
数据块的个数=Ceil(文件大小/每个块的大小)
-
-
注意事项
-
HDFS中一旦文件被存储,数据不允许被修改
- 修改会影响偏移量
- 修改会导致数据倾斜
- 修改数据会导致蝴蝶效益
-
但是可以被追加,但是不推荐
- 追加设置需要手动打开
-
一般HDFS存储的都是历史数据。所以将来Hadoop的mr都用来进行离线数据的处理
-
块的大小一旦文件上传之后就不允许被修改
- 128m-512M
-
如果数据文件的切割点128M整好是一个单词的中间部分,切分数据如何保证数据的完整性?
-
Block数据安全
-
肯定要对存储数据做备份
-
备份的数据肯定不能存放在一个节点上
- 使用数据的时候可以就近获取数据
-
所以备份的数量要小于等于节点的数量
-
每个数据块会有3个副本,相同副本是不会存放在同一个节点上
-
副本的数量可以变更
-
可能近期的数据被分析的可能性跟大,副本数可以多设置几个
-
后期数据很少被分析,可以减少副本数
-
Block的管理效率
- 需要专门给节点进行分工
- 存储 DataNode
- 记录 NameNode
- 日志QJM
HDFS的特点
-
优点
-
a)高容错性
-
i.保存多个副本,且提供容错机制。
-
ii.副本丢失或宕机自动恢复。默认存3份。
-
-
b)运行在廉价的机器上(商用机)
-
i.通过副本提高可靠性
-
ii.提供了容错和恢复机制
-
-
c)适合批处理
-
i.移动计算而非数据
-
ii.数据位置暴露给计算框架。NameNode上有位置
-
-
d)适合大数据的处理
-
i.TB,甚至PB级数据
-
ii.百万规模以上的文件数量
-
iii.10K+节点规模
-
-
e)流式数据访问
- i.一次写入,多次读取,高吞吐量,所以可以同时处理大量数据
-
-
缺点
-
a)不擅长低延迟数据访问
- 比如毫秒级
-
b)不擅长小文件的分区
-
i.占用NameNode大量内存
-
ii.磁盘寻道时间超过读取时间
-
-
c)不擅长并发写入,文件随机修改
-
i.一个文件只能有一个写入者
-
ii.仅支持append,也就是添加(有组件实现删等)
-
-
Hadoop 基础架构
NameNode(NN)
功能
-
接受客户端的读写服务
-
NameNode存放文件与Block的映射关系
-
NameNode会记录Block与DataNode的映射关系,但是不会持久化
-
-
保存文件的元数据信息
-
文件的归属
-
文件的权限
-
文件的大小时间
-
Block信息,但是block的位置信息不会持久化,需要每次开启集群的时候DN上报
-
收集Block的信息
-
系统启动时
-
NN关机的时候是不会存储任意的Block与DN的映射信息
-
DN启动的时候,会将自己节点上存储的Block信息汇报给NN
-
NN接受请求之后重新生成映射关系
- Block–DN3
-
如果某个数据块的副本数小于设置数,那么NN会将这个副本拷贝到其他节点
-
-
集群运行中
-
NN与DN保持心跳机制,三秒钟发送一次
-
<property> <description>Determines datanode heartbeat interval in seconds.</description> <name>dfs.heartbeat.interval</name> <value>3</value> </property> <property> <name>heartbeat.recheck.interval</name> <value>300000</value> </property>
-
如果客户端需要读取或者上传数据的时候,NN可以知道DN的健康情况
-
可以让客户端读取存活的DN节点
-
-
-
如果DN超过三秒没有心跳,就认为DN出现异常
- 不会让新的数据读写到DataNode
- 客户访问的时候不提供异常结点的地址
-
如果DN超过10分钟+30秒没有心跳,那么NN会将当前DN存储的数据转存到其他节点
-
超时时长的计算公式为:
timeout=2heartbeat.recheck.interval+10dfs.heartbeat.interval。
而默认的heartbeat.recheck.interval大小为5分钟,dfs.heartbeat.interval默认为3秒。
-
性能
-
NameNode为了效率,将所有的操作都在内存中完成
-
NameNode不会和磁盘进行任何的数据交换
-
问题:
-
数据的持久化
-
数据保存在内存中,掉电易失
-
-
DataNode(DN)
功能
-
存放的是文件的数据信息和验证文件完整性的校验信息
- 数据会存放在硬盘上
- 1m=1条元数据 1G=1条元数据
- NameNode非常排斥存储小文件,一般小文件在存储之前需要进行压缩
-
汇报
- 启动时
- 汇报之前先验证Block文件是否被损坏
- 向NN汇报当前DN上block的信息
- 运行中
- 向NN保持心跳机制
- 客户可以向DN读写数据
- 启动时
-
当客户端读写数据的时候,首先去NN查询file与block与dn的映射
- 然后客户端直接与dn建立连接,然后读写数据
Hadoop-HA架构
设计思想
-
hadoop2.x启用了主备节点切换模式(1主1备)
-
当主节点出现异常的时候,集群直接将备用节点切换成主节点
-
要求备用节点马上就要工作
-
主备节点内存几乎同步
-
-
有独立的线程对主备节点进行监控健康状态
-
需要有一定的选举机制,帮助我们确定主从关系
-
我们需要实时存储日志的中间件
ANN
-
Active NameNode的功能和原理的NN的功能是一样的
-
接受客户端请求,查询数据块DN信息
-
存储数据的元数据信息
- 数据文件:Block:DN的映射关系
-
工作
- 启动时:接受DN的block汇报
- 运行时:和DN保持心跳(3s,10m30s)
-
存储介质
-
完全基于内存
-
优点:数据处理效率高
-
缺点:数据的持久化(日志edits+快照fsimage)
-
SNN
-
Standby NameNode:NN的备用节点
-
他和主节点做同样的工作,但是它不会发出任何指令
-
存储:数据的元数据信息
- 数据文件:Block:DN的映射关系
- 它的内存数据和主节点内存数据几乎是一致的
-
工作:
- 启动时:
- 接受DN的block汇报
- 运行时:
- 和DN保持心跳(3s,10m30s)
- 启动时:
-
存储介质
- 完全基于内存
- 优点:数据处理效率高
- 缺点:数据的持久化
-
合并日志文件和镜像
-
当搭建好集群的时候,格式化主备节点的时候,ANN和SNN都会会默认创建
- fsimage_000000000000000
-
当我们操作HDFS的时候ANN会产生日志信息
- edits_inprogress_0000000000001
-
主节点会将日志文件中新增的数据同步到JournalNode集群上
-
edits文件默认2分钟生成一个,默认上限100W个;
-
只有Active NameNode 才可以将edits元数据写入到QJM;
-
每个NameNode上的edits元数据是不完整的(主备切换导致),但是QJM中一定是完整的;
-
Hadoop 2.x以及以后 fsimage 文件的合并机制:
- 时间纬度:1小时合并一次;
- 操作纬度:edits操作次数超过100W次;
- 纬度检查周期:默认1分钟检查一次。
-
QJM只保存 edits文件,不保存fsimage文件,fsimage 文件只保存在 NameNode中。SNN将合并后的fsimage发送给ANN,ANN验证无误后,存放到自己的目录中;
-
ANN使用fsimage 加edits_inprogress_文件还有大于fsimage的edits文件即可完全恢复元数据。
-
DataNode(DN)
-
存储
- 文件的Block数据
-
介质
- 硬盘
-
启动时:
- 同时向两个NN汇报Block信息
-
运行中
- 同时和两个NN节点保持心跳机制
QJM
-
Quorum JournalNode Manager 共享存储系统,NameNode通过共享存储系统实现日志数据同步。
-
JournalNode是一个独立的小集群,它的实现原理和Zookeeper的一致(Paxos)
-
ANN产生日志文件的时候,就会同时发送到JournalNode的集群中每个节点上
-
JournalNode不要求所有的jn节点都接收到日志,只要有半数以上的(n/2+1)节点接受收到日志,那么本条日志就生效
-
SNN每间隔一段时间就去QJM上面取回最新的日志
- SNN上的日志有可能不是最新的
-
HA集群的状态正确至关重要,一次只能有一个NameNode处于活动状态。
-
JournalNode只允许单个NameNode成为作者。在故障转移期间,将变为活动状态的NameNode将承担写入JournalNodes的角色,这将有效地防止另一个NameNode继续处于活动状态,从而使新的Active节点可以安全地进行故障转移。
ZKFC
- Failover Controller(故障转移控制器)
- 对NameNode的主备切换进行总体控制,能及时检测到NameNode的健康状况
- 在主NameNode故障时借助 Zookeeper实现自动的主备选举和切换
- 为了防止因为NN的GC失败导致心跳受影响,ZKFC作为一个deamon进程从NN分离出来
-
启动时:
- 当集群启动时,主备节点的概念是很模糊的
- 当ZKFC只检查到一个节点是健康状态,直接将其设置为主节点
- 当zkfc检查到两个NN节点是的健康状态,发起投票机制
- 选出一个主节点,一个备用节点,并修改主备节点的状态
-
运行时:
-
由ZKFailoverController、HealthMonitor和 ActiveStandbyElector这3个组件来协同实现主备切换
-
ZKFailoverController启动的时候会创建HealthMonitor和ActiveStandbyElector这两个主要的内部组件
-
HealthMonitor 主要负责检测NameNode的健康状态
-
ActiveStandbyElector主要负责完成自动的主备选举,内部封装了Zookeeper的处理逻辑。
-
-
-
-
主备节点正常切换
-
NameNode在选举成功后,ActiveStandbyElector会在zk上创建一个ActiveStandbyElectorLock临时节点,而没有选举成功的备 NameNode中的ActiveStandbyElector会监控这个节点
-
如果Active NameNode 对应的HealthMonitor检测到NameNode的状态异常时,ZKFailoverController会主动删除当前在Zookeeper上建立的临时节点ActiveStandbyElectorLock。
-
如果是Active NameNode的机器整个宕掉的话,那么跟zookeeper连接的客户端线程也挂了,会话结束,那么根据Zookeepe的临时节点特性,ActiveStandbyElectorLock节点会自动被删除,从而也会自动进行一次主备切换
-
处于Standby状态的NameNode的ActiveStandbyElector注册的监听器就会收到这个节点的NodeDeleted事件,并创建ActiveStandbyElectorLock临时节点,本来处于Standby状态的NameNode 就选举为Active NameNode 并随后开始切换为Active状态。
-
ZooKeeper
-
为主备切换控制器提供主备选举支持。
-
辅助投票
-
和ZKFC保持心跳机制,确定ZKFC的存活
脑裂 brain-split
-
定义
- 脑裂是Hadoop2.X版本后出现的全新问题,实际运行过程中很有可能出现两个namenode同时服务于整个集群的情况,这种情况称之为脑裂。
-
原因
- 脑裂通常发生在主从namenode切换时,由于ActiveNameNode的网络延迟、设备故障等问题,另一个NameNode 会认为活跃的NameNode成为失效状态,此时StandbyNameNode会转换成活跃状态,此时集群中将会出现两个活跃的namenode。因此,可能出现的因素有网络延迟、心跳故障、设备故障等。
-
脑裂场景
-
NameNode可能会出现这种情况,NameNode在垃圾回收(GC)时,可能会在长时间内整个系统无响应
-
zkfc客户端也就无法向zk写入心跳信息,这样的话可能会导致临时节点掉线,备NameNode会切换到Active状态
-
这种情况可能会导致整个集群会有同时有两个Active NameNode
-
-
脑裂问题的解决方案是隔离(Fencing)
- 1.第三方共享存储:任一时刻,只有一个NN可以写入;
- 2.DataNode:需要保证只有一个NN发出与管理数据副本有关的命令;
- 3.Client需要保证同一时刻只有一个NN能够对Client的请求发出正确的响应。
- (a)每个NN改变状态的时候,向DN发送自己的状态和一个本次选举对应的序列号。
- (b)DN在运行过程中维护此序列号,当failover时,新的NN在返回DN心跳时会返回自己的active状态和一个更大的序列号。
- DN接收到这个返回是认为该NN为新的active。
- (c)如果这时原来的active(比如GC)恢复,返回给DN的心跳信息包含active状态和原来的序列号,这时DN就会拒绝这个NN的命令。
-
解决方案
-
ActiveStandbyElector为了实现fencing,当NN成为ANN之后创建Zookeeper临临时节点ActiveStandbyElectorLock,创建ActiveBreadCumb的持久节点,这个节点里面保存了这个Active NameNode的地址信息(node-01)
-
Active NameNode的 ActiveStandbyElector在正常的状态下关闭Zookeeper Session的时候,会一起删除这个持久节点
-
但如果ActiveStandbyElector在异常的状态下关闭,那么由于/hadoop-ha/${dfs.nameservices}/ActiveBreadCrumb 是持久节点,会一直保留下来,后面当另一个NameNode 选主成功之后,会注意到上一个Active NameNode 遗留下来的这个节点,从而会回调ZKFailoverController的方法对旧的Active NameNode 进行 fencing。
- 首先尝试调用这个旧Active NameNode的HAServiceProtocol RPC 接口的 transitionToStandby方法,看能不能把它转换为Standby状态;
- 如果transitionToStandby方法调用失败,那么就执行Hadoop配置文件之中预定义的隔离措施。
- 1.sshfence:通过SSH登录到目标机器上,执行命令fuser将对应的进程杀死
- 2.shellfence:执行一个用户自定义的shell脚本来将对应的进程隔离
-
在成功地执行完成fencing之后,选主成功的ActiveStandbyElector 才会回调 ZKFailoverController的 becomeActive 方法将对应的NameNode转换为Active状态,开始对外提供服务。
-
新的主创建临时节点ActiveStandbyElectorLock,创建持久化节点ActiveBreadCrumb,并将自己的主机地址Node02赋值给初始化节点
-
Hadoop-Federation联邦
- HDFS Federation就是使得HDFS支持多个命名空间,并且允许在HDFS中同时存在多个Name Node。
单NN局限性
-
Namespace(命名空间)的限制
- NameNode所能存储的对象(文件+块)数目受到NameNode所在JVM的heap size的限制。
- 50G的heap能够存储20亿(200million)个对象,这20亿个对象支持4000个DataNode,12PB的存储
- DataNode从4T增长到36T,集群的尺寸增长到8000个DataNode。存储的需求从12PB增长到大于100PB。
-
性能的瓶颈
- 整个HDFS文件系统的吞吐量受限于单个Namenode的吞吐量
-
隔离问题
- HDFS上的一个实验程序就很有可能影响整个HDFS上运行的程序
-
集群的可用性
- Namenode的宕机无疑会导致整个集群不可用。
-
Namespace和Block Management的紧密耦合
-
纵向扩展目前的Namenode不可行
-
将Namenode的Heap空间扩大到512GB启动花费的时间太长
-
Namenode在Full GC时,如果发生错误将会导致整个集群宕机
-
Federation
-
块池Block Pool
- Block pool(块池)就是属于单个命名空间的一组block(块)管理区域
- 每一个datanode为所有的block pool存储
- Datanode是一个物理概念,而block pool是一个重新将block划分的逻辑概念
- 一个Namenode失效不会影响其下的datanode为其他Namenode的服务
- datanode与Namenode建立联系并开始会话后自动建立Block pool
-
Namespace Volume(命名空间卷)
- 一个Namespace和它的Block Pool合在一起称作Namespace Volume
- Namespace Volume是一个独立完整的管理单元。当一个Namenode/Namespace被删除,与之相对应的Block Pool 也也被删除。
-
通过多个namenode/namespace把元数据的存储和管理分散到多个节点中
- 降低单个NN节点数据压力,计算压力
-
namenode/namespace可以通过增加机器来进行水平扩展
-
可以让更多的节点参与到运算
-
namespace命名空间,通过这种方式确定要处理数据的路径
-
-
我们可以通过namenode和namespace组合使用
-
所有的nn共享dn
-
但是每一个namespace会单独管理自己的块
-
会创建一个管理块的机制:blocks pool
-
Hadoop-HA高可用集群环境搭建
目标环境
安装
解压即安装
将准备好的安装包上传至node01,然后解压:
[root@node01 ~]# tar -zxvf hadoop-3.3.4.tar.gz -C /opt/yjx/
[root@node01 ~]# rm hadoop-3.3.4.tar.gz -rf
修改配置文件
修改环境配置文件 hadoop-env.sh
:
[root@node01 ~]# cd /opt/yjx/hadoop-3.3.4/etc/hadoop/
[root@node01 hadoop]# vim hadoop-env.sh
在文件末尾添加以下内容:
export JAVA_HOME=/usr/java/jdk1.8.0_351-amd64
export HDFS_NAMENODE_USER=root
export HDFS_DATANODE_USER=root
export HDFS_ZKFC_USER=root
export HDFS_JOURNALNODE_USER=root
export YARN_RESOURCEMANAGER_USER=root
export YARN_NODEMANAGER_USER=root
修改核心配置文件 core-site.xml
:
[root@node01 hadoop]# vim core-site.xml
在configuration
节点中添加以下内容:
<!-- 设置 NameNode 节点的 URI(包括协议、主机名称、端口号),用于 NameNode 与 DataNode 之间的通讯 -->
<property>
<name>fs.defaultFS</name>
<value>hdfs://hdfs-yjx</value>
</property>
<!-- 设置 Hadoop 运行时临时文件的存放位置,比如 HDFS 的 NameNode 数据默认都存放这个目录下 -->
<property>
<name>hadoop.tmp.dir</name>
<value>/var/yjx/hadoop/ha</value>
</property>
<!-- 设置在 Web 界面访问数据时使用的用户名 -->
<property>
<name>hadoop.http.staticuser.user</name>
<value>root</value>
</property>
<!-- 设置 HA,需要一组 ZK 地址,以逗号分隔。被 ZKFailoverController 使用于自动失效备援 failover -->
<property>
<name>ha.zookeeper.quorum</name>
<value>node01:2181,node02:2181,node03:2181</value>
</property>
<!-- 该参数表示可以通过 httpfs 接口访问 HDFS 的 IP 地址限制 -->
<!-- 配置 root(超级用户) 允许通过 httpfs 方式访问 HDFS 的主机名、域名 -->
<property>
<name>hadoop.proxyuser.root.hosts</name>
<value>*</value>
</property>
<!-- 通过 httpfs 接口访问的用户获得的群组身份 -->
<!-- 配置允许通过 httpfs 方式访问的客户端的用户组 -->
<property>
<name>hadoop.proxyuser.root.groups</name>
<value>*</value>
</property>
hadoop.tmp.dir
属性的默认值为/tmp/hadoop-${user.name}
,NameNode 会将 HDFS 的元数据存储在这个/tmp 目录下,如果操作系统重启了,系统会清空 /tmp,导致 NameNode 元数据丢失,是个非常严重的问题,所以我们需要修改此路径。
hadoop.http.staticuser.user=dr.who
默认值是一个不真实存在的用户,此用户权限非常小,不能访问不同用户的数据,但是这保证了数据的安全。也可以设置为 hdfs 和 hadoop 等具有较高权限的用户,但会导致能够登陆网页界面的人会看到其它用户的数据。实际设置请综合考虑,如无特殊需求,使用默认值就好。
修改HDFS配置文件 hdfs-site.xml
:
[root@node01 hadoop]# vim hdfs-site.xml
在configuration
节点中添加以下内容:
<!-- 设置 nameservices 列表(联邦列表),逗号分隔 -->
<property>
<name>dfs.nameservices</name>
<value>hdfs-yjx</value>
</property>
<!-- 设置一个 NameNode 列表。hdfs-yjx 是指具体的 nameservice 名称,通常就是 dfs.nameservices 中配置的。值
是预备配置的 NameNode 的 ID,ID 是自己取的,不重复就可以,例如 nn1,nn2 -->
<property>
<name>dfs.ha.namenodes.hdfs-yjx</name>
<value>nn1,nn2</value>
</property>
<!-- 设置 NameNode 的 RPC 地址和端口 -->
<property>
<name>dfs.namenode.rpc-address.hdfs-yjx.nn1</name>
<value>node01:8020</value>
</property>
<!-- 设置 NameNode 的 RPC 地址和端口 -->
<property>
<name>dfs.namenode.rpc-address.hdfs-yjx.nn2</name>
<value>node02:8020</value>
</property>
<!-- 设置 NameNode 的 HTTP 地址和端口 -->
<property>
<name>dfs.namenode.http-address.hdfs-yjx.nn1</name>
<value>node01:9870</value>
</property>
<!-- 设置 NameNode 的 HTTP 地址和端口 -->
<property>
<name>dfs.namenode.http-address.hdfs-yjx.nn2</name>
<value>node02:9870</value>
</property>
<!-- 设置 QJM 共享存储系统服务器。在多个 NameNode 中共享存储目录,用于存放 edits 文件,该目录由 Active 写,
Standby 读 -->
<property>
<name>dfs.namenode.shared.edits.dir</name>
<value>qjournal://node01:8485;node02:8485;node03:8485/hdfs-yjx</value>
</property>
<!-- 设置 journalnode 用于存放 edits 日志的目录,默认值为 /tmp/hadoop/dfs/journalnode -->
<property>
<name>dfs.journalnode.edits.dir</name>
<value>/var/yjx/hadoop/ha/qjm</value>
</property>
<!-- 设置客户端连接 Active NameNode 所用的代理类 -->
<property>
<name>dfs.client.failover.proxy.provider.hdfs-yjx</name>
<value>org.apache.hadoop.hdfs.server.namenode.ha.ConfiguredFailoverProxyProvider</value>
</property>
<!-- 设置 HDFS-HA 功能的防脑裂方法。可以是内建的方法(例如 shell 和 sshfence)或者用户自定义的方法 -->
<property>
<name>dfs.ha.fencing.methods</name>
<value>sshfence</value>
<value>shell(true)</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>
<!-- 设置 HDFS 默认的数据块副本数。可以在创建文件时指定,如果创建时未指定,则使用默认值 -->
<property>
<name>dfs.replication</name>
<value>2</value>
</property>
修改 workers
:
[root@node01 hadoop]# vim workers
用以下内容替换文件内容:
node01
node02
node03
拷贝至其他节点
将node01 已配置好的 hadoop 拷贝至 node02和 node03。
[root@node02 ~]# scp -r root@node01:/opt/yjx/hadoop-3.3.4 /opt/yjx/
[root@node03 ~]# scp -r root@node01:/opt/yjx/hadoop-3.3.4 /opt/yjx/
# 或者使用分发脚本
[root@node01 ~]# yjxrsync /opt/yjx/hadoop-3.3.4/
修改环境变量
三个节点修改环境变量vim/etc/profile
,在文件末尾添加以下内容:
export HADOOP_HOME=/opt/yjx/hadoop-3.3.4
export PATH=$HADOOP_HOME/bin:$HADOOP_HOME/sbin:$PATH
修改完成后 source/etc/profile
重新加载环境变量。
启动
首先启动 ZooKeeper(三台机器都需要执行)。
zkServer.sh start
zkServer.sh status
然后启动 JournalNode(三台机器都需要执行)。
hdfs --daemon start journalnode
最后格式化NameNode等相关服务并启动集群。
# 格式化 node01 的 namenode(第一次配置的情况下使用)
[root@node01 ~]# hdfs namenode -format
# 启动 node01 的 namenode
[root@node01 ~]# hdfs --daemon start namenode
# node02 节点同步镜像数据
[root@node02 ~]# hdfs namenode -bootstrapStandby
# 格式化 zkfc(第一次配置的情况下使用)
[root@node01 ~]# hdfs zkfc -formatZK
# 启动 HDFS
[root@node01 ~]# start-dfs.sh
后期只需要先启动ZooKeeper然后再启动HDFS即可。
访问
访问:http://192.168.100.101:9870/和 http://192.168.100.102:9870/
测试文件上传
[root@node01 ~]# hdfs dfs -mkdir -p /test
[root@node01 ~]# hdfs dfs -put hadoop-3.3.4.tar.gz /test
# 指定 Block 大小
[root@node01 ~]# hdfs dfs -D dfs.blocksize=134217728 -put hadoop-3.3.4.tar.gz /test
关闭
先关闭HDFS。
[root@node01 ~]# stop-dfs.sh
再关闭ZooKeeper(三台机器都需要执行)。
[root@node01 ~]# stop-dfs.sh
环境搭建成功后 shutdown -h now
关机拍摄快照。
Hadoop 集群命令
命令分类
-
hadoop fs:
-
FS relates to a generic file system which can point to any file systems like local, HDFS etc. So this can be used when you are dealing with different file systems such as Local FS, HFTP FS, S3 FS, and others
-
该命令可以用于其他文件系统,不止是hdfs文件系统内,也就是说该命令的使用范围更广
-
-
hadoop dfs
- 专门针对hdfs分布式文件系统
-
hdfs dfs(推荐)
- 和上面的命令作用相同,相比于上面的命令更为推荐,并且当使用hadoop dfs时内部会被转为hdfs dfs命令
Hadoop FS命令
-
介绍
-
调用文件系统(FS)Shell命令应使用 bin/hadoop fs的形式。所有的的FS shell命令使用URI路径作为参数。
-
URI格式是scheme://authority/path。对HDFS文件系统,scheme是hdfs,对本地文件系统,scheme是file。
-
其中scheme和authority参数都是可选的,如果未加指定,就会使用配置中指定的默认scheme。
-
一个HDFS文件或目录比如/parent/child可以表示成hdfs://namenode:namenodeport/parent/child,或者更简单的/parent/child(假设你配置文件中的默认值是namenode:namenodeport)。
-
大多数FS Shell命令的行为和对应的Unix Shell命令类似,不同之处会在下面介绍各命令使用详情时指出。出错信息会输出到stderr,其他信息输出到stdout。
-
-
网址
-
1 hadoop fs -ls <path>
列出指定目录下的内容,支持pattern匹配。输出格式如filename(full path)<r n>size.n代表备份数。
2 hadoop fs -lsr <path>
递归列出该路径下所有子目录信息
3 hadoop fs -du<path>
显示目录中所有文件大小,或者指定一个文件时,显示此文件大小
4 hadoop fs -dus<path>
显示文件大小 相当于 linux的du -sb s代表显示只显示总计,列出最后的和 b代表显示文件大小时以byte为单位
5 hadoop fs -mv <src> <dst>
将目标文件移动到指定路径下,当src为多个文件,dst必须为目录
6 hadoop fs -cp <src> <dst>
拷贝文件到目标位置,src为多个文件时,dst必须是个目录
7 hadoop fs -rm [skipTrash] <src>
删除匹配pattern的指定文件
8 hadoop fs -rmr [skipTrash] <src>
递归删除文件目录及文件
9 hadoop fs -rmi [skipTrash] <src>
为了避免误删数据,加了一个确认
10 hadoop fs -put <> ... <dst>
从本地系统拷贝到dfs中
11 hadoop fs -copyFromLocal<localsrc>...<dst>
从本地系统拷贝到dfs中,与-put一样
12 hadoop fs -moveFromLocal <localsrc>...<dst>
从本地系统拷贝文件到dfs中,拷贝完删除源文件
13 hadoop fs -get [-ignoreCrc] [-crc] <src> <localdst>
从dfs中拷贝文件到本地系统,文件匹配pattern,若是多个文件,dst必须是个目录
14 hadoop fs -getmerge <src> <localdst>
从dfs中拷贝多个文件合并排序为一个文件到本地文件系统
15 hadoop fs -cat <src>
输出文件内容
16 hadoop fs -copyTolocal [-ignoreCre] [-crc] <src> <localdst>
与 -get一致
17 hadoop fs -mkdir <path>
在指定位置创建目录
18 hadoop fs -setrep [-R] [-w] <rep> <path/file>
设置文件的备份级别,-R标志控制是否递归设置子目录及文件
19 hadoop fs -chmod [-R] <MODE[,MODE]...|OCTALMODE>PATH
修改文件权限, -R递归修改 mode为a+r,g-w,+rwx ,octalmode为755
20 hadoop fs -chown [-R] [OWNER][:[GROUP]] PATH
递归修改文件所有者和组
21 hadoop fs -count[q] <path>
统计文件个数及占空间情况,输出表格列的含义分别为:DIR_COUNT.FILE_COUNT.CONTENT_SIZE.FILE_NAME,如果加-q 的
话,还会列出QUOTA,REMAINING_QUOTA,REMAINING_SPACE_QUOTA
hdfs dfs命令
-mkdir 创建目录 hdfs dfs -mkdir [-p] < paths>
-ls 查看目录下内容,包括文件名,权限,所有者,大小和修改时间 hdfs dfs -ls [-R] < args>
-put 将本地文件或目录上传到HDFS中的路径 hdfs dfs -put <localsrc> … < dst>
-get 将文件或目录从HDFS中的路径拷贝到本地文件路径 hdfs dfs -get [-ignoreCrc] [-crc] <src> <localdst>
选项:-ignorecrc选项复制CRC校验失败的文件。-crc选项复制文件和CRC。
-du 显示给定目录中包含的文件和目录的大小或文件的长度,用字节大小表示。 hdfs dfs -du [-s] [-h] URI [URI…] 选项:-s选项将显示文件长度的汇总摘要,而不是单个文件。-h选项将以“人可读”的方式格式化文件大小(例如64.0m而不是67108864);第一列标示该目录下总文件大小,第二列标示该目录下所有文件在集群上的总存储大小和你的副本数相关
(第二列内容=文件大小*副本数),第三列标示你查询的目录
-dus 显示文件长度的摘要。 hdfs dfs -dus < args> 注意:不推荐使用此命令。而是使用hdfs dfs -du -s。
-mv 在HDFS文件系统中,将文件或目录从HDFS的源路径移动到目标路径。不允许跨文件系统移动文件。
-cp 在HDFS文件系统中,将文件或目录复制到目标路径下 hdfs dfs -cp [-f] [-p | -p [topax] ] URI [ URI …]
< dest> 选项:-f选项覆盖已经存在的目标。-p选项将保留文件属性[topx](时间戳,所有权,权限,ACL,XAttr)。
如果指定了-p且没有arg,则保留时间戳,所有权和权限。如果指定了-pa,则还保留权限,因为ACL是一组超级权限。确定是否保留原始命名空间扩展属性与-p标志无关。
-copyFromLocal 从本地复制文件到hdfs文件系统(与-put命令相似)hdfs dfs -copyFromLocal <localsrc> URI
选项:如果目标已存在,则-f选项将覆盖目标。
-copyToLocal 复制hdfs文件系统中的文件到本地 (与-get命令相似) hdfs dfs -copyToLocal [-ignorecrc] [-crc] URI < localdst>
-rm 删除一个文件或目录 hdfs dfs -rm [-f] [-r|-R] [-skipTrash] URI [URI …] 选项:如果文件不存在,-f选项将不显示诊断消息或修改退出状态以反映错误。-R选项以递归方式删除目录及其下的任何内容。-r选项等效于-R。-skipTrash选项将绕过垃圾桶(如果已启用),并立即删除指定的文件。当需要从超配额目录中删除文件时,这非常有用。
-cat 显示文件内容到标准输出上。 hdfs dfs -cat URI [URI …]
-text 获取源文件并以文本格式输出文件。允许的格式为zip和TextRecordInputStream。 hdfs dfs -text
-touchz 创建一个零长度的文件。 hdfs dfs -touchz URI [URI …]
-stat 显示文件所占块数(%b),文件名(%n),块大小(%n),复制数(%r),修改时间(%y%Y) hdfs dfs -stat URI
[URI …]
-tail 显示文件的最后1kb内容到标准输出 hdfs dfs -tail [-f] URI 选项: -f选项将在文件增长时输出附加数据,如在Unix中一样。
-count 统计与指定文件模式匹配的路径下的目录,文件和字节数 hdfs dfs -count [-q] [-h] < paths>
-getmerge 将源目录和目标文件作为输入,并将src中的文件连接到目标本地文件(把两个文件的内容合并起来) hdfs dfs -getmerge < src> < localdst> [addnl] 注:合并后的文件位于当前目录,不在hdfs中,是本地文件
-grep 从hdfs上过滤包含某个字符的行内容 hdfs dfs -cat < srcpath> | grep 过滤字段
-chown hdfs上文件权限修改 hadoop fs -chown [-R] [OWNER][:[GROUP]] URI [URI ]#修改文件的所有者 例如:hdfs dfs -chown -R Administrator:Administrator /user/
-distcp 最常用在集群之间的拷贝:hadoop distcp hdfs://master1:8020/foo/bar hdfs://master2:8020/bar/foo
Java访问Hadoop集群
环境变量
Windows 系统的环境变量配置:
-
解压 hadoop-3.3.4.zip,将解压后的文件夹存放到自己软件目录,例如:D:\hadoop\hadoop-3.3.4
-
将D:\hadoop\hadoop-3.3.4\bin 目录下的 winutils.exe 和 hadoop.dll文件拷贝到C:\Windows\System32 目录下
-
将Hadoop 添加到环境变量
- HADOOP_HOME –> D:\hadoop\hadoop-3.3.4
- HADOOP_USER_NAME–>root
- Path –> %HADOOP_HOME%\bin;%HADOOP_HOME%\sbin;
- JDK的版本也设置的和服务器版本一致
- 修改当前Window的 hosts(C:\Windows\System32\drivers\etc\hosts)文件,添加以下内容:
192.168.100.101 node01
192.168.100.102 node02
192.168.100.103 node03
Java访问Hadoop
打开IDEA,创建一个普通的Maven项目。拷贝Hadoop的以下配置文件至项目 resources 目录:
-
core-site.xml
-
hdfs-site.xml
-
mapred-site.xml
-
yarn-site.xml
-
log4j.properties
pom.xml文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.yjxxt</groupId>
<artifactId>hadoop-demo</artifactId>
<version>1.0-SNAPSHOT</version>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<!-- Hadoop 版本 -->
<hadoop.version>3.3.4</hadoop.version>
<!-- commons-io 版本 -->
<commons-io.version>2.11.0</commons-io.version>
</properties>
<dependencies>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-common</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-hdfs</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-client</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-common</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-core</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>org.apache.hadoop</groupId>
<artifactId>hadoop-mapreduce-client-jobclient</artifactId>
<version>${hadoop.version}</version>
</dependency>
<dependency>
<groupId>commons-io</groupId>
<artifactId>commons-io</artifactId>
<version>${commons-io.version}</version>
</dependency>
<dependency>
<groupId>com.janeluo</groupId>
<artifactId>ikanalyzer</artifactId>
<version>2012_u6</version>
</dependency>
<dependency>
<groupId>org.junit.jupiter</groupId>
<artifactId>junit-jupiter-api</artifactId>
<version>5.9.2</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
HDFSTest.java 代码如下:
package com.yjxxt.hdfs;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.DisplayName;
import org.junit.jupiter.api.Test;
import java.io.IOException;
@DisplayName("HDFS 测试类")
public class HDFSTest {
FileSystem fileSystem = null;
@BeforeEach
public void hdfsInit() throws IOException {
// 加载配置文件
Configuration configuration = new Configuration(true);
// 获取文件系统
fileSystem = FileSystem.get(configuration);
}
@DisplayName("文件上传与下载")
@Test
public void testFileUploadAndDownload() throws IOException {
// 文件上传
//Path srcPath = new Path("E:\\Informations\\MSB\\technical_information\\学习资料\\大数据阶段\\大数据第一阶段\\01Linux\\003_software\\JDK\\8\\jdk-8u351-linux-x64.tar.gz");
//Path destPath = new Path("/yjx/jdk-8u351-linux-x64.tar.gz");
//fileSystem.copyFromLocalFile(srcPath, destPath);
//文件下载
Path localPath = new Path("D:\\test");
Path hdfsPath = new Path("/yjx/jdk-8u351-linux-x64.tar.gz");
fileSystem.copyToLocalFile(hdfsPath, localPath);
}
}
Jetbrains Plugins(了解)
在 IntelliJ IDEA 或者 PyCharm 中打开插件市场,搜索 big data
,选择 Big Data Tools
进行安装。
安装后重启,在右侧点击Big Data Tools
,然后点击+
号,选择HDFS
。
然后填写Active NameNode节点的IP:端口,以及有操作权限的用户。
点击 Test connection
时如果报错:Path hdfs://node02:8020/ is not accessible or does not exist
。是由于Hadoop集群环境搭建完成后,没有创建作业目录导致,hdfs dfs -mkdir -p/data
随便创建个目录即可。
最终效果如下:
注意:使用Hadoop插件需要配置Windows Hadoop环境变量。也就是 配置环境变量和修改 hosts这两步。
Hadoop3.x其他特性
Erasure Encoding
简介
-
HDFS默认情况下,Block的备份系数是3,一个原始数据块和其他2个副本。
-
其中2个副本所需要的存储开销各站100%,这样使得200%的存储开销
-
正常操作中很少访问具有低I0活动的冷数据集的副本,但是仍然消耗与原始数据集相同的资源量。
EC技术
-
EC(擦除编码)和HDFS的整合可以保持与提供存储效率相同的容错。
- HDFS:一个副本系数为3,要复制文件的6个块,需要消耗6*3=18个块的磁盘空间
- EC:6个数据块,3个奇偶校验块
-
擦除编码需要在执行远程读取时,对数据重建带来额外的开销,因此他通常用于存储不太频繁访问的数据
NameNode
在Hadoop3中允许用户运行多个备用的NameNode。例如,通过配置三个NameNode(1个Active NameNode和2个Standby NameNode)和5个JournalNodes节点,此时集群可以容忍2个NameNode节点故障。
服务器端口
早些时候,多个Hadoop服务的默认端口位于Linux端口范围以内。因此,具有临时范围冲突端口已经被移除该范围。
DataNode
单个数据节点配置多个数据磁盘,在正常写入操作期间,数据被均匀的划分,因此,磁盘被均匀填充。在维护磁盘时,添加或者替换磁盘会导致DataNode节点存储出现偏移。这种情况在早期的HDFS文件系统中,是没有被处理的。
Hadoop3通过新的内部DataNode平衡功能来处理这种情况,这是通过hdfs diskbalancer CLI来进行调用的。执行之后,DataNode会进行均衡处理。
JDK
Hadoop3中,最低版本要求是JDK8,所以低于JDK8的版本需要对JDK进行升级,方可安装使用Hadoop3
附录:配置文件详解
core-site.xml
core-site.xml配置文件的作用:
用于定义系统级别的参数,如HDFS URL、Hadoop的临时目录以及用于rack-aware集群中的配置文件的配置等,此中的参数定义会覆盖core-default.xml文件中的默认配置。
fs.defaultFS 参数的作用:
#声明namenode的地址,相当于声明hdfs文件系统。我们可以指定某个ip地址,在ha模式中我们通常指定hdfs集群的逻辑名称
hadoop.tmp.dir 参数的作用:
#声明hadoop工作目录的地址。
hadoop.http.staticuser.user 参数的作用:
#在网页界面访问数据使用的用户名。默认值是一个不真实存在的用户,此用户权限很小,不能访问不同用户的数据。这保证了数据安全。也可以设置为hdfs和hadoop等具有较高权限的用户,但会导致能够登陆网页界面的人能看到其它用户数据。实际设置请综合考虑。如无特殊需求。使用默认值就好.
ha.zookeeper.quorum 参数的作用:
#指定zookeeper集群的地址,让zookeeper帮我们管理hdfs集群。
hdfs-site.xml
1、hdfs-site.xml 配置文件的作用:
#HDFS的相关设定,如文件副本的个数、块大小及是否使用强制权限等,此中的参数定义会覆盖hdfs-default.xml文件中的默认配置.
dfs.replication 参数的作用:
#为了数据可用性及冗余的目的,HDFS会在多个节点上保存同一个数据块的多个副本,其默认为3个。而只有一个节点的伪分布式环境中其仅用保存一个副本即可,这可以通过dfs.replication属性进行定义。它是一个软件级备份。
dfs.nameservices 参数的作用:
#指定一个逻辑名称,该名称会自动去帮我们找打真实NameNode节点,这和咱们的keepalive的VIP有点类似!这个名称咱们可以自定义!但是我们正在引用时千万别引用错了!
dfs.ha.namenodes.yinzhengjie-hdfs 参数的作用:
#看到没,上面我们定义了dfs.nameservices的名称,现在我们就用到了,我们把定义的逻辑名称指向了各个namenode的别名
dfs.namenode.rpc-address.yinzhengjie-hdfs.namenode1 参数的作用:
#定义远程主机调用的服务器地址。
dfs.namenode.http-address.yinzhengjie-hdfs.namenode1 参数的作用:
#上面我们定义了集群的逻辑名称,也定义节点的逻辑名称,但是真正的ip地址我们始终没有指定,因此我们这一步骤就是指定dfs.namenode.rpc-address.yinzhengjie-hdfs.namenode1对应的IP地址。当然你写主机名称也是可以的,只不过嘛你得在/etc/hosts文件做映射或者配置DNS中有对应的A记录哟!
dfs.namenode.shared.edits.dir 参数的作用:
#配置JournalNode集群的地址。
dfs.client.failover.proxy.provider.yinzhengjie-hdfs 参数的作用:
#配置故障转移的代理类,这是HDFS客户端找到active NameNode类名的一个代理类,如果你不配置这个项的话,那么客户端连接active namenode地址时会报错!实际上故障转移就是通过这个代理类来实现的,我们只需要默认官网的配置即可!不需要手动修改!
dfs.ha.fencing.methods 参数的作用:
#指定ha出现故障时的隔离方法!
dfs.ha.fencing.ssh.private-key-files 参数的作用:
#指定隔离主机的私钥PATH。
dfs.journalnode.edits.dir 参数的作用:
#指定JN节点存放编辑日志的目录。
dfs.ha.automatic-failover.enabled 参数的作用:
#开启自动故障转移功能.
– dfs.name.dir
– NameNode 元数据存放位置
– 默认值:使用core-site.xml中的hadoop.tmp.dir/dfs/name
– dfs.block.size
– 对于新文件切分的大小,单位byte。默认是64M,建议是128M。每一个节点都要指定,包括客户端。
– 默认值:67108864
– dfs.data.dir
– DataNode在本地磁盘存放block的位置,可以是以逗号分隔的目录列表,DataNode循环向磁盘中写入数据,每个DataNode
可单独指定与其它DataNode不一样
– 默认值:${hadoop.tmp.dir}/dfs/data
– dfs.namenode.handler.count
– NameNode用来处理来自DataNode的RPC请求的线程数量
– 建议设置为DataNode数量的10%,一般在10~200个之间
– 如设置太小,DataNode在传输数据的时候日志中会报告“connecton refused"信息
– 在NameNode上设定
– 默认值:10
– dfs.datanode.handler.count
– DataNode用来连接NameNode的RPC请求的线程数量
– 取决于系统的繁忙程度
– 设置太小会导致性能下降甚至报错
– 在DataNode上设定
– 默认值:3
– dfs.datanode.max.xcievers
– DataNode可以同时处理的数据传输连接数
– 默认值:256
– 建议值:4096
– dfs.permissions
– 如果是true则检查权限,否则不检查(每一个人都可以存取文件)
– 于NameNode上设定
– 默认值:true
– dfs.datanode.du.reserved
– 在每个卷上面HDFS不能使用的空间大小
– 在每个DataNode上面设定
– 默认值:0
– 建议为10737418240,即10G。需要结合MapReduce场景设置。
– dfs.datanode.failed.volumes.tolerated
– DataNode可以容忍损块的磁盘数量,超过这个数量DataNode将会离线,所有在这个节点上面的block将会被重新复制
– 默认是0,但是在有多块磁盘的时候一般会增大这个值
– dfs.replication
– 在文件被写入的时候,每一块将要被复制多少份
– 默认是3份。建议3份
– 在客户端上设定
通常也需要在DataNode上设定
2、HDFS core-site.xml 参数配置
– fs.default.name
– 文件系统的名字。通常是NameNode的hostname与port
– 需要在每一个需要访问集群的机器上指定,包括集群中的节点
– 例如:hdfs://<your_namenode>:9000/
– hadoop.tmp.dir
– HDFS与本地磁盘的临时文件
默认是/tmp/hadoop-${user.name}.需要在所有的节点中设定
– fs.trash.interval
– 当一个文件被删掉后,它会被放到用户目录的.Trash目录下,而不是立即删掉
– 经过此参数设置的分钟数之后,再删掉数据
– 默认是0,禁用此功能,建议1440(一天)
– io.file.buffer.size
– 设定在读写数据时的缓存大小,应该为硬件分页大小的2倍
– 默认是4096,建议为65536 ( 64K)