Hadoop-balancer执行原理

2024-09-03 16:32
文章标签 原理 执行 hadoop balancer

本文主要是介绍Hadoop-balancer执行原理,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

 

核心类在

org.apache.hadoop.hdfs.server.balancer.Balancer

 

均衡算法 伪代码

while(true) {1.获取需要迁移的字节数if(需要迁移字节数 == 0) {return "成功,无需迁移";}2.选择需要迁移的节点if(需要移动的数据 == 0) {return "没有需要移动的块"}3.开始并行迁移4.清空列表5.Thread.sleep(2*conf.getLong("dfs.heartbeat.interval", 3));
}

 

获取所有的data node节点,计算

initNodes(client.getDatanodeReport(DatanodeReportType.LIVE));

initNodes()函数如下:

计算平均使用量long totalCapacity=0L, totalUsedSpace=0L;for (DatanodeInfo datanode : datanodes) {if (datanode.isDecommissioned() || datanode.isDecommissionInProgress()) {continue; // ignore decommissioning or decommissioned nodes}totalCapacity += datanode.getCapacity();totalUsedSpace += datanode.getDfsUsed();}

 

当前集群的平均使用率(是当前使用的空间/总空间*100),注意这个是百分比计算后再乘100的值,不是百分比

this.avgUtilization = ((double)totalUsedSpace)/totalCapacity*100;

 

 

四个队列

1.aboveAvgUtilizedDatanodes(超过集群平均使用率 && 低于集群平均使用率+阀值)

2.overUtilizedDatanodes(超过集群平均使用率+阀值)

3.belowAvgUtilizedDatanodes(低于集群平均使用率 && 超过集群平均使用率-阀值)

4.underUtilizedDatanodes(低于集群平均使用率-阀值)

 

2个参数

overLoadedBytes 超过负载值的字节

underLoadedBytes低于负载值的字节

//注意这里的阈值默认是10D,这里不是百分比计算集群平均使用率如果为0.5不是50%,而相当于0.5%
//所以如果是0.5-10D就变成负数了,一般来说肯定是小于当前节点使用率的,除非当前节点使用率特别大
//比如当前节点使用率为20,则用百分比来说就是使用了20%,这肯定就超于阈值了,于是这个节点的数据
//就需要均衡了
for (DatanodeInfo datanode : datanodes) {if(当前节点使用率 > 集群平均使用率) {if(当前节点使用率 <=(集群平均使用率+阀值) && 当前节点使用率 > 集群平均使用率) {创建一个BalancerDatanodeaboveAvgUtilizedDatanodes.save(当前节点)}else {overUtilizedDatanodes.save(当前节点)overLoadedBytes += (当前节点使用率-集群平均使用率-阀值)*当前节点总数据量/100}}else {创建一个BalancerDatanodeif(当前节点使用率>=(集群平均使用率-阀值) && 当前节点使用率<集群平均使用率) {belowAvgUtilizedDatanodes.save(当前节点)}else {underUtilizedDatanodes.save(当前节点)underLoadedBytes += (集群平均使用率-阀值-当前节点使用率)*当前节点总数据量/100}}
}均衡器只会执行 overUtilizedDatanodes 和 underUtilizedDatanodes队列中的集群

 

 

BalancerDatanode()构造函数

if(当前节点使用率 >= 集群平均使用率+阀值 || 当前节点使用率 <= 集群平均使用率-阀值) {一次移动的数据量 = 阀值*当前节点总容量/100
}
else {一次移动的数据量 = (集群平均使用率-当前节点使用率) * 当前节点总容量/100
}
一次移动的数据量 = min(当前节点剩余使用量,一次移动的数据量)
一次移动的数据量 = (一次移动数据量上限10G,一次移动的数据量)

 

chooseNodes()函数


chooseNodes(true);	 //首先在相同机架中迁移
chooseNodes(false);	 //在不同机架中迁移chooseNodes(boolean onRack) {chooseTargets(underUtilizedDatanodes.iterator(), onRack);chooseTargets(belowAvgUtilizedDatanodes.iterator(), onRack);chooseSources(aboveAvgUtilizedDatanodes.iterator(), onRack);
}chooseTargets() {for(源节点 source : overUtilizedDatanodes列表) {选择目标节点(source)}
}选择目标节点(source) {while() {1.从候选队列中找到一个节点2.如果这个可转移的数据已经满了continue3.if(在相同机架中转移)4.if(在不同机架中转移)5.创建NodeTask}
}//和chooseTargets函数类似
chooseSources() {for(目标节点 target : underUtilizedDatanodes) {选择源节点()}
}选择源节点(target) {while() {1.从候选队列中找到一个节点2.如果这个节点可转移的数据已经满了continue3.if(在相同机架中转移)4.if(在不同机架中转移)5.创建NodeTask}
}控制台或者日志上会显示  Decided to move 3.55 GB bytes from source_host:50010 to target_host:50010

 

开始并行迁移数据

    for (Source source : sources) {futures[i++] = dispatcherExecutor.submit(source.new ());}

 

BlockMoveDispatcher线程

1.选择要迁移的节点 chooseNextBlockToMove()
2.if(要迁移的节点 != null) {//启动数据迁移,创建一个新线程发送接收数据scheduleBlockMove()}
3.获取block列表,继续下一轮迁移

 

发送和接收数据块的dispatch()函数

//使用阻塞IO的方式发送数据并接收返回的结果sock.connect(NetUtils.createSocketAddr(target.datanode.getName()), HdfsConstants.READ_TIMEOUT);sock.setKeepAlive(true);out = new DataOutputStream( new BufferedOutputStream(sock.getOutputStream(), FSConstants.BUFFER_SIZE));sendRequest(out);in = new DataInputStream( new BufferedInputStream(sock.getInputStream(), FSConstants.BUFFER_SIZE));receiveResponse(in);bytesMoved.inc(block.getNumBytes());

 

这篇关于Hadoop-balancer执行原理的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1133451

相关文章

Spring Boot Interceptor的原理、配置、顺序控制及与Filter的关键区别对比分析

《SpringBootInterceptor的原理、配置、顺序控制及与Filter的关键区别对比分析》本文主要介绍了SpringBoot中的拦截器(Interceptor)及其与过滤器(Filt... 目录前言一、核心功能二、拦截器的实现2.1 定义自定义拦截器2.2 注册拦截器三、多拦截器的执行顺序四、过

Java 队列Queue从原理到实战指南

《Java队列Queue从原理到实战指南》本文介绍了Java中队列(Queue)的底层实现、常见方法及其区别,通过LinkedList和ArrayDeque的实现,以及循环队列的概念,展示了如何高效... 目录一、队列的认识队列的底层与集合框架常见的队列方法插入元素方法对比(add和offer)移除元素方法

SQL 注入攻击(SQL Injection)原理、利用方式与防御策略深度解析

《SQL注入攻击(SQLInjection)原理、利用方式与防御策略深度解析》本文将从SQL注入的基本原理、攻击方式、常见利用手法,到企业级防御方案进行全面讲解,以帮助开发者和安全人员更系统地理解... 目录一、前言二、SQL 注入攻击的基本概念三、SQL 注入常见类型分析1. 基于错误回显的注入(Erro

Spring IOC核心原理详解与运用实战教程

《SpringIOC核心原理详解与运用实战教程》本文详细解析了SpringIOC容器的核心原理,包括BeanFactory体系、依赖注入机制、循环依赖解决和三级缓存机制,同时,介绍了SpringBo... 目录1. Spring IOC核心原理深度解析1.1 BeanFactory体系与内部结构1.1.1

MySQL 批量插入的原理和实战方法(快速提升大数据导入效率)

《MySQL批量插入的原理和实战方法(快速提升大数据导入效率)》在日常开发中,我们经常需要将大量数据批量插入到MySQL数据库中,本文将介绍批量插入的原理、实现方法,并结合Python和PyMySQ... 目录一、批量插入的优势二、mysql 表的创建示例三、python 实现批量插入1. 安装 PyMyS

深入理解Redis线程模型的原理及使用

《深入理解Redis线程模型的原理及使用》Redis的线程模型整体还是多线程的,只是后台执行指令的核心线程是单线程的,整个线程模型可以理解为还是以单线程为主,基于这种单线程为主的线程模型,不同客户端的... 目录1 Redis是单线程www.chinasem.cn还是多线程2 Redis如何保证指令原子性2.

MyBatis Plus中执行原生SQL语句方法常见方案

《MyBatisPlus中执行原生SQL语句方法常见方案》MyBatisPlus提供了多种执行原生SQL语句的方法,包括使用SqlRunner工具类、@Select注解和XML映射文件,每种方法都有... 目录 如何使用这些方法1. 使用 SqlRunner 工具类2. 使用 @Select 注解3. 使用

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的