乐趣区

关于hadoop:数据库‖上千节点Hadoop集群升级过程分享

在上一次我进行了超万亿规模的Hadoop NameNode 问题的排查,通过为时四天的致力,终于解决了 Hadoop2.6.0 版本的瓶颈问题,然而生存往往就是墨菲定律,你所竭力防止的那些最坏的可能兴许终将会产生。

为了避免遇到 NameNode 的第二次瓶颈,我决定将以后集群由 Hadoop2.6.0 版本升级到 Hadoop3.2.1 版本,且启用联邦模式。然而在降级之后,咱们还是遇到了很多动向不到的问题,尽管最终通过一系列的排查还是解决了这些问题,然而我认为这次集群的降级教训可能帮忙一些同学少走弯路。

上面,enjoy:

一、降级前的筹备

在进行 Hadoop 集群降级,尤其是相似本次案例中这样上千节点的超大集群的降级,首先须要明确两点:

第一,是否的确有必要进行集群的降级,以目前的数据增长量级是否会涉及以后版本的瓶颈

首先须要申明一点,像本次案例中这样的超大规模的 Hadoop 集群,降级自身的难度就极大,须要耗费十分多的人力物力去批改数据库底层源码,仅仅对于咱们产品 LSQL 的源码批改就破费了咱们小组整整两周工夫。更无需说我下文中会列明的在降级后会遇到的一系列问题的排查和解决,更是须要投入极大的工夫精力。

本次咱们抉择进行 Hadoop 集群降级的次要起因是因为原先 2.6.0 版本过老,可能会存在其余未发现的问题。同时客户每天有近千亿条的数据增长,如不进行降级,很快还是会遇到 NameNode 的第二次瓶颈。如果客户在以后版本零碎可能稳固运行,并且将来的数据体量不会有大幅增长,咱们也不会采取降级集群的计划。

第二,是否做足了降级前的筹备工作,以及是否有应答降级呈现的各类问题的应急计划。

在本次降级前咱们就做了大量的后期筹备工作。咱们进行了屡次的降级演练,确保能应答在降级过程中呈现的各类突发状况。同时鉴于客户数十万亿的生产零碎的个性决定了在降级过程中决不能呈现失落数据或者服务长时间进行的状况。为此,咱们制订了一旦降级呈现问题就会采取的零碎回退计划,遭逢数据失落的挽回计划,以及在降级后的功能性验证等。

二、降级后所呈现的问题 & 解决

1.Hadoop 跨多个联邦后,速度不快反慢

实践上,Hadoop 升级成跨联邦机制,读写申请会别离平衡到三个不同的 NameNode 上,升高 NameNode 负载,晋升读写性能,然而事实是 NameNode 负载岂但没有升高,相同变得十分十分慢。

对于目前集群的卡顿水平,是必定无奈满足生产零碎的运行需要的。而此时降级曾经进行了三天了,如果卡顿问题不能失去解决,哪怕咱们心有不甘也只能立刻启动回退计划。然而毕竟咱们都为这次降级筹备了许久,而且客户也很期待降级后所带来的性能晋升,我微微抚了抚头顶那沉睡多年的毛囊,一狠心决定连夜奋战。

首先须要做的就是定位造成卡顿的起因,我先从堆栈动手,发现次要问题还是 NameNode 卡顿,生产零碎曾经不能持续考察上来了,如果不想回退零碎,就得让零碎可用,那就只能从咱们最相熟的中央下手 — 批改录信 LSQL,给所有申请 NameNode 文件的中央加上缓存,只有申请过的文件,就缓存下来,防止二次申请 NameNode。

录信 LSQL 批改后 NameNode 状态有十分大的改善,零碎根本可用。但具体为何降级到联邦后 NameNode 的吞吐量不升反降,咱们没能给出正当的解释,只能初步判定是因为历史数据还在一个联邦上,导致数据的散布不平衡,心愿之后能随着新数据的逐渐导入,从新造成一个较为平衡的态势。

