作者:蔡永承
大数据平台在唯品会近几年有了飞速发展,已经完成了从 0 到 1 的过程,各个部门逐渐将其引入到实际业务中。 "百尺竿头,更进一步",在业务压力和集群负载同步增加的情况下,如何实现平台优化是 2017 年的主旋律。
我们不可能面面俱到讲所有新东西,主要从集群健康和资源有效利用角度进行探讨,围绕集群监控,HDFS,Yarn 和 Capping 调度来展开。
集群监控
这个技术架构主要关注于离线数据平台。原始数据通过 flume 和 sqoop 接入不同的数据源,离线的 ETL 主要通过 Hive 和 SparkSQL 进行数据处理。Presto 主要用于 Ad hoc 的查询任务。这些工作都在数据开发平台自研的数坊中进行。ETL 开发自助的数据查询、定时任务 ETL 开发以及自助报表订阅,这些作业通过调度程序和作业前置依赖进行调度。在前端我们开发了自助分析平台和各种数据产品,比如比价选品、魔方等数据应用于生产。
Hadoop 集群开始于 2013 年,已经有 4 年时间了。我们从 0 开始建设,到现在有一个将近 1000 个节点主的集群以及一个用于实时离线融合的 SSD 集群。我们正在升级 Hadoop 以及 Hive 到最新版本。目前每天运行作业 10 万,yarn app 达到 50 万以上。
首先,通过专为海量数据批量处理设计的 Hadoop 集中式存储数据的平台,数据进入 Hive 数据仓库后,任意表就能关联、合并和计算,同时还保存了全量数据。SQL 基本是个人人都会的开发语言,在唯品数坊中通过 SQL 查询和处理数据,结合调度系统,就可以自动处理,合理分配资源执行大数据量的数据批量任务。对于个性化推荐需求,机器学习 pipeline 建立了 DAG,开发者通过 DAG Editor 就可以通过拖拉的方式建立机器学习实例,并且分布式进行调度。大数据除了应用于内部数据分析工具外,还出品线上业务的数据产品比如消费者在前端看到的实时个性化推荐,内部比价系统和供应商用于生产的售中组货,魔方等。
大数据平台主要职责是维护集群的稳定性,提供充足的资源以及多样化场景的需求。这个和我们面对的挑战是一致的。集群稳定性很重要的一点是可以通过平台监控来感知平台的隐患和压力。在监控中发现集群压力,我们下一步就要进行性能优化。优化后我们通过监控系统查看效果。这在整体上是一个闭环的过程。
系统告警在框架上必须满足三大要求:第一是必须全部覆盖机器层面、日志层面和服务层面,不可偏颇;第二必须是实时监控,遇到故障需要从邮件、短信和电话不同级别地升级和降级;第三也是非常重要的,就是告警规则必须是容易配置的。
用 ES 来监控日志文件和 Zabbix 来做机器层面的监控是我们做了比较久的,今年我们新的尝试是引入 Prometheus 和 Grafna 来重构服务层的监控。Prometheus 相当于就是开源版本的 Borgmon,而 Borgmon 是 Google 内部做大规模集群的监控系统。唯品会使用 Prometheus 主动 Pull 各种指标数据通过 Grafana 完美展现部门大屏 dashboard。目前 Grafana 已经对接原有的 Zabbix 数据源和 ES 数据源,同时开通了基于 jmx 的各种开源组件监控,包括 Kafka,Hadoop,Cassandra 等,对接邮件、短信和电话告警用于生产。
这里简单介绍一下如何通过 Prometheus 做服务层面的监控原理。Preometheus 是采用 pull 的模式而不是通过玩 agent 的方式拿数据,这样的好处就是不用客户端的强依赖。但是 prometheus 对于数据格式是有要求的,所以在这里首先需要建立一个 Http Server 来将 metrics 转换成 prometheus 认识的文本格式。这里的例子是获取 kafka lagoffset,然后这个服务开放以后,prometheus 就可以主动 pull 这个网址来实时抓到数据了。
Prometheus 拿到数据后就会存储到本地或者 remote 的存储,前端 Grafana 的配置也是非常简单的,定义好数据源和 metrics,加到 Graph 就可以了。在这个配置中,可以通过嵌入的 web hook 来定义告警规则。规则定义也是所见即所得,运维人员非常容易上手。
通过 Grafana 展示可以校验监控数据的链路。Grafana 提供了托拉拽的功能,我们把各种不同的 metrics 监控图组合成立了一个部门大屏。通过统一制定大屏,我们可以对系统情况一目了然。我现在每天上班的第一件事情,就是打开这个部门大屏查看系统情况。
Hive 在多 HDFS 集群上的实践
说完了监控部分,我们开始今年的一个落地尝试–实现多 HDFS 集群。在调研落地时我们发现目前比较流行的社区 Federation 方案与业务不是非常兼容。在这个基础上,我们研究了多 HDFS 集群的应用,保持一个 YARN、支持多个 HDFS 集群方式。该实践的特点是通过 Hive 层来使 HDFS 透明化,最大限度兼容原来的应用。
从多 HDFS 架构上来看,我们可以支持更多的 HDFS 集群,在上面暴露给业务方的是一个统一的 yarn 和 Hive metastore。通过底层的改变,我们希望用户如果通过 metastore 的访问可以做到透明。但是如果用户直接访问 HDFS 层,就需要通过设置一个缺省的 hdfs 集群保持不变。
需要多 HDFS 集群是由于单节点的 NameNode 压力导致。在去年 9 月份时一亿的元数据增长一年就到了两亿元数据,数据增长非常快。对于平台方来讲,我们需要未雨绸缪。这样如何横向扩展 NameNode 能力就被提上了日程。
目前业界比较普遍的做法是采用 Federation,我们在调研后发现 federation 需要业务分割的比较清楚,这和我们目前的业务模式不是非常吻合,而且它需要通过比较重的客户端 ViewFS 来实现,需要使用 mounttable 的挂载方式,这就好比为行驶中的汽车换轮胎一样。有没有一种更加轻量级的方法来实现类似的横向扩展呢?
多 HDFS 扩展首先需要解决的问题是如何透明地支持上层应用。我们用的方法是使用 Hive 的 location 特性使得表的 location 是可以区分集群的。这个可以支持一个表的不同分区在不同 HDFS 集群上面。
在 xml 配置上,和 federation 非常类似, 但是去除了部分关于 mount table 的配置和减少重客户端 viewFS 的方式。我们增加了 internal.dataservices 的属性,来指定缺省的集群。
我们已经部署了半年时间,对用户唯一不方便的地方则是直接写 hdfs 的程序使用具体的集群,由于我们在配置里加了 internal.nameservices,如果用户不写,缺省就会到缺省的集群。各方面反映还是不错的。
Yarn 分配 container 性能优化
第三部分是围绕 Yarn 做的优化。
问题的提出是这样的,在优化以前每一个 containser 分配资源需要 0.8ms,那么总共 7 万个 container,如果顺序分配完的话就需要大约 1 分钟。这个需要进行优化。
优化首先要了解分配原理是怎样的。唯品会使用的 yarn 的分配策略是 fair scheduler,它的特点是倾向于公平分配。调度器每次选择作业资源缺额最大的。那么每一次分配逐层遍历并根据缺额进行倒排序,然后尝试分配。
我们通过打 metrics 将耗时进行了分析,发现分配资源占了一半时间。当然分配失败是有很多种原因的,这里不一一列举了。我们的关注点在于如何提高资源分配的成功率,这将会缩短分配时间,提高分配效率。
有了前面的分析以后,新的分配算法就呼之欲出了。我们通过分配 container 不排序同时启发策略,从上一次 index 开始继续分配。这个方法提高了分配的时间效率,当然这是一种 trade-off。
从优化结果看,提高了近一倍的分配效率。
基于 Hook 的 Capping 资源管控
最后再讲一下以 capping 的流量控制为基础的资源管控。
这个资源管控问题源自于交通控制问题。那么在交通繁忙的时候,马路上公交车的优先级比私家车高,救火车的优先级又比公交车高。这个原理同样可以应用于 Hadoop 的资源管控。
实现作业资源管制的方法是首先我们能够认识来的作业是什么项目的,作业的优先级设置是怎样的。在平台这一层还需要配置不同优先级的队列,就像马路上不同的车道一样的道理。这里核心功能就是 engineswitch 可以通过读取 metadata,给作业填上不同的队列信息进行作业提交。
有了 capping 控制模块以后,作业将不会直接提交到集群,而是调用 hook 首先感知系统资源使用繁忙程度,然后比较队列 capping 阈值,再决定是否直接提交还是继续等待。我们设置了等待重试 6 次将会直接设置作业失败。
通过一个实际例子,我们可以更加清楚地了解这个原理。Root.bigdata_traffic.critical 和 root.bigdata_traffic.online 是两个三级队列,他们的 capping 阈值是不同的。在高峰期,他们的 capping 值分别是 1 和 0.9。当系统繁忙 root.usage 在 0.95 时,critical 这个关键队列里的作业就可以提交作业,而 online 队列就被堵塞了。直到 root.usage 下降了或者到了非高峰期的阈值变成了 0.95。
另外一点是我们已经实现了为各业务团队配置资源的限额(Quota),一旦该团队当日使用量超过日 Quota 值,系统将会自动降级该团队下面队列的 Capping 阈值。
感谢各位,以上是我们在 2017 年做的一部分工作,欢迎指正。
End.
来源: http://www.36dsj.com/archives/104657