1. 背景
随着公司业务的高速发展,业务数据的生产速度变得越来越快,离线集群规模快速膨胀,既有机房内的机位急剧消耗,在可预见的不久的将来会达到机房容量上限,阻塞业务的发展。因此,如何解决单机房容量瓶颈成为了我们亟待解决的问题。
目前,针对机房容量问题的解决方案主要有以下两种:
1)集群整体搬迁至更高容量的机房(scale up)。该方案是一种纵向扩容方案,即将现有集群搬迁至容量更大的机房,从而提供集群扩展的空间。现实中,集群迁移一般不能影响业务的发展,即保证不停机,因此,迁移过程中需要两个规模相近的集群做全量迁移,或者需要一个具有一定规模的过度集群,分批次迁移;对于大规模(tens of thousands)集群来说,迁移的经济成本巨大;另外,迁移后的新机房会有再次达到容量上限的风险。
2)多机房方案(scale out),即一个机房容量有限,扩展为多个机房,同时对既有架构进行一定的改造,保证用户视角仍像是一个机房。此举可依据业务需要,采用灵活的方式增量扩容,从而一定程度上避免容量冗余问题。然而,该方案会存在跨机房数据交互,而机房间网络带宽一般也存在瓶颈;同时,网络的抖动或断网可能造成跨机房业务出现异常。因此,该方案需要考虑/解决网络带宽不足及网络抖动/断网问题带来的影响,技术成本较集群整体搬迁方案高。
就我们目前自建机房的状态来看,中短期暂无清退既有机房(全部搬迁至新机房)的计划,另外,比起方案2的技术成本,我们更难接受方案1的经济成本和容量风险。 因此,方案2是我们解决机房容量问题首先方案。
2. 多机房方案
2.1 面临的问题
上文提到多机房方案面临带宽等网络问题,多机房方案的设计受其制约。
带宽瓶颈
离线场景主要是批处理场景,是对海量历史数据进行离线分析/处理的场景,该场景对延迟不敏感,但由于其处理数据量巨大对网络带宽等资源消耗较大; 另外,生产场景中作业数量一般较多且执行时间不受控,若两个机房的主机只是简单叠加在一起做为一个集群来用,可能会存在大量的跨机房互访,产生大量的随机流量打满有限的跨机房带宽, 此时除离线自身受影响外, 还可能对其它跨机房业务造成影响 。因此,如何防止跨机房随机流量打满跨机房带宽是多机房方案要解决的一个重要问题。
网络抖动&连通性
跨城网络会受供应商服务质量影响(或施工影响)造成抖动(或断网), 与机房内CLOS架构的网络质量相比会低很多。 若两个机房的主机只是简单叠加在一起做为一个集群来用,如图1 HDFS示例,当网络抖动时,不但会导致跨机房读写延迟增加,还会影响IBR等过程,造成服务性能下降;当网络出现严重问题造成断网时,会导致异地机房数据不可用,还会导致异地机房DN失联,造成大量块低于预期副本数,触发NN大量补副本等问题。因此,如何降低网络抖动及网络连通性问题带来的影响是多机房方案要解决的另外一个不可忽视的问题;
图1 HDFS 架构
2.2 设计选型
如上所述,多机房的主要矛盾是跨机房网络带宽不足、稳定性差与离线海量数据处理任务高效产出之间的矛盾,解决该主要矛盾面临的核心问题是如何减少跨机房带宽的消耗,以及如何降低网络稳定性问题带来的影响;
经调研,单元化架构是为解决多地多中心问题演进而来的部署架构,其中,单元是指一个能完成所有业务操作的自包含集合,在这个集合中包含了业务所需的所有服务,以及分配给这个单元的数据[1-2] 。按照单元化的思路,在多机房场景中,每个机房可以作为一个单元,每个单元内提供作业执行所需要的全部服务以及数据,保证作业在单元内完成,从而解决上述多机房面临的核心问题;在选定采用单元化思想来设计了多机房方案之后, 多机房方案的核心问题就限定在了如何决定作业与数据放置,以及如何让作业访问距离近的数据,来降低跨机房带宽的消耗及网络稳定性问题带来的影响;
带着上面的核心问题,我们调研了业界大厂的多机房解决方案[3-7]。这些方案在计算层面为防止Shuffle等中间结果数据造成跨机房流量,每个机房均独立部署了计算集群,在该层面均符合单元化思想;但在存储存面存在分歧,如图2所示,依据数据和异地机房的数据副本是否属于同一组NameSpace(NS),大体可以分为多机房单集群方案和多机房多集群方案;
图2 多机房方案分类
[3-5]采用了多机房单集群方案,该方案中采用Block级的数据副本,数据和数据副本同属于一组NS,无数据一致性问题,但因NS只能在其中一个机房,无法有效应对网络连通性问题,且异地副本管理改造成本较大,另外该方案可扩展性也受单集群规模制约。 [6-7]采用了多机房多集群方案,整体符合单元化思想。其中[6]应用于梯迁机房场景,它首先在同机房中通过Fast Copy将文件元数据分离到两个NS,然后再通过同NS内DN到DN的跨机房Copy将数据复制到远程机房,该方案在一定程度上可以有效应对跨机房网络风险,但因存在两次copy时效性上难以保障,另外也存在异地的数据节点,因此本质上也存在多机房单集群方案改造成本和扩展性问题;[7]阿里Yugong(Yugong: Geo-Distributed Data and Job Placement at Scale) 基于MetaStore针对分区表场景,通过调整作业放置和数据放置来降低跨机房带宽的消耗;如图3所示,计算A、B存在跨要房访问行为,通过调整(互换)计算A、B的放置位置可以有效减少跨机房访问流量;计算C、D同时跨机房消费同一份数据3, 若通过数据复制的方式将数据3复制到机房2, 让C、D依赖数据3在机房2中的副本,则可以减少一次跨机房消费数据流量。 但对于我们采用开源大数据架构的场景来说,需要改造(分属于多个子部门的)多种计算框架来适配其基于MetaStore的数据副本管理和数据路由,改造实施成本较大;另外,其基本MetaStore的设计只能解决表(SQL)场景的多机房问题,也不能覆盖我们对非表场景提供多机房支持的需求;不过,该方案中通过"作业放置-数据复制"来解决带宽瓶颈问题的思路非常值得我们借鉴;
图2 任务跨机房随机分布
综上,我们参考Yugong“作业放置-数据复制”的思路,采用有限的单元化思想设计多机房方案; 如图3所示,每个机房部署一套独立的完整的集群,为作业在一个机房内执行提供最基本的服务保障,从而在跨机房网络出现异常时,降低影响范围;同时,通过合理的作业放置和有计划的数据复制,消除跨机房随机访问流量及跨机房重复消费等问题,来达到降低带宽消耗的目的;另外,我们结合内部的基础设施情况以及满足表和非表两种场景,我们选择了基于扩展HDFS Rouer(RBF)多挂载点来实现数据副本管理和数据路由功能,并通过Client IP感知自动将数据请求路由至较近的机房;还有为解决数据复制带来的一致性问题引入了Version服务等,图中涉及组件将在实现部分进行介绍。
图3 多机房架构
2.3 总体流程
图4展示了以Hive作业为例的在上述设计思路下的总体流程,图中绿色模块为我们新增或改造组件。首先,通过周期性的分析作业间依赖关系及依赖的数据大小,确定作业放置位置信息并进行持久化(DataManager用于管理作业放置信息等),当作业管理平台提交作业时,先获取作业的放置机房,并检查预期放置机房的数据副本是否Ready,若Ready则提交作业,否则,阻塞提交,等待数据复制服务完成复制数据; 其次,作业调度提交后,拉起HiveDriver 生成可执行计划,向预期DC的Yarn集群提交Job,等待拉起Job; 最后,被拉起的作业请求HDFS数据,HDFS Router依据Client IP所属的DC信息,自动将请求路由到距离Client较近的数据复本所在机房的NS, 并将结果返回Client。
图4 多机房作业调度执行流程多机房核心流程包括 作业放置、数据复制、数据路由、版本控制、数据限流、跨机房流量分析等几个阶段, 上述Job 提交流程并未完全涵盖, 下文实现部分我们将对所有阶段进行详细说明。
3 多机房方案实现
下面章节会对多机房核心环节进行介绍, 包括作业放置、数据复制、数据路由,以及为保障数据副本一致性引入的数据版本服务和带宽控制的限流服务,并引入事后的跨机房流量分析工具,用以发现预期外的跨机房行为指导调整。
3.1 作业放置
a. 依赖分析
大数据离线场景,作业数量多,作业之间依赖复杂。比如,大数据离线报表处理业务,从数据采集,清洗,到各个层级的报表的汇总运算,到最后数据导出到外部业务系统,一个完整的业务流程,可能涉及到成百上千个相互交叉依赖关联的作业。就作业放置来说,对复杂作业依赖的管理和分析工作至关重要, 而如我们自研的调度平台Archer等DAG工作流类调度系统,自身具有较强的作业依赖管理能力,因此,我们仅需要聚焦作业依赖分析以确定要迁移的业务;
我们依据作业间依赖关系及需要处理的数据大小,基于社区发现(Community Detection)探索了一种考虑跨机房带宽代价的作业关系链划分模型。该模型首先依据调度系统管理的作业间的依赖关系构建DAG图, 然后从DAG图中圈出相对高内聚(相对比较闭环)的业务子单元,最后结合相互依赖的子单元间的数据量选择出的可以迁移的子单元; 如图4所示的简单DAG, 我们假定图中正方形代表计算,圆形代表数据,圆的大小代表数据大小,则我们以虚线作为划分边界将DAG分成两个子单元,分别调度到两个机房,则可满足数据传输代价小的目标。当然,整个过程除了考虑跨机房数据访问代价外,还需要考虑机房资源是否可以满足需求。
图4 依赖关系划分
一般而言,实际生产中的ETL等周期性调度作业相对比较稳定, 不会频繁发生变化,甚至部分作业不会出现变化,因此,确定Job放置在那个机房的的依赖分析过程可以以天或周为单位周期性的离线产生;另外,从管理的角度来看,公司一般会有多个相对比较独立的业务部门,每个业务部门又会垂直的划分出多个业务子单元,业务内的作业间联系紧密程度远大于业务之间; 同时,业务(单元)也是资源管理单元,以及多机房落地实施过程中的沟通单元; 因此,在实践中往往是以业务单元为边界进行依赖划分;
b. 作业放置
我们的生产环境中存在多个作业调度平台,如Archer、Airflow等平台,将Job放置在那个机房的信息维护在任一平台都不能涵盖所有作业, 因此我们引入DataManager服务(在整个体系中的位置见图3、4)做为接入层,用来管理作业放置的IDC信息和需要进行数据复制的路径信息,Archer/Airflow等平台通过对接该服务来接入多机房体系; 下面以自研DAG调度平台Archer为例描述工作流程如下:
1)前置工作:Archer 通过DataManager接口设置作业的放置位置信息,以及依赖数据的pattern、范围、生命周期等信息;
2)Archer 访问DataManager 确定作业放置的IDC信息,并为作业选择符合IDC作业配置信息;
3)Archer 询问Job 在IDC的数据是否Ready, 若Ready,则指定IDC并通过Yarn Router向计算集群提供作业;否则,挂起并等待数据Ready后尝试重新提交;其中数据是否Ready,是通过DataManager转发请求至数据复制服务得到;
3.2 数据复制
a. 复制服务
上小节作业放置会将有联系紧密的Job放在一个机房,以减少跨机房访问,进而减少跨机房网络带宽消耗;对于无法消除的跨机房依赖,特别是异地机房使用频次大于1的数据,需要异地机房也存在数据副本,以降低网络带宽消耗;因此,我们提供了数据复制服务来进行副本复制;
数据复制服务基于社区提供的DistCp工具实现, 并在正确性、原子性、幂等性、传输效率等方面作了增强, 同时支持流控、多租户传输优先级,副本生命周期管理等功能;
b. 复制流程
数据复制主要针对有规律的周期性调度作业进行,这类作业一般比较固定,通过对作业历史运行记录进行分析即可推测出作业的输入输出情况,包括数据路径和使用的数据范围(防止长时间跨度回刷任务大量复制)等信息。因此,当确定好待迁移的作业后,可以提炼出数据路径规则(rules),并持久化到DataManager的规则库中(规则库会随作业放置的变化而进行周期性更新)。
然后,针对不同的场景使用规则库进行路径抽取,下面以Hive表场景为例描述数据复制流程,如图5所示, 首先收集Hive MetaStore的挂载表/分区相关的Event信息至Kafka服务,然后通过实时任务清洗出符合上述规则库中规则的路径,交由数据复制服务进行传输,生成异地机房副本,并在传输完成后由数据复制服务持久化副本信息(包括路径、版本、TTL等),以对副本数据进而全生命周期管理;
图5 数据复制流程上述复制流程采用自动发现主动复制的策略,可以快速捕获并准备数据副本,经过统计在我们的生产中数据副本延迟的TP90可以控制在1min以内, TP99可以控制在5min以内,可以有效满足离线场景的业务需要;然而,上述自动发现主动复制的策略,可以有效解决增量数据副本的问题,但对于待迁移作业来说,可能还依赖较长一段时间的存量数量,针对该问题,我们除了采用提前启动复制流程的方式准备存量数据外,还针对需要快速迁移的场景引入了基于Snapshot的数据迁移策略进行初始复制,因Snapshot为社区成熟技术不再缀述;
3.3 数据路由
上小节介绍的数据拷贝后双机房均会存在某路径的数据副本,当作业放置到IDC后如何定位到正确的数据是数据路由服务要解决的关键问题;
如图6所示,我们基于HDFS Router的多挂载点实现了MergeFs功能,并在此基础上扩展实现了镜像挂载点来实现数据路由功能。为方便描述,我们约定原始数据为主数据, 传输到异地机房的数据为副本数据(也称为镜像数据,该数据只允许读取和删除),并且约定镜像挂载点中第一挂载点为主数据,之后的挂载点为副本数据(理论上可以扩展多个机房); 为了在路由层面做到对用户透明,我们在镜像挂载点的处理逻辑中,增加了请求来源的IP位置感知功能,该功能能过获取请求来源IP的位置信息,判断请求来源的DC并将请求路由到相应的DC的HDFS。如图6 示例所示,若数据请求来自DC1, 则Router将数据请求重定向到DC1的HDFS集群,来自DC2则定向到DC2的HDFS集群(图中同种颜色线条标识请求路径);
图6 基于Router的数据路由
为了降低跨机房带宽的消耗,原则上,我们规定所有对数据的读取操作,都只允许在本地机房(即Client所在机房), 否则先拷贝到本地机房。但特殊情况下,如图7所示,若Data Replication Service发生异常短时间无法修复 或 ns长时间异常时,则我们允许降级为跨机房限流读(副本未ready case, 超过一定的时间未在目标机房读取到数据,则降级),限流部分在后面章节进行详细介绍;
图7 数据路由容错
3.4 版本服务
分布式场景下,通过数据复制方式产生副本,不可避免会导致一致性问题,因此,多机房存在数据副本时,除了涉及上述路由选择问题外,还必须考虑数据版本一致性问题,我们通过引入版本服务(Version)解决该问题;为了简化版本服务设计, 针对大数据离线场景写少读多的特性,我们依据CAP理论对镜像挂载点的实现做了一定的取舍,规定了对主数据可以进行所有操作,副本数据只允许读/删操作;在这个前提下,我们引入了基于HDFS Editlog的版本服务,如图8所示,该服务以观察者的身份监控向HDFS JournalNodes(JN)订阅路径的变更行为,并以操作ID(transaction id)来标识数据版本;若订阅的路径中数据发生了变化,则会通过editlog传导到JN,再由JN通知Version进行版本更新;因所有对数据的变更操作都会记录editlog,因此,不论SQL场景和非SQL场景,只要数据存在变化均可被版本服务捕捉到,从而可以有效保证数据的一致性;
图8 数据版本工作流程
上文2.3 节总体流程所描述的提交作业时,当获取到作业预期的放置机房后,检查依赖数据是否Ready的工作也包括版本检查工作;当作业需要副本数据时,会通过数据传输服务检查已传输的数据副本的版本与版本服务中订阅的最新版本是否一致,若一致允许作业提交使用数据副本;否则,作业临时阻塞,待传输服务更新副本数据后,则允许提交作业;若超过一定的时间未在目标机房读取到数据,则降级为读取主数据;
3.5 限流服务
我们的场景下跨机房带宽有限(约3Tbps),并且和在线服务、实时服务等对延迟更敏感的服务共用带宽,为防止离线跨机房流量(特别是计划外的跨机流量)打满带宽影响在线业务, 我们引入了基于令牌桶的限流服务。
图9 令牌桶
令牌桶限流的核心思想为当进行某操作需要令牌时,需要从令牌桶中取出相应的令牌数,如果获取到令牌则继续操作,否则阻塞,用完之后不用放回。基于该思想我们设计了全局中心限流服务,通过对HDFSClient 输入/输出流进行包装,使其在进行跨机房数据操作前先尝试获取Token;除利用令牌桶固有的特性外,我们在令牌桶的基础上我们实现了加权公平特性,来保障多租户的情况下重要服务可以获取到Token;在稳定性方面,为了降低限流服务的压力,我们设置每个Token代表相对较大的流量单元,来降低Token的获取次数;为防止限流服务宕机导致作业阻塞,我们增加了降级为固定带宽的策略, 同时,我们在水平扩展限流服务方面也做了一定的探索,在增强HA的同时期望可以接入所有跨机房访问请求;
另外, 多机房方案中,数据拷贝失败或无法按时完成时,我们提供了跨机房限流读的降级方案,限流服务也是保障降级的重要服务。
3.6 跨机房流量分析
在大数据场景跨机房流量可以分为计划内流量和非计划内流量两大类:
- 计划内流量:3.2 小节所述数据复制服务进行数据副本复制产生的流量,我们称为计划内流量, 该部分数据大概率会被多次使用;
- 非计划内流量:即非数据复制服务产生的数据流量,单次(或多次)使用,主要来源有以下几种可能:
a. 计划内的调度任务发生长时间跨度的历史回刷,依赖的数据副本已过期销毁;
b. (漏迁/错迁/新增等)放置位置不合理的周期性调度任务,可以通过优化作业放置消除;
c. Adhoc查询,突发流量, 单次(或多次)使用,临时生产需求,无法预知需要的数据,无法预先进行处理;
流量分析工具
在实际生产过程中,非计划内流量不可避免,为了对跨机房流量进行有效管控,我们引入了跨机房流量分析工具。该工具通过在DFSClient Name中注入作业ID信息,并在DataNode中埋点记录作业读写流量,然后从作业ID、client ip网段等维度聚合汇总出作业粒度的流量信息,并依据该信息进行针对性的治理(包括重新方置、紧急查杀、作业优化等);
Adhoc流量治理&优化
对于Adhoc类型的非计划内流量,因为其随机性,本文所述多机房体系中“数据复制-作业放置-数据路由”方式不适用;因此,我们采用一些其它的优化手段, 比如,通过SQL Scan扫描出依赖的数据大小、位置信息,以节省多机房带宽为最主要目标,结合集群的实际负载情况,决定SQL调度那个机房,比如:
- 访问单张表: 作业调度至数据所在机房;
- 访问多张表
- 多表在同机房, 作业调度至数据所在机房
- 多表在不同机房, 作业调度至数据量较大的表所在机房;较小表限流读,或者阻塞通知拷贝服务拷贝 ;
另外, 对于Presto这种有多源查询能力的引擎,我们利用其Connector多源查询功能力将每个机房视为一个Connector,在多表访问场景中将子查询下推发送到远端机房进行处理,以减少垮机房流量带宽;
4 小结&展望
本文描述了离线多机房方案,该方案已内部平稳上线运行半年以上,从实践的结果来看该方案在很大程度上解决了跨机房网络带宽不足、稳定性差与离线任务高效产出之间的矛盾。鉴于当前部分大数据关键组件的单元化进程,在抗网络连通性风险方面的能力还有较大的提升空间,后续我们将不断的推单元化进程,进一步降低网络问题的影响范围,同时赋予部分高优化作业“双活”的能力。
引用
[1] https://cloud.tencent.com/developer/article/1891503
[2] https://help.aliyun.com/document_detail/159741.html
[3] https://www.infoq.cn/article/fo*rxliycw7exf3g8mct
[4] https://cloud.tencent.com/developer/news/594902
[5] https://www.infoq.cn/article/gtlguya2mo8rgbwndt2x
[6] https://www.slideserve.com/jola/namenode
[7] Yugong: Geo-Distributed Data and Job Placement at Scale
网友评论