服务依赖发现简介
随着分布式软件系统的规模与复杂度的增加,分布式软件系统所提供的服务往往会被拆分为多个子服务。分布式软件系统通过不同子服务之间的组合与协作,在稳定提供多样化服务的同时,提高了系统设计、开发与更新的效率。但与此同时,系统中错综复杂的依赖关系导致分布式软件系统容易牵一发而动全身。单个服务的故障会在分布式软件系统中迅速传播,导致大量的服务失效,且故障根因难以定位;单个服务的升级与变动可能会影响其他服务的正常运行,造成性能下降或系统故障。准确地发现分布式软件系统中的依赖关系不仅能够及时定位故障的根因,有效降低故障带来的损失,保障系统迭代更新时服务的稳定,也有利于在系统部署的过程中根据服务依赖优化服务的部署策略,降低服务的响应时间。
01
什么是服务依赖发现
服务依赖发现即发现分布式软件系统中的依赖关系的过程。
服务:由于在分布式系统中,没有一个通用且标准的关于“服务”的定义,所以在不同的研究工作中,服务依赖发现中的“服务”的具体形式可能有所不同,但基本可以划分为三类:IP&Port,组件,虚拟机。在文献[2, 3, 6, 7, 8, 9]中,服务或被定义为(IP,Port)这样的二元组,或被定义为(IP,Port,Protocol)的三元组,因此服务依赖发现即发现(IP,Port)/(IP,Port,Protocol)之间的依赖关系的过程。在文献[5, 10, 11, 12]中,服务即组件,组件是分布式软件系统中可被独立部署的最小单元。而将虚拟机作为服务依赖发现的研究对象[1, 4]时,通常是基于假设:每个虚拟机中仅部署一个服务(IP&Port或组件),因此虚拟机之间的依赖关系也就代表服务之间的依赖关系。
依赖:服务依赖发现中的依赖关系即指一个服务为完成对该服务的请求的响应,对其他服务的调用关系。但文献[2][3]与文献[7]对服务依赖关系进行了延伸,将依赖关系划分为直接依赖(local-remote dependency)关系与间接依赖(remote-remote dependency)关系。直接依赖关系即一个服务为完成对该服务的请求的响应,对其他服务的调用关系。如一个交易服务,会调用数据库服务来完成一笔交易的请求,那么交易服务直接依赖于数据库服务。间接依赖关系是当客户端在请求服务S2之前,必须先请求服务S1时,服务S2对S1的依赖关系。如一个登陆服务,客户端调用登陆服务之前,必须先调用DNS服务查询登陆服务的IP,那么登陆服务间接依赖于DNS服务。除此之外,通常会有一定的算法来赋予依赖关系一个数值来衡量依赖关系的强弱或依赖关系成立的可能性。
发现:服务依赖的发现早期主要依靠专家知识与人工标记,但这种方式不仅消耗大量的时间与精力,且无法应对规模与复杂度不断增长的大规模分布式系统,也无法及时反应系统的更新升级等导致的依赖关系的变化,因此本文主要探讨的是自动化的服务依赖发现技术。自动化的服务依赖发现技术根据不同的标准可以有不同的划分方法,文献[3]按照是否在发现过程中产生除系统本身运行时生成的数据之外的其他数据将服务依赖发现技术分为主动发现与被动发现两类。文献[2]则按照服务依赖发现技术其工作的层次将服务依赖发现技术分为网络层的与应用层两类。文献[1]则按照服务依赖发现技术的工作原理将其分为基于代码注入,基于网络流量推断与基于系统日志挖掘三类。
02
服务依赖发现技术及相关工作介绍
本文按照服务依赖发现技术所基于的数据,将服务依赖发现技术划分为基于监控数据,基于网络流量,基于系统日志,基于请求追踪数据四类。
1. 基于监控数据
基于监控数据的服务依赖发现技术通常利用分布式软件系统中每个服务的一个或多个监控指标,通过一定的方法来计算不同的服务的一个或多个监控指标在时间序列上的相似度,任意两个服务之间的相似度即服务依赖的强弱。这些监控数据往往与服务的资源消耗,请求数量与响应时间有关。这些技术通常假设:存在依赖关系的两个服务,在一定的时间窗口内,其监控指标的值存在较强的相关性与相似性。如图1中展示的在Hadoop及RUBiS中相互依赖的组件其TCP连接数量在时间轴上的相似性[1]。
图 1 Hadoop与RUBiS中服务之间TCP 连接数量的相关性
文献[1]便收集分布式软件系统中每个组件的TCP/UDP连接数量及其资源使用数据(CPU_user, CPU_system, mem_used, rd_sec/s, wr_sec/s, rxpck/s, txpck/s),通过公式(1)对每个监控指标的每个时刻的值进行归一化(其中Xi 代表监控指标X的第i个时刻的值,max(Xi)与min(Xi)分别代表监控指标X在一定时间窗口内的最大值与最小值。
在对TCP/UDP连接数量进行一定的降噪处理后,根据公式(2)中的皮尔森积矩相关系数(Pearson product-moment correlation coefficient)计算方法和公式(3)计算任意两个组件在某一监控指标上的相似度。
(2)
(3)
获取任意两个组件之间在8个监控指标上的相似度之后,文献[1]又提出了一种基于熵的不同监控指标的权重计算方法iEntropy,从而使用8个监控指标相似度的权重加和来作为任意两个组件之间的相似度。然后作者又提出一种聚类算法HiKM(hierarchical and iterative k-means)根据组件之间的相似度来对组件进行聚类,聚到同一簇的任意两个组件之间存在依赖关系,其依赖关系的强弱即两者之间的相似度。
相比于文献[1],文献[4]则仅使用每个服务的CPU使用量的监控数据,使用Auto-regressive(AR)模型对每个服务的CPU使用的峰值(spike)之间的关系进行建模,然后使用欧式距离(Euclidean Distance)衡量不同服务之间的AR模型的相似度,进而使用K-means算法根据不同服务之间的相似度将服务进行聚类。同[4]相似,聚到同一簇的任意两个组件之间存在依赖关系,其依赖关系的强弱即两者之间的相似度。文献[10]则利用监控工具监控每一个请求进入一个组件和离开一个组件的时间戳,将其作为一个事件,通过在时间上计算不同组件上的事件的包含关系(调用关系)和统计这种包含关系的置信度(包含关系出现的频率)来发现两个组件之间的依赖关系。
这类方法的问题通常存在于其假设上,若相互依赖的两个服务其在监控指标上没有较强的相似关系,则会错误的生成依赖关系。且其时间窗口大小的选择与监控指标的选择也存在需大量人工调试的问题。而文献[4]则对监控工具的要求更高,要求能够发现请求进入一个组件和离开一个组件的时间及请求的类型,实用性较低。
2. 基于网络流量
基于网络流量的服务依赖发现技术通常通过拦截并解析每个服务的网络交互数据,提取其源IP,源端口,目标IP,目标端口,基于这种不同服务(IP,port)或(IP,port,protocol)之间的交互关系建立不同服务之间的依赖关系。
文献[9]便是这种技术的一个体现,利用每个从网络流量中提取的(localIP,localPort,remIP,remPort,proto)这样一个五元组,来直接获取两个服务(localIP,localPort,proto)与(remIP,remPort,proto)之间的依赖关系。
文献[8]则在文献[9]的基础上提出了Inference Graph模型来表示分布式软件系统中所有服务的依赖关系,模型中包含三类节点:Root-cause节点,Observation节点与Meta节点。Root-cause节点是不依赖于其他任何服务的服务节点。Observation节点是指发起服务请求的客户端。Meta节点又分为三类,noise-max,selector和failover节点。Noise-max是对某一类服务的抽象所生成的节点,selector是负责负载均衡或路由的节点,failover是负责失败重启及容错的节点。图2展示了在访问分布式系统中的文件服务时的部分Inference Graph及其表示的服务依赖关系。除此之外,其还在文献[9]的基础上提出了计算服务依赖关系强弱的计算方法,即统计在一定时间窗口内的所有网络流量数据(五元组)中,服务A与服务B在一定的interval内被一起调用的频率。
图2 访问文件服务时的Inference Graph及其表示的服务依赖
文献[7]则在文献[9]的基础上使用信号处理与统计学方法发现服务之间的依赖关系。文献[7]基于假设:如果两个服务之间存在依赖关系,则两个服务的延迟分布delay distribution不会是随机的。该技术以3s为时间窗口,获取每个节点上在3s内从网络流量提取到的(localIP,localPort,remIP,remPort,proto)这样的五元组,并计算这2秒内任意两个五元组如(localIP1,localPort1,remIP1,remPort1,proto1)与(localIP2,localPort2,remIP2,remPort2,proto2)所可能包含的所有直接依赖关系如(localIP1,localPort1,proto1)->(remIP2, remPort2,proto2)与间接依赖关系如(remIP1, remPort1,proto1)->( remIP2, remPort2, proto2)。然后根据两个服务之间的起始时间的delay的均值与标准差,选取合适的delay粒度,画出两个服务之间的delay distribution图并使用信号处理方法进行去噪,当检测到两个服务之间的delay distribution不是随机时,则认为两个服务之间存在依赖关系,如图3所示。
图3 相互依赖的服务之间的delay distribution和非相互依赖的服务之间的delay distribution
此类方法仅能用于发现(IP,Port)/(IP,Port,Protocol)所代表的服务之间的关系,当前的相关工作也主要集中在TCP网络流量的拦截。
3. 基于系统日志
基于系统日志的服务依赖发现技术通常利用分布式软件系统的日志,通过统计方法发现日志之间的关联关系,并根据日志与服务之间的对应关系,来推断服务之间的依赖关系。
文献[6] 利用分布式系统中特殊的日志(带有IP与端口信息的网络通信日志,IP包含sourceIP与destIP),通过在一定时间窗口内发现日志之间的父子关系,结合日志与服务(IP,Port)的对应关系,构建服务之间的依赖(调用)关系。其具体过程如下:每一条通信日志代表一个消息m,m的时间戳为t,则在时间窗口[t-th, t]内寻找destIP为m的sourceIP的消息集合作为parent message candidates集合N。对于m所代表的一个服务S,通过对S的p次消息的统计,得到p个parent message candidates集合。然后通过启发式算法,计算每个parent message candidates集合中的消息的sourceIP所代表的服务在所有parent message candidates中出现的次数,次数出现最高的服务即S的父服务P,即父服务P调用服务S。通过启发式算法删除包含服务P的parent message candidates集合,再次计算次数出现最高的服务Q,循环上述步骤直至所以parent message candidates集合被删除,即获得S的父服务集合,集合中的所有服务依赖于S服务本身。
文献[5]与文献[6]方法类似,其首先对日志进行模版提取,将每一条日志消息表示为log key(模板+变量),然后计算不同组件之间的任意两个log key之间的关联关系(即在所有的日志数据中,两个log key在一定时间窗口内一起出现的频率)。log key之间的关联关系的方向根据贝叶斯决策理论产生。挖掘出log key之间的关联关系及其方向后,结合log key与组件之间的对应关系,确定组件之间的依赖关系。
此类方法对日志的格式有一定的要求,如文献[5]要求请求在进入一个服务与离开一个服务时都产生一条日志,且日志中需要包含sourceIP与destIP,而文献[6]则要求log key之间须存在值相同的变量,否则无法正确发现log key之间的关联关系。
4. 基于请求追踪数据
基于请求追踪数据的服务依赖发现技术需要分布式追踪技术作为支撑,关于分布式追踪技术的具体内容可以参考之前的文章(
分布式追踪系统简介
)。通过分布式追踪技术,生成一次服务请求在分布式软件系统中的请求执行路径,每一个请求执行路径中都包含了准确的但不全面的服务依赖信息,而将多个请求执行路径中的服务依赖信息进行合并便能准确地获取分布式软件系统完整的服务依赖信息。如文献[2]中,通过提取网络消息中包含的request ID,可以生成以服务为节点的一次服务请求的执行路径,而请求路径中服务之间的因果关系即服务之间的依赖关系,如图4所示。其他的分布式追踪技术也非常容易应用到服务依赖发现的场景中,而不需要依赖统计推断或其他的数据挖掘方法。此类方法发现的服务依赖准确率相对较高(主要依赖于底层的分布式追踪技术是否能够产生准确的请求执行路径),但可能会因为分布式追踪技术而需要进行代码修改并引入额外的系统开销。
图4 一个以服务为顶点的请求执行路径与系统中的服务依赖
03
总结
本文介绍了服务依赖发现的含义,并根据不同服务依赖发现技术所依赖的数据不同,对相关研究工作进行了分类和简要介绍。如果任何错误和问题,欢迎联系本公众号进行探讨。
参考文献
[1] Yin J, Zhao X, Tang Y, et al. CloudScout: a non-intrusive approach to service dependency discovery[J]. IEEE Transactions on Parallel and Distributed Systems, 2017, 28(5): 1271-1284.
[2] Novotny P, Ko B J, Wolf A L. On-demand discovery of software service dependencies in MANETs[J]. IEEE Transactions on Network and Service Management, 2015, 12(2): 278-292.
[3] Zand A, Vigna G, Kemmerer R, et al. Rippler: Delay injection for service dependency detection[C]//INFOCOM, 2014 Proceedings IEEE. IEEE, 2014: 2157-2165.
[4] R. Apte, L. Hu, K. Schwan, and A. Ghosh, “Look who’s talking: Discovering dependencies between virtual machines using cpu utilization,” in Proc. 2nd USENIX Conf. Hot Topics Cloud Computing, 2010, pp. 17–17.
[5] Lou J G, Fu Q, Wang Y, et al. Mining dependency in distributed systems through unstructured logs analysis[J]. ACM SIGOPS Operating Systems Review, 2010, 44(1): 91-96.
[6] Kitajima S, Matsuoka N. Inferring Calling Relationship Based on External Observation for Microservice Architecture[C]//International Conference on Service-Oriented Computing. Springer, Cham, 2017: 229-237.
[7] Chen X, Zhang M, Mao Z M, et al. Automating Network Application Dependency Discovery: Experiences, Limitations, and New Solutions[C]//OSDI. 2008, 8: 117-130.
[8] Bahl P, Chandra R, Greenberg A, et al. Towards highly reliable enterprise network services via inference of multi-level dependencies[C]//ACM SIGCOMM Computer Communication Review. ACM, 2007, 37(4): 13-24.
[9] Bahl V, Barham P, Black R, et al. Discovering dependencies for network management[J]. 2006.
[10] Gupta M, Neogi A, Agarwal M K, et al. Discovering dynamic dependencies in enterprise environments for problem determination[C]//International Workshop on Distributed Systems: Operations and Management. Springer, Berlin, Heidelberg, 2003: 221-233.
[11] Bagchi S, Kar G, Hellerstein J. Dependency analysis in distributed systems using fault injection: Application to problem determination in an e-commerce environment[J]. 2001.
[12] Brown A, Kar G, Keller A. An active approach to characterizing dynamic dependencies for problem determination in a distributed environment[C]//Integrated Network Management Proceedings, 2001 IEEE/IFIP International Symposium on. IEEE, 2001: 377-390.
作者简介
杨勇,软件工程专业
博士研究生四年级
研究方向,分布式追踪
往期文章汇总
谈谈区块链
分布式追踪系统简介
软件社区中的Tag推荐
Ceph分布式存储系统简介
领取专属 10元无门槛券
私享最新 技术干货