2. 降级联邦后数据库稳定性升高,极易挂掉

在进行降级之后,咱们发现简直每隔几天咱们的数据库系统 LSQL 就会挂掉一次。

察看录信 LSQL 的宕机日志,发现有大量的如下输入,证实 Hadoop NameNode 常常位于 standby 模式,导致 Hadoop 服务整体不可用,从而引起录信 LSQL 数据库宕机。

进一步剖析 NameNode 发现 Hadoop 的 NameNode 并未宕机,active 与 standby 都活着。联合 Zookeeper 日志剖析发现,期间产生了 NameNode 的 activer 与 standby 的切换。

这里波及两个问题,一是为什么产生了主备切换,二是切换过程中是否会导致服务不可用。

针对主备切换的起因,通过比照切换产生的工夫,发现切换时 NameNode 做了比拟大的负载申请,如删除快照,或者业务进行了一些负载较大的查问。这很有可能是因为 NameNode 负载较高,导致的 Zookeeper 链接超时。具体为什么 NameNode 负载很高,这个咱们在前面论述。

至于切换过程中是否会导致服务不可用,咱们做了测试。第一次测试,间接通过 Hadoop 提供的切换命令切换,后果切换对服务没有影响。第二次测试,间接将其中的 Active NameNode 给 kill 掉,问题复现了。可见 在 Hadoop 3.2.1 版本里,active 与 standby 的切换,在切换过程中,是存在服务不可用的问题的。咱们针对报错地位进一步剖析如下:

看 RouterRpcClient 类的设计实现,应该是存在 failover 的逻辑。相干配置参数 key 值如下:

最终剖析 RouterRpcClient.java 这个类,发现其设计逻辑是有问题的,尽管预留了下面那些参数,但没有失效,NameNode 在主备切换过程中,存在两个 NameNode 同时处于 Standby 的过程。并且这个阶段,会间接报错,导致因报错而服务不可用。

咱们具体浏览了该类的实现,发现该类尽管预留了重试的逻辑,然而这些重试的逻辑并没失效,存在 BUG,故咱们对此进行了修复。修复后录信 LSQL 的宕机问题不再呈现,如下是波及源码的剖析过程:

如下是修复版本后,router 重试过程中记录的日志:

3. 数据库查问呈现间接性卡顿

Hadoop 降级到 3.2.1 版本后,录信 LSQL 会呈现间歇性的卡顿情景,导致业务查问页面总是在“转圈圈”。

到现场后第二天遇到了该景象,通过了一系列的排查和追踪,最终定位在 Hadoop 的 NameNode 卡顿(是不是很相熟的感觉,没错它又来了 ……)。具体体现在进行一次 ls 操作,会卡顿 20~30 秒的工夫。进入 NameNode 节点的机器察看负载状况,发现 CPU 的负载占用在 3000% 高低。

后通过屡次抓取 jstack,发现导致 NameNode 卡顿的堆栈的地位点如下:

没错,是 addBlock,也就是写数据的写锁会阻塞所有的查问。依照以往的教训,咱们认为是上图中的锁引起的,故咱们进行了去锁操作。

因为 NameNode 主备切换的问题曾经解决,所以咱们能够在生产零碎通过热切的形式来验证咱们的问题。去锁后的后果十分蹩脚,卡顿景象岂但没有缩小,相同变得更重大,整台 NameNode 的负载岂但没有升高,反而间接飙升到全满。

没方法,咱们只好持续排查起因,仔细分析该类的相干实现,最终发现如下问题:

联合下面的起因,咱们略微改了下代码实现。

经剖析发现每进行一次 addBlock 的申请,这里就会产生一次循环,这是一个机架上的所有机器。这意味着每调用一次 addBlock 办法,NameNode 就要对一个机架内的设施进行一次循环,集群设施上千台,就是循环上千次,那这 CPU 使用率还了得!之前加锁状态,因为有锁的限度,只是会导致写入慢,查问还算可用。当初把锁去掉了,罗唆 CPU 飚满,更是查不动了。而后 jstack 发现卡顿的中央变了,如下图所示:

