Hadoop3.x中一把锁毁灭的大数据集群

2024-09-03 11:38

本文主要是介绍Hadoop3.x中一把锁毁灭的大数据集群,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

集群版本:HDP3.1.5

Hadoop版本:Hadoop3.1.1

源码地址:https://github.com/hortonworks/hadoop-release/tree/HDP-3.1.5.152-1-tag

一、前置知识

​ 大家都知道hadoop的核心组件是HDFS和YARN,HDFS负责存储,YARN负责计算资源管理,今天要重点扯一扯YARN。YARN的架构跟众多分布式架构一样是主从式,为了维护可靠性,ResourceManager(RM)支持High Available(HA)功能。在所有人的认知中,只要是主从架构,挂了一个slave节点或master节点,框架内部的容错机制都会保证整个系统的正常运行,加上下游的计算应用的重试机制,甚至对用户无感知。貌似所有人都关心一种情况,就是某个或者某种类型的节点挂掉,但是,还有没有其它情况呢?非死即生?不,还有一种叫stop the world生不如死,类似jvm的gc,这也是java生态框架最头疼问题之一。当然,今天要讲的不是gc,而是另一种情况下的java进程stop the world导致的严重问题——锁。

为什么需要锁

RM作为资源管理服务,必然要维护存储资源的信息,最简单的,比如Container被客户端申请分配,多线程的情况下,要保证Container数值的准确性,多线程下客户端要申请资源,会对数值进行更改,避免可能会出现数据不一致的问题,因此对此类资源的操作必须要加锁。在RM相关的代码中,有大量的加锁操作,在hadoop2.x中,RM对资源操作的锁都是最原始的syncrinized锁,而在hadoop3.x中,社区考虑到性能问题,把syncrinized锁全部换成了ReentrantReadWriteLock锁。

ReentrantReadWriteLock

ReentrantReadWriteLock可以多个Thread可以同时进行读取操作,但是同一时刻只允许一个Thread进行写入操作,而synchronized 不论读写,只要线程进入synchronized代码就互斥,所以,会出现一个线程读另一个线程不能进入的现像。ReentrantReadWriteLock里其实是加了两把锁,写锁排斥读、写,读锁只排斥 写,所以能达到并发读的效果,克服了synchronized 读互斥的缺点,所以说 ReentrantReadWriteLocksynchronized 快,这也是hadoop3.x版本中对锁进行优化原因。

二、事发背景

​ 考虑成本问题公司今年迁移到新集群,由原来的cdh5.13和hdp2.6两个集群(都是hadoop2.x)迁移到HDP3.1.5,最后一个开源版本,打包的组件版本都比较新,众多新特性等待发掘,不至于技术基础上落后。迁移之初,业务并没有从其余两个集群完全迁移过来,迁移过来的业务也并没有对外服务,考虑到中间磨合过程。俗话说小病重启,大病重装,某一天,突然发现所有任务都提交不到yarn上去,正在运行的任务也无法结束,但是yarn的8088 web ui能够正常打开。看RM的log也没看到任何报错信息,于是直接重启RM,一切恢复正常。我大意了啊,没有进一步排查,这好吗?这不好。之后的一段时间里,貌似平静许多,后面才知道,同样的情况原来越来越频繁,运维小哥哥每天凌晨偷偷起来重启RM保障集群稳定,传说中的人肉运维。随着集群迁移的完成,所有业务正式上线,每天在yarn上跑的任务越来越多,好几万个实例。然鹅RM出现这种情况的频率从一周一次变成几个小时一次,啪的一下又hang住了,挂掉还好,会主备切换,但是hang住后zkfc并不会判断active节点不可用,所以不会切换,几百上千个任务卡住无法运行,严重影响业务,导致集群完全不可用!!濒临奔溃边缘!看样子Hadoop3.X显然是有bear而来不讲武德!

