其他分享
首页 > 其他分享> > 从0到1:饿了么大数据平台Hadoop集群规模突破1000+之炼金术

从0到1:饿了么大数据平台Hadoop集群规模突破1000+之炼金术

作者:互联网

随着接入的需求方越来越多样化,对大数据的数据使用、数据存储与计算的需求也越来越多样化,同时业务飞速发展,集群的规模也急速扩大。如何在这样的场景下通过大数据平台,稳定支撑住业务的发展是一个不小的挑战。本文分享主要平台工具链,技术、选型及架构设计上的一点经验。

大数据平台现状

饿了么的大数据平台团队成立于2015年5月份左右,在16年4月份,Hadoop集群规模还只在100+节点数,而在一年时间里集群规模快速增长到1000+的水平,这还是在引入数据生命周期进行管控的情况下的规模增速;同样,流计算集群的规模虽然相对较小,但也经历了10倍的增长,一些topic的吞吐量已超过百万每秒。 

当前平台部分的逻辑架构如图1,并持续演进。

图1 饿了么大数据平台的逻辑架构图

当初面临的问题

饿了么已经成立9年时间,相对而言数据平台团队非常年轻,在加入团队之初面临了如下挑战:

因此,主要以效率、质量和持续扩展为核心来建设数据平台。

技术选型

如图2所示,大数据的技术栈非常多样化,对于团队很多初入大数据领域的成员来说很容易在尝新过程中消耗团队的生产力,因此在加入团队初期,首先就要确定在当时条件下的技术选型。

图2 多样化的大数据技术栈

选型原则

在技术选型方面坚持的原则是“3T”:要解决什么样的问题和场景(Trouble),有哪些技术可供选择(Technology),以及团队技术栈与目标采用技术的匹配程度或者说掌控能力(Team)。

下面举几例子来看:

即席查询引擎选型

在以Hive on Hadoop为中心的离线数据仓库,最开始分析师以及数据工程师也都是使用Hive来做数据分析和探索,但是Hive本质上是基于MapReduce架构的,并不是很适合这个场景。当时所选择的目标集中在Presto和SparkSQL上,社区活跃度Spark是最高的,并且从SQL语法兼容性来看SparkSQL也是最合适的,用户的使用成本比较低,但是在测试的时候发现失败率高达50%,在兼容性和稳定性方面如果无法对Spark代码做一定定制化开发的话达不到我们的要求,相对而言Presto虽然语法兼容性不如SparkSQL,但是比较稳定并且在运行效率上也高于SparkSQL,考虑到当时团队的Spark力量积累不足,同时团队成员也有曾使用和管理过Presto的经验,因此优先考虑Presto作为Ad-hoc的查询引擎。

海量Key-Value存储选型

对于比如用户画像、历史订单等场景通常是需要一款能够支持海量K-V存取的存储引擎,大多基于Hadoop的团队使用HBase是比较自然的选择,同时也是我个人过去使用比较多的存储之一,但是发现其他成员对于HBase的掌控能力非常薄弱,同时周边的配套设施也没有建设起来,是否坚持使用HBase需要尽快想清楚。从HBase的架构上看(如图4),整体建构组件多(NameNode、DataNode、JournalNode、Zookeeper、RegionServer、HMaster),运维成本高;同时对非Java客户端还需要再引入thrift server,为了HA和负载均衡还需要一层LB,进一步加大了系统的复杂度。这时我们把目光转向了Cassandra:结构简单便于聚焦,多语言支持CQL,客户端功能丰富,访问控制也更成熟。另外,对于Cassandra一致性的顾虑在团队的场景应用中是比较容易规避的,大多数都是定期推送频繁读取,推送具有幂等性且场景对于一致性的要求不严格,同时反而可以利用Cassandra的多点提供读能力增加读取的吞吐量(对应的,HBase只有一个数据节点提供读请求)。最后决定把已有基于HBase的数据接口迁移到Cassandra来,降低了开发和维护的成本。

