Netflix 基于 Hadoop 的数据仓库达到 Petabyte 量级,而且增长迅速。他们大数据处理架构十分独特,能让他们构建一个可以在云中无限扩容的数据仓库,而且是在数据和计算能力两方面同时做到无限扩容。前不久,他们在自己的技术博客上发布了一篇文章,其中谈到了 Netflix 基于云的数据仓库,以及它与传统基于数据中心的 Hadoop 基础设施的不同之处,此外还介绍了如何利用云的弹性构建动态可扩展的系统。文章重点对 Genie 项目做了说明,该项目是 Netflix 内部的 Hadoop PaaS,为作业执行和资源管理提供 REST-ful API。
在传统的、基于数据中心的 Hadoop 数据仓库中,数据保存在 HDFS 中。HDFS 可以运行在商用硬件之上,提供对大数据集的容错和高吞吐访问。在云中,最典型的方式就是跟随这个模型,将存在 HDFS 上的数据放在基于云的 Hadoop 集群上。但是,Netflix 没有这么做,他们的选择是:
我们将所有的数据存在 Amazon S3 上,这是我们架构的核心原则。
我们使用 S3 作为基于云的数据仓库的真正数据来源。任何值得存留的数据都放在 S3 上。这包括每小时产生的几十亿个流事件,它们来自支持 Netflix 的电视、笔记本电脑、移动设备,被我们的日志数据管道(Ursula)抓取,还有由 Cassandra 提供的维度数据,来自我们的 Aegisthus 管道。
之所以选择 S3,文中给出 4 个原因:
S3 保证其中存储的对象在一年期内的耐用性(durability)是 99.999999999%,可用性(availability)是 99.99%,并可同时承受两个机房的并行数据丢失。
其次,S3 提供存储桶版本控制,我们使用该功能来防止数据出现无意丢失。举个例子,如果开发人员不小心误删除某些数据,我们可以轻易恢复。
第三,S3 具备弹性,而提供事实上“无限”的存储容量。我们不需要事先准备任何存储资源,就让数据仓库做到了有机增长,从几百个 T 到 P 级。
最后,用 S3 作为数据仓库,我们可以运行多个高度动态化集群,而且能适应失败和负载。
当然,也有一些问题:
S3 的数据读取和写入都比 HDFS 慢。不过,很多查询和流程都是多步骤的 MapReduce 作业,因此第一个步骤中的 mapper 从 S3 中同时读取输入数据,最后一个步骤中的 reducer 将数据写回 S3。HDFS 和本地存储用来完成所有中间的转换和临时数据,这就降低了性能开销。
Netflix 使用 Amazon 的 Elastic MapReduce(EMR)Hadoop 版本。他们会使用多个 Hadoop 集群处理不同负载,全都访问同样的数据。一个超过 500 个节点的“查询”集群,供工程师、数据科学家、分析人员使用,完成随机查询。还有一个与“查询”集群大小相似的“生产”(或称为“SLA”)集群,运行由 SLA 驱动的 ETL(数据抽取、转换、加载)作业。他们还有其他一些“研发”集群,根据需要启动。
如果我们使用 HDFS 作为数据来源,那么就要把数据复制到所有的集群中。使用 S3,这就不是问题了,所有的集群可以马上访问同一个完整的数据集。
亚马逊通过 EMR 提供 Hadoop IaaS,EMR 有 API 可以准备和运行 Hadoop 集群。但 Netflix 实现了自己的 Hadoop PaaS,名为“Genie”,提供更高层面的抽象。开发人员可以使用 RESTful 的 API 来提交单个 Hadoop、Hive 或是 Pig 作业,而不需要准备新的 Hadoop 集群,或是安装任何 Hadoop、Hive 或 Pig 客户端。而且,这让系统管理员可以管理和抽象出云中不同 Hadoop 后端资源的配置。
那为什么还要开发 Genie 呢?
我们的 ETL 过程是松耦合的,组合使用 Hadoop 和非 Hadoop 工具,跨越云和我们的数据中心。举个例子:我们需要在基于云的 Hadoop 数据仓库中使用 Pig 和 Hive 执行每日总结,并将结果加载到在数据中心的关系数据仓库中。这是很常用的大数据架构,用小得多的关系数据仓库来对上基于 Hadoop 的系统。前者提供实时性更强的互动查询和报表,而且与传统的 BI 工具整合更好。目前,我们使用 Teradata 作为关系数据仓库。不过,我们也在研究 Amazon 的 Redshift 新产品。
在数据中心中,我们使用企业级调度应用 UC4 ,用其定义数据中心和云之间不同作业的彼此依赖关系,将它们作为“ 流程流(process flow)”运行。因此,我们需要一种机制,在不安装整个 Hadoop 软件栈的前提下,做到从任何客户端启动 Hadoop、Hive 和 Pig 作业。而且,由于我们每小时运行数百个 Hadoop 作业,需要该系统来水平扩展,主要原因在于:随着将更多 ETL 和处理工作放在云中的 Hadoop 上,负载会不断增加。最后,由于云中的集群总有可能发生变化,而且有多个 Hadoop 集群可以运行 Hadoop 作业,我们需要从客户端中抽取出后端集群的具体细节。
之所以不用一些现有的工具,是因为:
开源社区中现在没有合适的工具,能满足我们的需求:要有 API 可以执行作业、抽象后端集群、有能力提交作业到多个集群、足够的可扩展性(水平或是其他方式)等等。
Genie 到底是什么呢?
Genie 是一系列 REST-ful 服务,用来管理 Hadoop 生态系统中的作业和资源。其中有两个关键服务。
- 执行服务(Execution Service):提交和管理 Hadoop、Hive 和 Pig 作业。客户端通过执行服务 API 来与 Genie 交互,发送带有参数的 JSON 或是 XML 消息启动作业。如果一个作业提交成功,Genie 会返回一个作业 ID,可用它获取作业状态和输出 URL。
- 配置服务(Configuration Service):保持可用 Hadoop 资源的资源库,包括需要链接和在这些资源上执行作业的元数据。配置服务跟踪所有目前运行的集群,还有它们支持的调度类型。
文中还简单介绍了如何使用 Genie 完成动态资源管理。
在 Netflix,不同工程师团队在 AWS 的自动扩展组(auto-scaling groups,简称 ASG)内的预留实例上运行自己的服务,它们会根据负载扩展或收缩。很多 ETL 作业在午夜执行,这个时候,很多 ASG 都已经变小了。因此,我们使用这些过剩的预留实例来启动“奖励”集群,补充其他生产集群。我们会用配置服务注册这些实例,Genie 客户端(ETL 作业)会使用执行服务 API 访问这些新集群。当工程团队需要他们的实例时,“奖励”集群会中止并取消注册,而且无法通过 Genie 客户端访问。
不像传统的 Hadoop 集群,我们不需要做滚动升级。如果需要升级一个生产(SLA)集群,一个方法是使用升级后的软件栈来启动一个新的生产集群,然后停止将流量路由到旧集群上,要实现这个目的,只需要设置其状态为“Out of Servcie”。另一个方法,是将运行中的集群状态设置为“Out of Service”,然后执行升级,并临时将另一个运行中的集群设置为 SLA 集群。
目前,Genie 项目还没有开源,让我们期待 Netflix 将其放在自己 Github 页面上的那一天!
评论