三、问题分析

  • 分析日志

    出问题,第一时间看日志,我们分析了每一次出问题时候的RM日志,基本的现象是,RM hang住前,控制container生命周期的打印的log越来越少,比如申请、分配、完成、释放等等,等到hang住后,这些日志完全没打印了,也没有任何报错信息,没结果。

  • 分析监控

    接着我们把RM的所有监控metrics都看了个遍,包括rpc、gc、cpu、内存、网络、资源分配等等,包含了RM大部分常用的指标和RM所在服务器的指标,大概上百个,我们分析出问题的那一刻指标的异动情况,中间只要有个别指标的异常,都刨根问底的查到低,最后也没查出个所以然。

  • 分析任务

    为了找出RM hang住的原因,无所不用其极啊,甚至有人把调度任务跟出事的时间点扯上关系,看是不是某些在yarn上跑的特殊的任务导致RM处理问题,在之前hadoop2.x中跑任务从来没出过这样的问题。然鹅,还是没有结果。

  • 分析现象

    每次出问题的时候,RM的webui能够正常打开,但是有个地方一直不会跳转,如下图:

    yarn web ui

    终于有了突破口,这个问题跟Scheduler有关!

  • 线程堆栈分析

    一般非jvm gc导致的进程卡死的问题,都是线程问题。查了一圈关于死锁问题分析的资料,可参阅:https://blog.csdn.net/liwenxia626/article/details/80791704。我把正常状态下和非正常住状态下的RM的jvm线程堆栈日志dump出来,执行

    jstack <RM PID> > rm.stack
    

    毕竟是头一回正儿八经的在生产上分析jvm的堆栈,事先也补了大量的课,前面所有的分析步骤都像无头苍蝇乱打乱撞,对比两个日志,虽然没有明显的dead lock字眼,但是有了重大发现,看到了曙光,非正常日志下:

    rm stack

    RM内部有线程在等待某个锁的释放,但是一直没释放!根据上面的信息,可以知道是由于org.apache.hadoop.yarn.server.resourcemanager.scheduler.capacity.LeafQueue#completedContainer里面有写锁的操作,有写锁必然会有释放锁,但是根据上面的线程堆栈日志,显然是有进程在等待它释放锁,但是它没有进入finally释放锁,而另一个进程一直在等待它释放,于是出现了死锁!!

   public void completedContainer(Resource clusterResource, FiCaSchedulerApp application, FiCaSchedulerNode node, RMContainer rmContainer, ContainerStatus containerStatus, RMContainerEventType event, CSQueue childQueue,boolean sortQueues) {// Careful! Locking order is important!try {// 获取锁  writeLock.lock();// 中间逻辑略} finally {// 释放锁  writeLock.unlock();}}

除了上面日志的WriteLock.lock(),堆栈日志中同样有ReadLock.lock()

readlock

根据堆栈日志锁出现的地方,均在Scheduler相关的类方法,org.apache.hadoop.yarn.server.resourcemanager.scheduler.*下存放的是RM资源调度相关的类,有我们熟知的FIFO、Fair、 CapacityScheduler。本集群使用CapacityScheduler,CS调度下每个队列内默认FIFO。这也解释了上面点击web ui只有Scheduler那一栏卡住不动,可以肯定的是点击前端页面有后端方法进入了scheduler包下相关的类方法。

四、定位问题

上面就定位到根本问题了么?只知道是锁的问题,但不知道为何会导致死锁问题。翻了yarn的源码所有锁的操作都没问题,找不到任何毛病,此时又进入无头苍蝇模式,病急乱投医之下疯狂的调yarn参数,最后还是没有任何作用。在社区jira上疯狂的提问,YARN-10440 , YARN-10482 , YARN-10483。最后都没得到想要的结果。估计现在没有多少大公司在生产环境使用hadoop3.X,99%还停留在2.x的时代。花了很长时间排查hadoop源码的锁这一块,最终还是没头绪。自己解决不了的还不能找人帮忙么?最后,所幸想起参加过开源社区的线下meetup加了一位京东yarn开发组大佬,同时也是hadoop的commitor,在这里要感谢他抽时间帮我看这个问题,最后确定了这是一个jdk1.8的bug引起的,而不是hadoop的bug,详情参考bug地址:https://bugs.openjdk.java.net/browse/JDK-8134855,ReentrantReadWriteLock在某些情况下会导致解锁失败,进而导致死锁问题,这个bug在jdk9及以上版本中已修复。

五、解决方案

由于现在大部分公司都使用jdk1.8,已经找到了根本原因是jdk的bug,这下就有了正确的解决方向

更换jdk

我们集群使用的是oracle jdk1.8,jdk9由于社区不再维护,不知道更换后有没有其它会不会有其它问题,考虑风险就直接放弃了。

于是直接更换到jdk11,但是发现更换后RM根本起不来,仔细一查,原来hadoop3还不支持jdk11的runtime,此路不通,也放弃了。

修改yarn的锁

没法解决的bug,只能想办法避开,亦是另一种解决方式,参考hadoop2.x的源码,CapacityScheduler相关的类几乎都使用的synchronized锁,于是 ,我参考Hadoop2.7的源码,把当前Hadoop3.1.1的ReentrantReadWriteLock全部改回synchronized锁,这样虽然性能会有些损失,对于没达到一定量级的公司来说,可以忽略不计。

patch已提交到 YARN-10482

也可以参考本人单独维护的hadoop3.1.1完整提交记录:https://github.com/lijufeng2016/HDP-hadoop3.1.1/tree/yarn-capacity-hotfix-20201104,
或者同样是HDP3.1.5版本的hadoop3.1.1可以直接使用编译好的jar包:hadoop-yarn-server-resourcemanager-3.1.1.3.1.5.0-152.jar

最后,集群终于稳定!

六、小结

这是从业以来解决的跨度时间最大的一个问题,从最初出现,到彻底解决,中间跨度3-4个月,其中花了整整一周时间集中排查解决这个问题,中间排查解决的过程远不止上面描述的这个简单。引入新技术框架,出现问题,要接的住,化解的了,最后发到社区给同样遇到问题的人,不会接化发,年轻人不要轻易在生产环境使用过新的技术,不然碰到棘手问题,耗子尾汁。

这篇关于Hadoop3.x中一把锁毁灭的大数据集群的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



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

相关文章

SQL Server修改数据库名及物理数据文件名操作步骤

《SQLServer修改数据库名及物理数据文件名操作步骤》在SQLServer中重命名数据库是一个常见的操作,但需要确保用户具有足够的权限来执行此操作,:本文主要介绍SQLServer修改数据... 目录一、背景介绍二、操作步骤2.1 设置为单用户模式(断开连接)2.2 修改数据库名称2.3 查找逻辑文件名

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

使用SpringBoot整合Sharding Sphere实现数据脱敏的示例

《使用SpringBoot整合ShardingSphere实现数据脱敏的示例》ApacheShardingSphere数据脱敏模块,通过SQL拦截与改写实现敏感信息加密存储,解决手动处理繁琐及系统改... 目录痛点一:痛点二:脱敏配置Quick Start——Spring 显示配置:1.引入依赖2.创建脱敏

详解如何使用Python构建从数据到文档的自动化工作流

《详解如何使用Python构建从数据到文档的自动化工作流》这篇文章将通过真实工作场景拆解,为大家展示如何用Python构建自动化工作流,让工具代替人力完成这些数字苦力活,感兴趣的小伙伴可以跟随小编一起... 目录一、Excel处理:从数据搬运工到智能分析师二、PDF处理:文档工厂的智能生产线三、邮件自动化:

Python数据分析与可视化的全面指南(从数据清洗到图表呈现)

《Python数据分析与可视化的全面指南(从数据清洗到图表呈现)》Python是数据分析与可视化领域中最受欢迎的编程语言之一,凭借其丰富的库和工具,Python能够帮助我们快速处理、分析数据并生成高质... 目录一、数据采集与初步探索二、数据清洗的七种武器1. 缺失值处理策略2. 异常值检测与修正3. 数据

pandas实现数据concat拼接的示例代码

《pandas实现数据concat拼接的示例代码》pandas.concat用于合并DataFrame或Series,本文主要介绍了pandas实现数据concat拼接的示例代码,具有一定的参考价值,... 目录语法示例:使用pandas.concat合并数据默认的concat:参数axis=0,join=

C#代码实现解析WTGPS和BD数据

《C#代码实现解析WTGPS和BD数据》在现代的导航与定位应用中,准确解析GPS和北斗(BD)等卫星定位数据至关重要,本文将使用C#语言实现解析WTGPS和BD数据,需要的可以了解下... 目录一、代码结构概览1. 核心解析方法2. 位置信息解析3. 经纬度转换方法4. 日期和时间戳解析5. 辅助方法二、L

使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)

《使用Python和Matplotlib实现可视化字体轮廓(从路径数据到矢量图形)》字体设计和矢量图形处理是编程中一个有趣且实用的领域,通过Python的matplotlib库,我们可以轻松将字体轮廓... 目录背景知识字体轮廓的表示实现步骤1. 安装依赖库2. 准备数据3. 解析路径指令4. 绘制图形关键

解决mysql插入数据锁等待超时报错:Lock wait timeout exceeded;try restarting transaction

《解决mysql插入数据锁等待超时报错:Lockwaittimeoutexceeded;tryrestartingtransaction》:本文主要介绍解决mysql插入数据锁等待超时报... 目录报错信息解决办法1、数据库中执行如下sql2、再到 INNODB_TRX 事务表中查看总结报错信息Lock

使用C#删除Excel表格中的重复行数据的代码详解

《使用C#删除Excel表格中的重复行数据的代码详解》重复行是指在Excel表格中完全相同的多行数据,删除这些重复行至关重要,因为它们不仅会干扰数据分析,还可能导致错误的决策和结论,所以本文给大家介绍... 目录简介使用工具C# 删除Excel工作表中的重复行语法工作原理实现代码C# 删除指定Excel单元