咱们长期调整 NameNode 的日志级别,调整为 DEBUG 级别,看到了如下的输入,更是进一步的验证了咱们的想法。

同时咱们比照了下 Hadoop2.8.5 版本的源码,发现这个中央的逻辑在 Hadoop3.2.1 中做了较大的变更。存在设计不当的问题,这种循环形式会消耗很多 CPU。设计的本意是随机抽取节点,却要遍历一个机架下的所有节点,挨个加一遍锁。为了一次 addBlock,平白无故加了几百次锁,哪能这样设计呢?咱们仿照 2.8.5 的一些写法,从新修改了一下,针对这里的随机形式进行了从新革新。

改变结束后,再持续抓 jstack,解体的是,这块的逻辑的确抓不到了,但又在别的中央呈现了,一样有个相似的循环。具体看代码发现 Hadoop3.2.1 的这个类外面,这样的循环太多了,在生产零碎上改不起,也不敢改了。只能转变思路来解决,如果是因为这个循环的问题导致的 NameNode 卡顿,为何不是始终卡顿,而是间歇性卡顿,理分明这个思路,兴许就关上了一扇窗。

(1)SSD 机器的 Xreceiver 引发的血案

咱们剖析了循环里的 IP 列表(DataNode 的 IP),并且联合现场日志的设施,发现了一个法则,这些循环外面的 IP,均是 SSD 设施的 IP,并非是 SATA 设施的 IP。现场设施分为六组,每组一个机架,SATA 和 SSD 各占一半。从 IP 的法则上来看,这些 IP 均是 SSD 设施。进一步剖析,什么状况下这些 DN 会被退出到这个循环外面,从日志和源码剖析,咱们最终定位在 Exclude 上,也就是说 Hadoop 认为这些设施是坏了的,是应该被排除掉的设施。

难道是咱们的 SSD 设施全都宕机了,或者他们的网络有问题?但通过排查,咱们排除了这些问题。问题又回归到了源码层面,通过了大概 1 天的追踪定位,发现如下逻辑:

Hadoop 在抉择写入 DN 的时候,会思考到 DN 的负载状况,如果 DN 负载比拟高,它会将这个节点退出到 Execude 外面,从而排除掉这个节点,以此 判断一个 DN 负载高下的就是 Xreceiver 的链接数量。默认状况下,只有 Xreceiver 的链接数量超过了整个集群连贯数量的 2 倍,就会排除掉这个节点。而 LSQL 自身采纳了异构的个性,意味着咱们会优先从 SSD 盘读取数据,而 SSD 盘设施的性能好,数量又绝对较少,导致这些 SSD 设施的机器连接数远高于 SATA 盘的链接数。SATA 盘冷数据偏多,简直很少有人去查问。针对这一状况,就会呈现在一瞬间,因为连接数的问题,导致所有的或大多数的 SSD 设施被排除掉的情景。

咱们的 Hadoop 集群有一部分数据的写入是采纳 ONE_SSD 的模式,也就是一份数据存储在 SATA 设施上,另一份数据会存储在 SSD 设施上。而 Hadoop3.2.1 的个性,会随机在 SSD 设施里抽取一个节点,如果它没有在排除的 execlude 列表里,则会写入到这个设施里。而如果该设施被排除了,那么 Hadoop 就会再次尝试,再随机抽取其余节点,如此重复循环。然而咱们的 SSD 设施因为 Xreceiver 负载的关系,绝大多数或全副都被排除掉了,间接导致了一直的循环,甚至上百次,最终还有可能发现一个 SSD 设施都不可用。日志里会提醒 2 个正本 1 个 SATA 的写入胜利了,还短少一个正本没写胜利,如下图所示:

