集群版本:HDP3.1.5
Hadoop版本:Hadoop3.1.1
一、前置知识
大家都知道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
读互斥的缺点,所以说 ReentrantReadWriteLock
比synchronized
快,这也是hadoop3.x版本中对锁进行优化原因。
二、事发背景
考虑成本问题公司今年迁移到新集群,由原来的cdh5.13和hdp2.6两个集群(都是hadoop2.x)迁移到HDP3.1.5,最后一个开源版本,打包的组件版本都比较新,众多新特性等待发掘,不至于技术基础上落后。迁移之初,业务并没有从其余两个集群完全迁移过来,迁移过来的业务也并没有对外服务,考虑到中间磨合过程。俗话说小病重启,大