图4 HBase架构图

通过以上的例子总结下选型心得:

架构设计

技术选型确定了,接下来需要解决在业务急速增长情况下的架构设计问题。理想的架构是系统上线后尽量减少人的参与,或通过简单的流程即可应对外部变化,追求可持续扩展的架构设计,这里通过一个具体案例来表达我们在设计时的关注点。

如图5,流入三个源数据流:用户行为、主站订单、以及开放平台订单的订单渠道,进行各种实时指标的计算,其中分渠道订单相关指标的计算和多维度组合下的UV计算场景是比较典型的流计算问题。

图5 流入三个源数据流的UV计算渠道订单

异步

分渠道订单指标计算需要将主站订单流和开发平台订单流进行Join计算,因为是多数据流的合并计算,所以在设计该架构时基于的假设是:不同源数据流之间的到达时间无法协同,我们将问题转化为”在可调整的时间窗口内通过匹配触发Join计算”。具体落地则是通过Redis缓存住还没有匹配的订单数据,引入时间窗口是为了控制住缓存的大小,而时间窗口的控制有两处:在拿到数据时会检查是否在时间窗口内;另外在未匹配的情况下写入Redis时会把时间窗口通过TTL的方式一并维护,避免多余的维护任务。

可扩展性

UV计算首先要解决的就是去重问题,比如判断某个deviceID是否是当天的平台新访客,一种做法是通过Redis的集合来判断,具体数据结构如下:

key : YYYYMMDD_uv

value : deviceID的集合

这样的设计会带来热点问题,所有该维度的deviceID请求都会打到一个节点上产生热点,当流量增加时无法通过直接扩容来解决问题,那么自然就想到如下的数据结构:

key : _YYYYMMDD

value : 占位符

通过如此转化可以很好地把请求打散,有具更好的扩展性。

回到多维度UV计算的场景下,通常涉及到的组合维度可以达到2的N次方,如果采用上述结构无论是读写的吞吐还是空间的消耗都是巨大的,扩展成本非常高,我们选择牺牲一定精度来达到低成本的扩展性。UV计算本质是基数估计问题,在该领域非常出名的数据结构就是HyperLogLog(以下简称HLL),虽然Redis本身支持HLL但是无法避免热点问题,我们选择在流计算过程中本地计算HLL,因为HLL支持merge操作同时幂等可回放,大量的计算都在计算任务节点本地完成,无论是shuffle还是落地存储的处理毫无压力,通过压测,在不扩容的情况下可以支撑20倍的压力。

稳定性

对于稳定性主要通过事前、事中和事后三个方面来看,即执行计划、故障处理和事后复盘。

执行计划

首先线上变更为了控制风险,有两点是必须遵守的:一定要有可行的回滚方案,一定要灰度。

其次,对于具体的尚未自动化支持的变更流程或SOP需要考虑异常分支,大多数看到的SOP文档只是考虑正常流程一步步执行下来,可是经常遇到的问题反而是某个流程走不通或者出问题了。

最后,就是变更时间估算很重要,对变更的节奏把握的越清楚风险越从容。

故障处理

对于故障处理我们比较关注的一个指标就是MTTR(Mean Time To Recovery,即平均恢复时间)。

从上面的公式可以看出MTTR主要是由响应时间和处理时间构成。

监控 ≠ 告警

对于稳定性来说监控是底线,但是”监”而无”控”的现象非常普遍,带来的结果是收到一个告警不知道如何处理,或者忽略掉,或者“千人千面”处理,问题不同程度地被隐藏或放大。

监控 = metrics+trigger+action

那么如何“控”呢?

监控的”控”

我们坚持如下次序:低成本的自愈优先于流程或SOP,如果SOP没有覆盖的场景就需要一个原则来指导方向,比如故障发生后是优先保哪个方面,一致性还是可用性。逐步迭代将故障处理的“千人千面”收敛到从容有序。

复盘原则

