| 本文根据美团基础架构部技术专家舒超在2019 ArchSummit(全球架构师峰会)上的演讲内容整理而成。html
命名服务主要解决微服务拆分后带来的服务发现、路由隔离等需求,是服务治理的基石。美团命名服务(如下简称MNS)做为服务治理体系OCTO的核心模块,目前承载美团上万项服务,日均调用达到万亿级别。为了更好地支撑美团各项飞速发展的业务,MNS开始从1.0向2.0演进。本文将围绕本次演进的初衷、实现方案以及落地的效果等方面进行展开,同时本文还介绍了命名服务做为一个技术中台组件,对业务的重要价值以及推进业务升级的一些成果。但愿本文对你们可以有所启发。git
从架构上看,MNS 1.0 主要分为三层:首先是嵌入业务内部的SDK,用做业务自定义调用;而后是驻守在每一个机器上的SgAgent,以代理的方式将一些易变的、消耗性能的计算逻辑与业务进程分离开来,从而下降SDK对业务的侵入,减小策略变更对业务的干扰;远端是集中式的组件,包括健康检查模块Scanner,鉴权缓存模块MNSC,以及基于ZooKeeper(如下简称ZK)打造的一致性组件MNS-ZK,做为通知和存储模块。在层级之间设立多级缓存,利用“边缘计算”思想拆分逻辑,简化数据,尽可能将路由分配等工做均摊到端上,从而下降中心组件负载。更多详情你们可参考《美团大规模微服务通讯框架及治理体系OCTO核心组件开源》一文中的OCTO-NS部分。github
在体量方面,MNS 1.0已经接入了美团全部的在线应用,涉及上万项服务、数十万个节点,并覆盖了美团全部的业务线,日均调用达万亿级别,目前咱们已将其开源。数据库
总的来说,做为公司级核心服务治理组件,MNS 1.0在架构上带有明显的CP属性,在保持架构简洁、流程清晰的同时,还支持了业务大量迭代的需求,较好地帮助公司业务实现了服务化、标准化的目标。编程
可是随着美团业务的快速增加,公司的服务数、节点数、服务信息量、服务变更频次等维度都在快速增加,有些服务甚至呈现出跨数量级的增加。在这样的状况下,命名服务也面临着一些新的问题和挑战:后端
从可用性、扩展性、性能等三个方面,MNS 1.0暴露出不少的问题,究其根源,原来的命名服务做为一个CP系统,为得到“数据一致性”而牺牲了部分状况下的可用性。其实,对于命名服务而言,一致性并无这么重要,最可能是调用方在必定时间内调多了或调漏了服务方而已,这个后果在不可靠网络的大前提下,即便命名服务没有出现问题,也可能常常会出现。借助端的自我检查调整机制,其影响能够说微乎其微。而另外一方面,若是是一个机房或一个地域的调用方和服务方没有问题,可是由于这个区域和命名服务主集群断开了连接,从而致使本域内不能互调,这个就显得不太合理了。跨域
因此总结一下,咱们认为,命名服务的本质是创建和加强服务自己的连通性,而不是主动去破坏连通性。命名服务本质上应该是一个AP系统。缓存
其实,业界对命名服务AP/CP模式都有相应实现和应用,不少企业使用CP模式,缘由可能有如下几点:安全
另外,咱们了解到,一些公司使用特殊的方式弱化了这个问题,好比将CP系统进一步拆分到更小的域中(好比一个IDC),缩小分区的粒度,而全局有多个CP系统自治。固然,这个可能跟调用方服务方的跨度限制或者说调用配套部署有关系,但也有可能带来更复杂的问题(好比CP系统之间的数据同步),这里就不作详细的讨论了。微信
除去MNS 1.0自己的架构缺陷,咱们还须要面临另外一个问题,当初在项目启动时,云原生尚处于起步阶段,而现在,一些基于云原生理念兴起的网络基础设施,尤为是Service Mesh在美团快速发展,也须要MNS进行改造去适配新的流量通道和管控组件,这也是这次MNS 2.0演进的目标之一。
综上,咱们以AP化、Mesh化为主要目标,正式开始了从MNS 1.0向MNS 2.0的演进。
MNS 2.0的总体架构自上而下主要分为四层:
控制服务层:新增注册中心控制服务,这也是MNS 2.0的核心。主要分为如下三个模块:
综上所述,MNS 2.0总体架构在兼容1.0的前提下,重点变化是:新增了控制服务层并对底层存储介质进行拆解。下面,咱们来看一下服务注册发现功能在MNS 2.0中的实现流程:
接下来,咱们一块儿来看下MNS2.0的主要演进成果。
2.1 流量洪峰&平行扩展
流量洪峰对于不一样领域而言有不一样的时段。对于O2O领域好比美团来讲,就是天天中午的外卖高峰期,而后天天晚上也会有酒旅入住的高峰等等。固然,基于其它的业务场景,也会有不一样的高峰来源。好比经过“借势营销”等运营手段,带来的高峰量可能会远超预期,进而对服务形成巨大的压力。
MNS 1.0受制于MNS-ZK集群数量上限和强一致性的要求,没法作到快速、平行扩展。MNS 2.0的数据存储层重心是保证数据安全读写和分布式协调,在扩展能力层面不该该对其有太多的要求。MNS 2.0的平行扩展能力主要体如今控制服务层,其具体功能包括如下两个方面:
集群分片:控制服务提供全量注册数据的分片能力,解决命名服务单独进行大集群部署时不能进行业务线隔离的风险。MNS-Control网关模块分为Master和Shard等两类角色,协做提供大集群分片能力。
网络分区可用:MNS 1.0阶段,网络分区对可用性的影响巨大,分区后MNS-ZK直接拒绝服务。新架构将存储迁移到KV系统后,在网络专线抖动等极端状况下,各区域依然能正常提供数据读取功能。同时,咱们与公司存储团队共建C++ SDK的地域就近读写功能。一方面,提升跨域服务注册发现的性能,另外一方面,实现了网络分区后,各区域内命名服务可读、可写的目标,提升了系统的可用性,整个命名服务对网络的敏感度下降。
目前,控制服务层在平行扩缩容时间和集群原地恢复时间等方面,都达到了分钟级,集群也没有节点上限,从而可以有效应对突发的流量,防止服务出现“雪崩”。
2.2 推送风暴&性能提高
另外一个典型的场景是推送“风暴”,在服务集中发布、出现网络抖动等状况下,会致使命名服务出现"一横一纵"两种类型的放大效应:横向是“关注放大”,相似于社交网络中某大V消息须要分发给众多的粉丝,服务越核心,放大的效果越明显。纵向是“级联放大”,命名服务的上下游会逐级进行拷贝发送,甚至一级上下游会针对一个消息有屡次的交互(Notify+Pull)。
“关注放大”和“级联放大”自己都是没法避免的,这是由系统属性决定,而咱们能作的就是从两方面去平滑其带来的影响:
正面提高核心模块性能,加强吞吐、下降延迟
2.高并发的吞吐能力:控制服务经过无锁编程处理关键路径的竞争问题,借助应用侧协程机制,提供高并发、低延迟的数据分发功能。
另外,包括前面提到的控制服务集群的平行扩展能力,其实也是总体性能提高的一种方式。
侧面疏通,区分冷热数据,下降推送的数据量,提升效能
天然界中广泛存在“80/20法则”,命名服务也不例外。服务注册信息的结构体中元素,80%的改动主要是针对20%的成员,比较典型的就是服务状态。所以,咱们将单个整块的服务信息结构体,拆分为多个较小的结构体分离存储;当数据变更发生时,按需分发对应的新结构体,可以下降推送的数据量,有效减小网络带宽的占用,避免代理组件重复计算引发的CPU开销,数据结构变小后,内存开销也获得显著下降。
那是否须要作到彻底的“按需更新”,仅推送数据结构中变更的元素呢?咱们认为,彻底的“按需更新”须要很是精细的架构设计,并会引入额外的计算存储开销。好比,咱们须要将变更成员分开存储以实现细粒度Watcher,或用专门服务识别变更元素而后进行推送。
同时,还要保证不一样成员变更时,每次都要推送成功,不然就会出现不一致等问题。在组件计算逻辑所需的数据发生变化时,也会带来更多的改动。在命名服务这样的大型分布式系统中,“复杂”、“易变”就意味着稳定性的降低和风险的上升。因此根据“80/20法则”,咱们进行尺度合理的冷热数据分离,这是在方案有效性和风险性上进行权衡后的结果。
通过改造,MNS 2.0相比MNS 1.0的吞吐能力提高8倍以上,推送成功率从96%提高到99%+,1K大小服务列表服务发现的平均耗时,从10s下降到1s,TP999从90s降低到10s,总体优化效果很是明显。
2.3 融入Service Mesh
在MNS 2.0中,咱们将代理服务SgAgent部分注册发现功能合并到了Mesh数据面,其流程以下图所示:
关于美团服务治理功能与Service Mesh结合的技术细节,这部分的内容,咱们今年会单独作一个专题来进行分享,感兴趣的同窗能够关注“美团技术团队”微信公众号,敬请期待。
2.4 无损迁移
除了上面说到的MNS 2.0的这些重点演进成果以外,咱们还想谈一下整个命名服务的迁移过程。像MNS这样涉及多个组件、部署在公司几十万个机器节点上、支撑数万业务系统的大规模分布式系统,如何进行平滑的数据迁移而不中断业务正常服务,甚至不让业务感知到,是MNS 2.0设计的一个重点。围绕业务服务无感知、具有快速回滚能力、新/老体系互备数据不丢失等要求,咱们设计了以下图所示的迁移流程:
MNS 2.0总体以服务为粒度进行迁移操做,设置标志位说明服务所处的状态,由接入代理层组件识别该标志作出相应的处理。标志位包括:
上述能够总结为:聚焦单个服务,阶段性迁移服务发现流量,从而达到相似系统新功能发布时“灰度上线”的能力。固然,这个策略还涉及一些细节在其中,好比,分开存储在双写时须要重点去保证异常状况下的最终一致性等等,鉴于篇幅缘由,这里就不详细展开讨论了,并且业界针对这种状况都有一些成熟的作法。
另外,咱们经过优化命名服务发布系统的发版形式,实现自动化的流量灰度策略,下降了人力成本,同时构建了自动化的迁移工具、巡检工具,高效地进行自动化的数据迁移工做,可以快速巡检迁移后的链路风险,保障新MNS 2.0的稳定上线。
2.5 演进总结
在美团命名服务这样的大型分布式系统优化过程当中,具体到架构和功能设计层面,咱们也作了很多的权衡和取舍,前面咱们也提到,放弃了增量式的精准变更信息推送方式。在考虑性能的前提下,也没有使用数据多维度营运能力更好的MySQL做为主要存取介质等等。取舍的核心原则是:改造目标时强调业务收益,落地过程当中减小业务感知。
目前,MNS 2.0主要成果以下:
命名服务自己做为基础的技术中台设施,在坚持“以客户为中心”,升级自身架构的同时,也从以下几个方面对美团的多个业务进行赋能。
单元化(SET化)是业界比较流行的容灾扩展方案,关于美团单元化的详细内容,可参考OCTO团队在本次ArchSummit中的另外一个专题分享《SET化技术与美团点评实践解密》。这里主要是从命名服务对单元化支撑的角度去解答这个问题。
如上图所示,业务多种来源的外网流量在经过网关进入内网后,会借助命名服务提供的能力(SDK/Agent),并按照业务自定义的核心数据维度和机器属性,给流量打上单元化标签,而后路由到标签匹配的下一跳,从而实现了单元间流量隔离。一个单元内部,从服务节点到各类存储组件,都依赖于命名服务提供的单元识别和路由能力来完成隔离,因此命名服务在单元化中主要起底层支撑的做用。目前单元化在美团的重点业务,好比外卖、配送已经建设的比较完备,经过必定的单元冗余度,能在一个单元出现问题时,切换到另外一个可用的镜像单元,显著提升了业务总体可用性。
接下来,咱们再来看一下泳道场景。目前泳道在美团这边主要用于业务作完代码UT以后的线下集成测试阶段,同时结合容器,实现一个即插即用的上下游调用环境去验证逻辑。命名服务在其中起到的做用与单元化相似,根据泳道发布平台对机器的配置,自动编排上下游的调用关系。以下图所示:
当下一跳存在泳道节点时,测试流量进入泳道。反之,测试流量回流到主干。每一个节点重复上述过程。
命名服务另一个重要场景是服务的平滑发布,咱们与发布平台配合,控制发布流量的自动摘除与恢复,实现服务发布操做的自动化与透明化。具体流程以下图所示:
早期的发布流程,存在异常调用的风险,上线过程当中存在一段服务实例不可用的“时间窗口”,此时流量再进入可能致使调用失败,而后会报错。为保证发布的稳定性,须要操做人员手动进行流量排空,流程上效率低、易出错,浪费业务团队的时间。针对这项业务痛点,命名服务向发布系统提供针对服务实例的流量管控能力,实现进程重启前自动摘除并清空来源请求,升级完毕后,提供自动流量恢复的平滑发布功能。智能地解决发版过程当中的异常调用问题,提升公司的服务上线效率,下降了业务团队的运维成本。
弹性伸缩是容器一个很大的卖点。可是在伸缩过程当中有不少问题须要考虑,好比扩缩容策略,包括调用亲和度配置,路由均衡等等。命名服务和容器化合做,提供业务的上下游调用关系、分组设置信息、容器下线流量无损摘除等服务,同时保障伸缩服务注册及时、高效。以下图所示:
MNS服务数据对业务的赋能主要分为两个部分,一是将自身运行状态以业务可理解的SLA暴露出来,方便业务评估命名服务健康情况。对于命名服务来讲,SLA指标主要有推送成功率和推送耗时两种(其实,推送耗时也能够看作成功率的一个衡量维度,这里暂时不作太详细的区分)。
MNS 1.0精准量化运行情况的困难在于,一方面MNS的发布/订阅机制重度依赖ZK,受限于ZK的自身实现和链路上众多不一样组件的异构性,及时获取完整链路的推送行为数据很困难。另外一方面,因为节点数众多,全量采集服务发现数据,对公司的监控上报系统以及采集以后的计算也是很大的负担。
在MNS 2.0中,咱们首先在架构上显著弱化了ZK的地位,它基本上只做为一致性通知组件。咱们自研的MNS-Control能够充分DIY埋点场景,保证了主要推送行为抓取的可控性。其次,咱们采用了分级采样计算,在全面梳理了公司现有的服务节点数比例后,将典型的服务列表数划分为几个档次,好比1000个节点的服务为一档,100个又为一档,并建立相应的非业务哨兵服务,而后在不一样机房选取适量的采样机器按期注册+拉取来评估总体的运行状况。这样既作到了上报量的精简,又兼顾了上报数据的有效性。详细操做流程,以下图所示:
控制层周期性修改采样服务中的服务数据,触发服务发现的数据推送流程。
参与指标统计的机器节点,本地代理进程获取到注册信息推送后,上报送达时间到运维平台并由其写入存储层。
控制层对数据库中的数据进行聚合计算,最后上报监控系统展现指标数据。此外,经过与监控团队合做,解决全量部署的Agent埋点监控问题。
命名服务存储的服务信息有很高的业务价值,从中能够知道服务的部署状况、发布频次以及上下游拓扑信息等等。因此“赋能”的第二个部分在于,借助这些信息,咱们能够挖掘出业务服务部署运维上不合理的地方或风险点,不断推进优化,历来避免一些没必要要的损失。目前已经在推进的项目包括:
在架构上,MNS 2.0依赖DB和其它一些数仓介质,进行多种维度的数据上卷和下钻,并结合一些定制的风险策略逻辑去帮助业务发现和规避问题,目前这个事情也在进行中。
将来,美团命名服务主要会朝两个方向发展:
美团OCTO服务治理团队诚招C++/Java高级工程师、技术专家。咱们致力于研发公司级、业界领先的基础架构组件,研发范围涵盖分布式框架、命名服务、Service Mesh等技术领域。欢迎有兴趣的同窗投送简历至tech@meituan.com(邮件备注:美团OCTO团队)。
阅读更多技术文章,请扫码关注微信公众号-美团技术团队!