当前位置: 首页 > 科技观察

携程ServiceMesh性能优化实践

时间:2023-03-16 16:37:03 科技观察

作者简介本文作者左思、少宇、ShirleyBo来自携程云容器团队。类基础设施服务的云原生化。团队负责K8s容器平台的研发和优化,重点推动基础设施云原生架构的升级,以及创新产品的研发和落地。一、背景为支持业务的快速发展,自2017年起,携程逐步推进应用容器化改造和业务云化工作。同一时期,携程的技术架构经历了从集中式单体应用到分布式微服务的演进过程。随着Kubernetes的不断发展和推广,ServiceMesh在近几年变得非常流行。ServiveMesh之所以越来越受欢迎,除了提供服务治理、安全、可观察性等更多核心能力外,从架构设计层面解决了上述痛点。服务治理能力基于Sidecar模型。下沉到数据面解决了SDK升级和多语言的问题。对于负载均衡、断路器、限流等策略配置,由控制平面统一管理配置,并下发至数据平面生效。在整体架构的云技术方案选择上,我们权衡了各种方案的功能完备性、架构可扩展性、改造维护成本、社区发展等,最终选择了基于Istio构建ServiceMesh平台治理方案。1.1携程ServiceMesh开发从2020年年中开始,我们依托K8S基地的能力,对ServiceMesh技术进行预研,深度定制Istio,并与携程框架部门合作进行小规模试点。到2021年底,接入600+非核心应用,为ServiceMesh最终落地携程奠定基础。目前已接入生产环境2000个应用(业务POD数量近1W),预计下半年将推进核心应用的接入。1.2携程ServiceMesh数据性能在早期的应用接入过程中,在Istio稳定性方面(主要是性能方面)梳理了以下问题:控制面并发性能:pilot对象处理的并发性能是否满足平台要求?控制面配置下发的时效性:配置下发的时延和准确性能否满足业务需求?本文主要分享在当前体量下如何解答以上问题,让控制面能够顺利支持大型sidecar的落地。经过如下优化,测试域(IstioCR级别为1W+)如下图所示:从实际生产来看,ServiceEntry的处理效率提升了15倍左右。从测试域来看,整体的initContext延迟从原来的P9930s变成了现在P99的5-10秒。从测试域来看,整体优化水平从原来的P9930s+变成了现在P9915s左右(这是全推水平,15s的结果是平衡资源使用和推流效率调优的目标值,这里PILOT_DEBOUNCE_AFTER设置为10s)启用增量推送后,测试域实例推送的推送效果从10-30s减少到2.5s左右携程目前Istio版本为1.102.ServiceMesh优化思路与挑战2.1现状携程ServiceMesh的服务目标可以用一句话概括:通过横向扩展业务服务,支持10000级。为完成上述目标,团队面临以下挑战:当前Istio对象处理性能等方面无法满足平台要求配置交付的延迟和准确性无法满足业务需求前期和中期之后,深入研究Istio架构及上线前测试性能Pre-research,核心问题集中在以下几点:istio对象处理性能低:处理ServiceEntry时缺乏并发,WorkloadEntry计算耗时高Selector模式等istio配置推送性能低下:配置推送时全处理对象延长投递延迟,会随着Istio对象的增长近乎线性增加2.2优化实践下面主要分享遇到的性能问题携程及对应的优化方向:对象处理性能目前,Istio使用s一个内部队列来处理每个Object类事件,属于线性处理过程,效率相对较低。社区提供了用于处理的名称空间过滤器以缓解性能问题。但是对于Istio相关的对象,并没有实现基于命名空间的隔离,所以效率的提升并没有达到预期。推送性能xDS是istio控制平面和数据平面envoy之间的通信协议,其中x代表多个协议的集合,xDS可以简单理解为网格中服务发现数据和治理规则的集合。xDS数据量的大小与网格大小正相关。目前istio采用全量交付策略来交付xDS,即网格中的所有sidecar都会将整个网格中的所有服务发现数据都存储在内存中。在服务实例数量较多的情况下,全量投放会影响Pilot和Sidecar的性能和稳定性。Istio虽然在不断进化的过程中引入了一些Scoping机制,但它是Sidecar的CRD。这种配置可以显式定义服务,但是这种Scoping方案仍然不能满足业务端对推送延迟的期望。首先简单介绍一下Istio的推送流程:注:这里使用海东的推送源码分析图。根据上图结合源码可以看出,StreamAggregatedResources会与当前的Proxy建立连接,并创建一个接受请求的reqChannel。同时新开一个协程receiveThread处理客户端发起的请求,期间调用s.globalPushContext().InitContext(s.Env,nil,nil)初始化数据。InitContext需要处理所有IstioCR的全量数据(如VirtualServices、DestinationRules、EnvoyFilters、SidecarScopes等),这个操作耗时较长,因为上述对象在测试环境中的量级约为2w,导致P99的执行时间约为28s。从con.pushConnection获取到pushEv事件后,调用s.pushConnection()进行处理,判断是否是全量推送:ifpushRequest.Full{//UpdateProxywithcurrentinformation.s.updateProxy(con.proxy,pushRequest.Push)}其中updateProxy更新当前代理信息,主要逻辑如下:func(s*DiscoveryServer)updateProxy(proxy*model.Proxy,push*model.PushContext){s.setProxyState(proxy,push)ifutil.IsLocalityEmpty(proxy.Locality){...iflen(proxy.ServiceInstances)>0{proxy.Locality=util.ConvertLocality(proxy.ServiceInstances[0].Endpoint.Locality.Label)}}}func(s*DiscoveryServer)setProxyState(proxy*model.Proxy,push*model.PushContext){proxy.SetWorkloadLabels(s.Env)proxy.SetServiceInstances(push.ServiceDiscovery)...proxy.SetSidecarScope(push)proxy.SetGatewaysForProxy(push)}链接在setProxyState方法中获取SidecarScope等相关信息。基于以上介绍,可以明确以下优化方向:Istio虽然对K8S对象实现了命名空间级别的隔离,但没有对IstioCR对象实现命名空间级别的隔离。在InitContext方法中,Push()这么慢,主要是因为req。Full全量推送时,需要初始化PushContext。在初始化PushContext的过程中,需要调用initServiceRegistry、initEnvoyFilters、initSidecarScopes等,耗时较多。2.2.1Pilot性能优化基于Namespace的资源隔离Istio虽然对K8S对象实现了命名空间级别的隔离,但是没有对IstioCR对象实现命名空间级别的隔离。基于此,内部团队在Istio1.10.3版本对IstioCR对象实现了命名空间隔离,使其影响范围控制在指定的命名空间下,其他用户相互独立操作IstioCR。干扰,并且可以大大减少IstioEvent事件的处理,加快Pilot的启动速度,提高事件处理效率,促进配置下发效率。在CRClient结构中,新的namespaceFilter和其他相关字段定义如下://ClientisaclientforIstioCRDs,implementingconfigstorecache//用于Istio配置上的CRUD操作,以及事件处理configchangestypeClientstruct{...namespaceInformerv1.NamespaceInformernamespaceFilterfilter.DiscoveryNamespacesFilter...}截至目前,携程Mesh平台主要分为两个命名空间:SLB和SOA。基于命名空间进行隔离后,预计效率提升50%左右。ServiceEntryStore改造了ServiceEntryStore的数据处理性能,主要有以下几点:其中有一个步骤,会全量更新实例的索引,也就是说其中一个服务发生了变化,它会更新实例的索引allservices,这是一个量级级别的写法,放大了WorkloadEntry和ServiceEntry之间的关联查询耗时。随着对方的数量逐渐变大,configController的Queue队列是线性处理的,效率低下。因此,携程将ServiceEntry对象从线性处理转变为Concurrent处理,同时舍弃了WorkloadEntry结构,选择直接使用ServiceEntry,由业务方的operator管理Endpoint方法对应的ServiceEntry,以优化处理性能。从实际生产效率来看,ServiceEntry的处理效率提升了4倍左右。EnvoyFilter的增量改造通过上面的介绍,我们可以看出Push()这么慢,主要是因为req.Full在做全量推送的时候,需要初始化PushContext。如果物体的量级很大,计算时间将呈指数增长。对于EnvoyFilter的全量处理,不涉及其他对象,可以定义EnvoyFilterController结构运行在Controller模式下,实现全量变化。结构体定义如下:[string][]*wrapEnvoyFilterWrapper}Sidecar延迟和按需计算在InitContext方法中,除了EnvoyFilter耗时之外,initSidecarScopes也是耗时的。从代码中我们可以看出Sidecar有两种,一种有WorkloadSelector,一种没有。如果没有Selector,它将对该命名空间下的所有服务生效。如果没有手动创建默认的Sidecar,Pilot会通过DefaultSidecarScopeForNamespace为当前命名空间创建一个默认的Sidecar,遍历网格中的所有服务,写入SidecarScope。initSidecarScopes循环计算如下:sidecar个数x(egressConfigs个数x(selectVirtualServices耗时+selectServices耗时)+out.EgressListeners个数x(listener.services个数+listener.virtualServices个数...))因为SidecarScope涉及其他CR对象的结果,因此不能简单的从全量变成增量,而是可以通过延迟计算和按需计算来提高效率。延迟计算主要是将initSidecarScopes的计算逻辑移到push阶段。按需计算是指不需要计算所有的sidecars,只需要根据链接的代理进行计算。通过以上优化,可以进行如下针对性调整:如果集群中服务比较多,为每个应用创建一个sidecar,防止所有服务信息都推送给envoy,导致envoyOOM。经过以上优化,InitContext的处理时间可以从P99的30s减少到P99的5s左右。此时配置推送效率提升了5倍左右,那么setProxyState的耗时会变大,CPU占用率会降低。将呈指数增长,可以通过以下配置进行优化。2.2.2Pilot配置优化开启XDS增量推送通过为istiod配置PILOT_ENABLE_EDS_DEBOUNCE环境变量,我们开启istiod的增量推送,无需等待全推。减少推送量配置istiod的PILOT_FILTER_GATEWAY_CLUSTER_CONFIG环境变量为“true”,这样Istio只会推送Gateway需要的服务信息。这种配置会大大减少每次推送的量。启用该功能后,集群中istiod向Gateway推送的服务信息每次减少90%。关闭Headless,将istiod的PILOT_ENABLE_HEADLESS_SERVICE_POD_LISTENERS环境变量配置为“false”,因为headlesssvc对应的endpoints发生了变化,会触发全推的行为。提高吞吐量默认情况下,单个istiod的并发推送数只有100个,这可能会导致配置在更大的集群中延迟生效。istiod环境变量PILOT_PUSH_THROTTLE可以配置这种并发。建议根据集群大小进行配置。避免频繁推送PILOT_DEBOUNCE_AFTER和PILOT_DEBOUNCE_MAX是配置istioddebounce的两个参数。默认配置是100ms和10s,这意味着当集群中发生任何事件时,Istio将等待100ms。如果启用了EDS,增量推送将不会等待。如果100ms内没有事件进来,Istio会立即触发推送。否则,Istio会再等待100ms,重复此操作,直到总等待时间达到10s,才会强制触发推送。在实践中,这两个值可以适当调整以匹配集群大小和实际应用。携程内部将PILOT_DEBOUNCE_AFTER增加到10s,避免频繁推送对性能的影响,同时也避免极端情况下推送不及时导致的503问题。三、ServiceMesh的未来展望控制面的重点是解决规模问题。后续控制面将在以下几个方面进行深入探索:控制面将去除对k8s资源的依赖,将推送时间降低到秒级,满足更大规模的需求。接入使用NDS实现DNS解析功能,避免了搜索域的多次查询,提高了Mesh的易用性。团队将与社区深度合作,密切关注控制面增量推送等特性。未来会优先考虑控制面的稳定性性能增强,比如以下功能:连接限流:通过限流功能,大量Sidecars同时连接到同一个Pilot实例的风险减少,减少服务风暴的概率。Circuitbreaker:根据生产场景的压测数据,计算单实例Pilot可服务的Sidecar上限。超过上限后,新的连接将被Pilot拒绝。ServiceMesh是云原生领域的下一代微服务技术。经过两年多的探索和进化,携程已经完成了多语言、多场景的业务落地。它实际上已经展示了ServiceMesh在流量控制和系统扩展性方面的优势。服务治理能力延伸至基础设施层,中间件与业务系统高度解耦的可行性。未来,携程将在总结前期非核心应用ServiceMesh改造的基础上,逐步推进核心应用落地,同步打磨完善平台能力,全面提升稳定性,并提供最佳实践和相关参考为行业实施服务网格。

最新推荐
猜你喜欢