故障复盘对于系统稳定性的提高是个非常非常有价值的闭环反馈,在这方面我们实践着Facebook的DREP原则,同时基于实践经验引入了W9(Workaround),强调可持续的稳定性。

图6 Facebook的DREP原则

工具链

上文提到的技术选型及架构设计和稳定性保障通常依赖于人,我们更希望将人的经验构建在工具中,减少对人的依赖,提升组织的可扩展性。图7为工具链的架构图。

图7 工具链架构图

尽量扩大工具在整个数据工作生命周期的覆盖度,为数据工作人员赋能,主要包括:

本文着重分享数据开发管理和数据报表开发。

图8 数据表管理系统功能示意图

数据表管理

生产数据表是所有数据开发工作的源头,因此我们把生产数据表的创建及维护工作统一收到数据表管理系统(以下称dtmeta)中,除了建表的基础功能外,主要关注如下信息:

有了这些信息,减少了大量后续维护的工作,降低交互成本。

数据开发及任务管理系统

数据开发

图9 Titan调度平台编辑任务截图示意

图10 Hive的多数据存储推送

任务执行与管理

对于任务执行和任务的自助化运营管理我们主要关注这几点:

图11 错误日志的常见处理策略

1. DAG出度分析,评估任务重要程度,同时也是提供给调度系统的重要特征;

2. 运行趋势分析,包括启动时间,运行时长,处理数据量的趋势变化;

3. 通过埋点将用户级别的任务和下游系统(Hadoop等)的任务全链路打通,可以追溯到任何一个层面执行状况;同时,会给任务打标签,比如倾斜、参数不合理等提供给用户进行快速的自助分析和管理;

4. 对错误日志进行归类处理,去掉噪音,并附上常见的处理策略,进一步提升任务自助化管理。

报表开发平台

报表开发是数据应用非常常见的一个场景,在大数据部门成立初期有大量的报表开发工作需要消耗很多人力,虽然有很多成熟的商业产品,但是大多专注于交互可视化,对于已有系统和基础设施的接入成本很高,因此我们快速开发了报表开发平台(EMA)。

可以将模板化的SQL快速转成报表嵌入到各个系统中,并且和内部系统打通,血缘建立,支持包括MySQL/Preso/Kylin/Hive/Spark等各种常见的数据源或执行引擎,同时可配置报表查询缓存使得大计算量小结果集的场景得到很好满足。EMA上线至今,有接近八成的报表都是出自该系统。

图12 报表开发平台应用

实时开发平台

在线算法的实时特征计算包括POI感知、上下文场景感知,都是很典型的实时计算场景。实时开发管理平台主要包括数据源的端到端接入,封装框架的业务无关细节,提供可配置策略,另外利用flux将任务配置和拓扑管理抽象出来。任务的发布控制以及上线后自动监控联动,让开发人员更多关注业务逻辑和架构设计,减少管理层面的投入。

图13 实时开发平台的架构设计

平台的一些思考

1. 面向用户:尽量推动助化,和产品的自解释;

2. 反复强化用户预期;

3. 面向系统:推动系统的自动化和一键化,最后才是SOP。

1. Less is more

2. Think about future, design with flexibility,but only implement for production

以上是我们截止到17年H1的一个回顾,饿了么大数据平台还在持续快速演进中,期待有更多的干货在接下来能够和各位技术同仁共同交流探讨。

欢迎学Java和大数据的朋友们加入java架构交流:736925717 

加群链接:https://jq.qq.com/?_wv=1027&k=5XXrrMk

群内提供免费的架构资料还有:Java工程化、高性能及分布式、高性能、深入浅出。高架构。性能调优、Spring,MyBatis,Netty源码分析和大数据等多个知识点高级进阶干货的免费直播讲解  可以进来一起学习交流哦


标签:炼金术,平台,Hadoop,任务,开发,计算,选型,数据,1000
来源: https://blog.51cto.com/14224832/2362560