上述问题中,间接导致大数据集群的两个致命性问题为:第一,NameNode CPU 飚高,产生重大的间歇性卡顿;第二,SSD 设施间歇性的被排除掉,只写胜利了一个 SATA 正本,如果 SATA 设施忽然损坏一个盘,那么数据就会失落。

针对 SSD 的 Xreceiver 修复办法很简略,禁用该性能,或者调大倍数,如下图所示:

调整结束后,咱们非常明显的感触到了 NameNode 负载的降落,同时业务的所有查问,响应速度回归失常。

(2)机架调配策略不合理导致的同样问题

在咱们验证上述问题的过程中,尽管 NameNode 的负载显著降落,然而下面所说的循环状况仍然存在,查看 DEBUG 日志,令咱们十分诧异的是,这次循环的设施不是 SSD 设施,变成了 SATA 设施,这是什么状况?说不通啊。

还好,通过几天工夫研读 Hadoop 源码,初步理解了这部分逻辑,咱们关上 Hadoop 的 DEBUG 日志,察看到如下日志:

咱们发现,一个机架下容许写入的块数超了,而别的机架没有可用的存储策略写入时,就会呈现上述的循环。咱们看下,一个机架下容许写入多少个数据块,又是怎么决定的?如下图所示:

咱们分了 6 个机架,3 个 SATA,3 个 SSD,从日志看,咱们一个数据块要写入 24 个正本,这 24 个正本均要写入到 SATA 设施上。每个机架 Rack 上最多能够写入 5 个正本,3 个 SATA 机架能够写入 15 个,另外的 9 个写入失败。Hadoop3.2.1 在计算机架策略的时候并未思考到这种状况,另外的 SSD 设施无奈写入 SATA 存储策略的数据,导致了 Hadoop 在这种状况下将 SATA 设施循环几百遍,CPU 飙升。

因为后续的 9 个正本,始终没有中央写入,Hadoop 就会又像之前那样,将所有的 SATA 的设施循环上几百遍。这也会导致 CPU 的飙升。

咱们理论生产环境中,写入 24 个正本的状况是极少的,只存在更新的一些场景,因为带更新的数据,须要被每个节点读取(有点相似 Hadoop 的 DistirbuteCache),如果 2 正本,会造成个别 DataNode 的压力过大,故咱们增大了正本数。

这一状况也跟之前业务提出,只有一执行更新,就会显著感触到业务查问的卡顿的景象对应上。

针对这个问题,咱们认为应该 对机架调配策略进行调整,不容许独自的 SSD 与 SATA 在各自不同的机架上,一个机架上必须即有 SSD 设施,也要有 SATA 设施。这样这个问题就能够躲避了。但咱们放心一旦更改了此时的机架策略,会造成 Hadoop 的正本大量迁徙(为了满足新的机架策略的须要),咱们的集群规模太大了,咱们最终还是抉择了批改 NameNode 的源码。从源码层面解决这个问题,如下图所示:

三、总 结

总结一下,本次降级过程次要分享的知识点有两个:

第一,Hadoop Router 针对 NameNode 的 failover 没有进行重试解决,在主备切换期间,会产生服务报错,导致系统整体不可用;

第二,Hadoop addBlock 在 3.2.1 版本的设计思路上会因为机架策略的问题而进行循环解决,后果导致 CPU 占用过高,频繁加锁。

最初,本次 Hadoop 集群降级过程总体而言不算顺利,在降级之后也遇到了一些让咱们感到辣手的问题,在此咱们还是心愿同学们在筹备进行 Hadoop 集群降级,尤其是超大规模的集群降级时肯定要做好短缺的筹备,在发现降级后零碎无奈满足生产需要时也要有壮士断腕的勇气,及时进行零碎版本的回退。

PS:更多 hadoop 技术实际干货欢送在微信中关注公众号“录信数软”~

退出移动版