之前一直讲存储层,大家都知道计算机三层架构分为: cpu / 内存 / 硬盘。

前几篇都是在讲存储层数据治理,讲如何控制硬盘里的数据量。集群不要失控啦,不要被新增业务线数据撑爆啦,要分清楚哪些是冷数据,哪些是小文件啦。总之都是围绕着“硬盘”。

今天就来侃侃 hadoop 集群的 cpu & 内存管理。

PS: 本文的tool和可视化图表都是由 

@ArancioneRagazz

 同学在hulu实习期间开发的,感谢她出色&辛苦的工作。


  

郑州最好的妇科医院

   

Agenda

  1. history 谈谈yarn的历史,由来

  2. yarn相同的领域,还有哪些产品

  3. yarn的设计,多租户,队列/标签

  4. real world里,yarn的问题

  5. 数据驱动的yarn管理,资源治理

  6. 分析规律,反哺线上,做出改变

  7. 总结


1. 谈谈yarn的历史,由来

当下hadoop稳定在了2.x.x版本,3.x版本也基本production stable了,虽然敢用的公司很少。(2.x 也很难升级到3.x, no-downtime upgrade又是另一个高大上的话题了,在hadoop 2.x后,都是用 YARN (Apache Hadoop YARN )来管理集群的计算资源。

随着互联网的发展,互联网公司的业务越来越复杂,早在10年钱,一个普通的小网站有个50台机器,能有20个web服务器20个数据库,公司内有10来个应用系统,也就差不多了。但是像google,bat这种巨无霸,很早就面临了大规模集群的管理问题,且问题越来越大。看看现在的bat,有多少业务线,内部有多少it系统在不停歇的运转。倘若每个应用的开发者,都自己维护自己的物理机,那这些机器出问题后,每个开发者的维护成本简直无法估量。即使有专业的运维团队,把每个应用部署在哪台机器,哪台机器坏了,把应用迁移到另外的机器,这些问题都是很棘手的。慢慢的为了自动化,让运维人更自由,业界也就产生了“分布式操作系统”。单台操作系统管理本机的cpu,内存。“分布式操作系统”就管理整个集群成千上外台机器的cpu,内存,甚至网络。你的应用被提交到“分布式操作系统”后,一定会跑成功,即使运行你应用的节点发生故障,“分布式操作系统”也会自动在另外的节点,重试。

这一段我稍待讲讲,不说太多,因为不是hadoop系列的point,我的point是怎么能更好的运维好hadoop/yarn。因此懂yarn的人自然懂,不懂yarn的朋友,可以顺着看看第二章我介绍的产品,读一读“分布式操作系统”的业界产品的wiki,或者我推荐的论文。


2. yarn相同的领域,还有哪些产品

资源管理领域:

  • google先有了borg(论文) ,后又开源了 Kubernetes.(Wiki)

  • hadoop系有了yarn

  • twitter开源了Mesos

可谓百花齐放。

因为hadoop的特点,以及历史原因,hadoop集群的资源管控,发展到了yarn这套系统,可以说yarn是专门跑hadoop系应用的,即 mapreduce/spark等等计算作业。有人说yarn上面能否跑一些别的项目应用啊? 答案当然是可以。

用户需要自己编写一个on yarn的程序,写自己的application-master (Hadoop: Writing YARN Applications ),自己写资源申请模块等等。

我这里也找了一些开源届的人尝试写的on-yarn应用:

1.Docker on YARN

2.Presto YARN Integration

3.prestodb/presto-yarn

4.Introducing Hoya - HBase on YARN - Hortonworks

但是我相信,在实际的应用场景中,大多数规模以上公司,hadoop集群光跑mapreduce/spark的job,集群资源就基本耗尽了,所以other on-yarn application,也不在本文的讨论范畴内。这一篇只讨论竞争激烈的真正跑满了hadoop application的 hadoop yarn cluster。


3. yarn的设计,多租户,并行app,队列/标签

3.1 yarn设计的最大初衷,是多租户,并行app。

在早版本hadoop 0.x.x时期,hadoop job是提交给jobtracker的,mapreduce作业的mapper和reducer任务会跑在tasktracker上。整个集群其实是一个first-in-first-out的调度队列。每个app都在排队跑,当一个app占不满集群的资源,整个集群的空闲计算资源就浪费在那里了。

到了yarn时期,hadoop终于可以允许多个app同时跑,按自己的需求共享集群资源。这使得集群的资源利用率得到了大幅度的提升。这也解决了大数据底层的大规模集群空置问题,可谓业界向大数据落地的一次大前进。

下图列出了yarn的一些主要的特点:


v2-3ee9e97d066e24d976c375296d64a669_hd.jpgyarn 优点


3.2 队列/标签

3.2.1 队列

在当下稳定的hadoop版本下,资源的调度,都是基于队列的。

v2-9359423a4580bf5e5f495e551d3add83_hd.jpg队列-标签的映射关系

在一个公司里,不同的team,可以按需求把作业提交到不同的队列里。 这就好比,银行的门店,可以办理不同的业务。不同的业务会分散不同的窗口(queue)。根据业务强度,银行会给不同的窗口分配不同的人(机器),有的窗口分配能力强的人(多cpu),甚至开多个窗口(子队列),有的子队列只服务“军人”/“老人” (sub-queue)。有的窗口分配普通员工。

yarn的主流调度器 Hadoop: Fair Scheduler & Hadoop: Capacity Scheduler 都是基于队列设计的。对这一块没了解的朋友,可以点击上面scheduler链接,读读官网的原版wiki.

CapacityScheduler

v2-bf003435d26542929a4f0788f5755056_hd.jpg

FairScheduler

v2-3a98158deb28af2655f0d45b0d6712cf_hd.jpg

本文的重点第5部分,就会提到基于queue history data 分析。

本文不对这两种调度器的对比做过多的评价,这里提供一些讲调度器的文章:

  1. Cloudera Community : Cloudera’s Fair Scheduler vs. Capacity Scheduler, which one is the best option to choose?

  2. [StackOverflow]: What is the difference between the fair and capacity schedulers?


3.2.2 标签

Node label (YARN Node Labels )是一个为了给相同特点的集群机器分组的解决方案,说直白点,就是异构机器分组。这一波机器A,用来跑 map-reduce,另一波机器B,用来跑spark. 还有一部分机器C,用来跑ai/machine-learning job.

为什么会产生这种需求呢?

因为hadoop技术栈已经产生了很多年了,在公司集群中,有的机器是3年5年前买的,有的是近1年买的。那么随着时间的推移,集群中的机器配置必然会是异构性。一般来讲,都会用老的机器跑一些“实时性不是很重要”的batch job,而让一些新一些的机器,跑一些需要快速处理的"spark/ streaming" 甚至olap的计算任务。而这种分组,就是使用yarn node label功能做到的。

这里有几篇讲nodelabel的很好的文章:

1.slideshare.net/Hadoop_S

2.YARN Node Labels: Label-based scheduling and resource isolation - Hadoop Dev

3.Node labels configuration on Yarn


总之,hadoop的admin可以把一个或多个label关联到queue上。一个hadoop application只能使用一个queue下面的一种label.

例子:

  • 提交mr作业到label X:

提交mr作业到Xlabel:
yarn jar /usr/iop/<iopversion>/hadoop-mapreduce/hadoop-mapreduce-examples.jar
  wordcount -D mapreduce.map.node-label-expression="X" /tmp/source /tmp/result


  • 提交spark作业到label Y:

./bin/spark-submit --class org.apache.spark.examples.SparkPi
  --master yarn --deploy-mode cluster --driver-memory 3g --executor-memory 2g
  --conf spark.yarn.am.nodeLabelExpression=Y
  --conf spark.yarn.executor.nodeLabelExpression=Y jars/spark-examples.jar 10


v2-a532106eb4082840b01238c588376e7f_hd.jpgyarn queue label

Tip! YARN node-labels 功能在Apache Hadoop 2.6被开发出来,但并没有被merge到官方版本中,只能通过打patch的方式使用. 是有很多bug的,官方推荐 hadoop 2.8.x 之后在使用,fix了很多bug,而事实上在Apache Hadoop 2.7.3 版本的官方主业里,nodelabel功能被正式介绍出来。

我司使用的是CDH-5.7.3,即cloudera公司发行的hadoop版本,底下是Apache hadoop 2.6.0. 对hadoop部署版本感兴趣的朋友,请看《大数据SRE的总结(1)--部署》。 我们就踩坑了, cloudera 把node-label的feature打入了,但很多bug并没有fix。我在下一小节会着重讲。


最后,yarn发展到了,多queue 多租户,以及成熟的label管理。已经到了一个相对完备的功能阶段。下面,我讲讲我自己在运维yarn的工作时碰到的各种问题。



4.real world里,yarn的问题


4.1 用户问题

YARN resources are always complained insufficiently by big-data users.

在我们公司,big data infrastructure team,是有一个内网的聊天channel的。hadoop user总是会来这里抱怨,抱怨他们的job今天跑的慢了,pending太久了,为什么还拿不到资源等等。

我们分析了产生问题的原因Reason (R) 。总结出来有一下几种:


R1.资源分配问题。

  • 给某些队列划分了过多的资源,导致某些队列的job卡住很久,队列资源使用率达到100%时,另一个队列的资源使用还不到50%. 比如下图,streaming队列明显快满了,olap队列还使用了不到1/4.

v2-2a061621e9cef17d334200af5124a9ce_hd.jpg


R2.应用程序滥用问题。

先给大家show几个图,第一个图是一个app,经过分析,他申请了32GB的内存,而统计后平均使用的内存是514MB ! what ! 作为管理员,看到这种用户,是不是想骂街。。

v2-2f22050d48e7eadf617e83e6b98e537f_hd.jpg

第二个是app申请的资源,这一个app申请了740个cpu,3000GB的总内存,这类app很多。这种app我认为调优的空间都很大。一个mapper/reducer能优化30%的内存占用量,总体看就是一个很客观的数字。

v2-fd9593fd2bb5ef8e121016fc9c45507c_hd.jpg


4.2 yarn的管理员问题

1.我们怎么才能知道队列的资源使用长期情况呢? 拿什么数据来作为调整yarn队列queue级别资源的依据呢?

2.每次在新加入了一批机器后,我们当然要给机器打label,yarn的shell cmd中,打label:

yarn rmadmin -replaceLabelsOnNode “node1[:port]=label1 node2=label2

如果一次加入100台机器,打label去输入这么多命令,很容易出问题。怎么能又快速又安全的搞定这个工作呢?

3.用户在channel不停的问application的问题,有什么办法能减少admin人工回复用户的工作,让用户自助解决问题?


4.3 node-label问题

然后在上一节,我提到我司使用的hadoop版本是基于apache hadoop 2.6.0,在node-label这里有bug。

Bug1.缺乏 node-label 资源显示。

v2-d52272bcb0cea77ec456cfc675f8a099_hd.jpgcdh-5.7.3-hadoop-2.6.0的yarn ui

而稳定版本,是可以显示出哪种label,有多少机器,有多少memory和cpu资源的。

v2-07f4cf86f9abd8a6963ed368b8fbf7c6_hd.jpgnode-label 稳定版本 hadoop 2.8.x

Bug2. yarn shell 功能不全。甚至不能使用list all labels功能。

v2-66fcc056dd4e739efa86e46e50acdf4a_hd.jpg



Bug3. yarn ui没有分label去显示queue的资源使用率。

v2-a1ce6aebe3c397cf1ebad3ddf4300c16_hd.jpg非稳定版v2-48f91fccd00e8d5ce54814c851245da2_hd.jpg稳定版



5. 数据驱动的yarn管理,资源治理

为了解决上一节提出来的种种问题,我们做了很多自动化的工具。

  • 我们用搜集“时间序列”的数据,来评估队列的使用情况

  • 用ui tool 来加快运维操作的批量性/安全性

  • 用更简洁明了的图表,来给用户展示他能得到的资源

等等。


5.1 yarn资源调配

为了解决yarn queue资源调配的公平。我们制作了yarn queue level 的 capacity 占比history 趋势图。

总揽图:所有子队列的历史资源使用都在这里,可以看出哪个队列长期超负荷运转,哪些queue长期用不满资源。总揽图主要用来做对比,发现有问题的queue。

  • 超负荷queue (长期capacity使用量都在100%以上的。配置了过高的max-capacity)

  • 低负荷queue (长期capacity使用量低于50%的 )

v2-20fc360648af1364a98d88f6cc038f10_hd.jpg


队列图:队列图是针对一个queue进行详细的分析用的。包括队列里使用哪种label的机器,队列有多少资源。队列资源的历史使用占比,超负荷占比,running/pending app历史,以及reserve 的container历史等等。

有了这两张图,在user对队列资源提出质疑时,我们admin会先让user自己看,是否本队列的使用量已经满了,以及是否队列已经在reserve container,让user心理有一个reasonable的预期。

v2-c403c74868696a53e91da512066805ca_hd.jpg


v2-407a77102daa7c8ca8f79c7f02d10806_hd.jpg


那么,一次yarn的queue 级别资源调配应该是这样的:

1.从“总揽图”找到长期“低负荷queue”和“超负荷的queue”。

2.把相对“低负荷queue”队列的资源,划归给“超负荷”的队列。

3.等一段时间,观察“总揽图”,看“超负荷”队列的资源使用情况是否变好,不是则重复1



5.2 yarn运维

在上一节,我们提到了给新加入集群的机器打label是个漫长的过程。没关系,本着在《大数据SRE的总结(0)--开篇 》提到的“让一切人对机器的操作尽可能的自动化”的原则。我们设计的给node批量打label的ui界面。可以按着ctrl健,然后点击鼠标来进行“多选”。这和window等操作系统的文件多选逻辑是相同的。最后选择一个label,点击完成按钮。

v2-bfafe5d0abb103af5ee72e9463f4cabf_hd.jpg


5.3 yarn queue 级别资源分配页面展示逻辑不友好

开源版本的yarn ui,样式很不说很多重要的信息展示的也不够透彻,比如:

  • yarn的queue资源分配到底占了资源的多少。

  • 缺失不同queue之间的资源对比

像这种文字类的ui,作为使用hadoop的数据团队user,是不够直观的。

v2-6980af1361c936f5e553d96bd812e032_hd.jpg

我们重绘了yarn 的queue level 资源分配。哪个queue分多少资源,一目了然。包括capacity和max-capacity的柱状图。

并且着重强调了node-label在划分资源里的重要性。

v2-afdfa76f1fe715fa47265137c12e5f9e_hd.jpgv2-68ad032ae5372e98a19bc743f00078b1_hd.jpg


5.4 解决用户自助排查问题。

这一块我们使用了linkedin开源的dr.elephant linkedin/dr-elephant.

这个工具提供了很多针对hadoop job的诊断/调优信息,可以帮助用户调优自己的hadoop job。我们也基于他做了很多二次开发,比如我们需要这样的功能:

  • 在某个“queue”下面,按“浪费”的内存数量倒排,分别罗列出所有浪费内存绝对数量/相对数量最多的 application。

这个工具的意义,就好比很多公司的“客服系统”。一些简单的问题,先让用户自行解决,包括查阅文档啊,语音机器人啊。当遇到实在很难解决的问题时,再进行人工介入。要知道,hadoop admin的人数在公司内是很少的,每个人的时间资源更是很宝贵的,不能陷入“运维陷阱”。



6 分析规律 反哺线上

如何调整yarn queue级别的资源分配,我们上一章已经做了简单的介绍。

至于实操,每个公司都不一样。但有一个通用的原则,即hadoop 运维团队可以按 月/季度,设定运维日。所有需要调整yarn资源的需求,都发给管理员,待管理员在 运维日统一调整。


另外一个比较有意思的地方是,观察yarn集群资源使用率历史走势,往往有的高峰期和低谷期。

高峰期,可能会让集群的使用率持续打满。 而低谷期,使用率往往又可能下降到50%甚至更低。通过我们绘制的集群使用率“总揽图”,以及队列的“队列图”。可以分别观察集群总体的规律,和每个队列的规律。


比如我们的yarn总体使用量走势,如下图所示:

v2-7b8466e3a0ef49719bea8e7b5d723138_hd.jpg

我们分析,yarn job的最大的来源,是来自于作业的调度,即调度系统!

我们可以看到。每一天的凌晨零点左右,资源使用率都会爬上去直到100%,而每一天的早上6点到下午3点,集群资源使用率都会下降,甚至下探到50%以下。

很多调度系统都是按天级别来调度作业的,允许用户配置类似cron语法的job。很多调度系统还提供了简单的daily选项(airflow daily),而这个选项就默认把作业的调度时间设置为了0点。这样在0点附近,大规模的作业被同时调度出去,互相挤占资源,大家都跑的慢。

我们会建议数据团队们,把不那么重要的job,更改其daily运行的小时点,“错峰”运行。

v2-9edddb9c53df1ef1bc385515b2acda0c_hd.jpgairflow 的 daily 调度默认为0点



总结

1. 用数据说话,让一切人的决策基于数据

2. 开发灵活方便的tool ,让一切人对机器的操作尽可能的自动化

3. 谨慎使用开源版本,尤其是非稳定的需要打patch的功能,做好踩坑填坑的准备