一种基于边追踪的分布式系统死锁检测方法
技术领域
本发明涉及程序死锁检测领域。更具体地,涉及一种基于边追踪的分布式系统死锁检测方法。
背景技术
随着大数据规模的日益增长和数据处理技术的不断发展,原有的单机系统无法满足当前快速、高效的数据处理需求。因此,越来越的多的商业系统开始向分布式的体系架构转变。其中,分布式系统中的死锁检测已成为并行程序错误检测的一个重要研究课题。
死锁的定义是系统中出现两个或者两个以上的进程在执行时出现互相等待对方而阻塞的状态。通常,分布式系统中的一些节点或多或少需要依赖其他节点上的共享资源,分布式节点之间的依赖关系产生的原因是节点上的进程有依赖关系。这就导致在分布式系统中可能会产生多个节点循环等待的状态,也就是发生了死锁。
死锁发生的必要因素有四个:(1)对于每个共享资源,一次是能给一个进程使用;(2)请求资源的进程无法强行从已经占有资源的进程中夺取资源而只能由资源的占有者主动释放;(3)节点在请求新的资源的同时不释放而是一直保持已经占有的资源;(4)所有请求资源的进程形成了一个循环的等待队列。当分布式系统发生死锁时,由于其中的进程相互等待,导致程序无法进一步执行,无法得到预期的运行结果,并且降低系统单位时间内可以处理的数据量。同时,参与死锁的进程不释放已经占有的资源,可能导致其它请求被占资源的进程也发生死锁。因此,分布式系统需要快速的检测并解决系统中出现的死锁问题。
现有算法通常使用等待图(Wait-for Graph,简称WFG)来分析死锁。在WFG中,每个顶点表示一个进程,而从顶点i到顶点j的一条有向边表示进程i向进程j请求资源,或者说进程i依赖于进程j。当一个进程依赖于多个进程时,WFG中的边还需要使用依赖信息(Request Condition,简称RC)来表示同一个顶点的不同边之间的关系。依赖信息是一个由节点id和逻辑运算符组成的表达式。例如,RCi=j∧k表示进程i的依赖信息。它的含义是进程i依赖于进程j和k,并且仅当进程j和k的依赖都得到满足时进程i的依赖才能得到满,即当RCj=true且RCk=true时,RCi=true。特别地,如果一个进程不依赖于其它进程,则RC=true。根据死锁检测算法对于WFG的不同表示,死锁检测算法可以划分为三大类:集中式、分布式和层次式。集中式的死锁检测算法需要在分布式系统中预先定义一个中心节点,其它节点上的依赖信息通过消息传递给中心节点,最终由中心节点构建WFG并对死锁进行检测。而分布式的死锁检测算法没有一个预先定义的中心节点。层次式算法则结合了集中式和分布式算法的优点。
当发生死锁时,系统中会有多个不同的节点同时发起死锁检测。每个在不同节点发起的检测同一个死锁的算法执行过程被称为一个实例。不同的算法实例可以使用优先级来区分。优先级是由算法实例发起节点的id和发起检测时刻的时间戳组成的一个二元组。不同的优先级可以通过节点id和时间戳来比较。首先,节点id大的优先级高。其次,时间戳小的优先级高。
目前的死锁检测算法还存在着不少问题。例如,集中式的死锁检测算法虽然易于实现,但是存在单点故障的问题。分布式的死锁检测算法需要大量额外的数据结构和消息来保证依赖信息的准确收集。而层次式的死锁检测算法虽然兼顾了两者的优点,但是其性能取决于底层采用的集中式算法,并且算法的实现更加复杂。
因此,需要提供一种基于边追踪的分布式系统死锁检测方法。
发明内容
本发明的目的在于提供一种基于边追踪的分布式系统死锁检测方法,主要解决死锁检测时消息数量过多和消息大小过大的问题,以实现相比于现有的方法减少死锁检测过程中消息传递的数量。
为达到上述目的,本发明采用下述技术方案:
一种基于边追踪的分布式系统死锁检测方法,通过引入消息计数器延后依赖消息的传递,该方法包括如下步骤:
S1、分布式系统中的各节点根据自身的状态初步判断分布式系统中是否已经发生死锁,初步判断发生死锁的节点作为死锁检测的发起节点开始执行死锁检测;
S2、发起节点向其自身所依赖的节点发送探针消息;
S3、收到探针消息的非发起节点将探针消息传递给其自身所依赖的节点;
S4、在非发起节点收到所有来自依赖于自身的节点的探针消息之后,非发起节点将其自身依赖消息发送给发起节点;
S5、发起节点收到所有非发起节点的依赖消息之后根据各节点之间的依赖关系判断是否发生死锁。
优选地,步骤S1进一步包括如下子步骤:
S1.1、分布式系统中的所有节点分别分配一个唯一的且大于0的节点id,设置各节点自身的优先级初始值,设置各节点自身的权值为0;
S1.2、各节点根据自身的状态初步判断分布式系统中是否已经发生死锁,初步判断发生死锁的节点作为死锁检测的发起节点开始执行死锁检测。
优选地,步骤S2进一步包括如下子步骤:
S2.1、发起节点根据当前的系统时间和其自身的id,生成一个大于优先级初始值的优先级值,并赋给探针消息;
S2.2、发起节点初始化并设置一个权值1,将权值1根据其自身所依赖的节点数平均分配并赋给每一个探针消息;
S2.3、发起节点向其自身所依赖的节点发送携带权值和优先级值的探针消息。
优选地,步骤S3进一步包括如下子步骤:
S3.1、收到探针消息的非发起节点比较探针消息中优先级值和自身的优先级值:
如果探针消息中的优先级值小于非发起节点自身的优先级值,则非发起节点丢弃探针消息;
如果探针消息中的优先级值大于非发起节点自身的优先级值,则非发起节点将自身的优先级值更新为探针消息中的优先级值,之后转入步骤Step3.2;
S3.2、非发起节点读取收到的探针消息中的权值,设置本地用于统计探针消息条数的计数器值为1;
S3.3、令n表示非发起节点所依赖的节点总数,非发起节点将收到的探针消息中的权值中的1/(n+1)取出作为该节点自身的权值;
S3.4、非发起节点将剩余的权值根据其自身所依赖的节点数平均分配并赋给每一个待其传递的探针消息;
S3.5、非发起节点向其依赖的节点传递携带权值和优先级值的探针消息。
优选地,步骤S4进一步包括如下子步骤:
S4.1、当探针消息的优先级与非发起节点自身的优先级相等时,非发起节点将探针消息中的所有权值累加至本地保留的权值上,并更新用于统计探针消息条数的计数器;
S4.2、当非发起节点收到的探针消息的条数等于依赖于其自身的节点数时,非发起节点向发起节点发送依赖消息。
优选地,步骤S5进一步包括如下子步骤:
S5.1、发起节点在收到依赖消息时,将依赖消息中的权值累加,同时将消息中的依赖信息存入一个依赖信息集合中,当权值累计为1时,转入步骤S5.2;
S5.2、发起节点遍历所有节点的依赖信息,对于任一节点,如果其依赖可以满足就将依赖信息对应的节点id加入一个集合A中,否则将依赖信息对应的节点id加入到另一个集合B中;
S5.3、发起节点检查集合B中所有的依赖信息,如果集合B中依赖信息包含集合A中的节点id,用true替换集合B中依赖信息中相应节点id所处的位置;
S5.4、对替换后的依赖信息,发起节点重复执行S5.2至S5.3,直到集合B的大小不变;
S5.5、如果集合B非空,则判断分布式系统中存在死锁。
通常,在使用优先级区分不同死锁检测算法的实例时,低优先级的实例会被高优先级的实例覆盖。在高优先级的实例执行之前,低优先级的实例也会发送部分消息。本发明通过给分布式系统中的非中心节点引入一个探针消息计数器,延后给中心节点发送依赖信息,从而减少在高优先级实例执行之前重复传递消息的数量。已有的基于探针消息的死锁检测算法至少需要两类消息——携带发起节点信息的探针消息和携带依赖信息的依赖消息。而本发明能够通过减少低优先级实例的消息重复传递次数,降低整个死锁检测方法执行过程中需要传递的消息的数量。
本发明的有益效果如下:
本发明所述技术方案通过引入消息计数器到死锁检测算法中的消息传递阶段,减少重复发送的消息数量。更具体地,当分布式系统中发生死锁时,多个死锁检测算法的实例会同时存在于系统中。对于其他已有算法,虽然低优先级的实例的执行会被高优先级的实例覆盖,但是低优先级的实例也会在被覆盖前发送不少消息。而在本发明中,非发起节点通过引入消息计数器,延后发送依赖消息。这样可以避免依赖消息在低优先级实例中的重复发送,能够降低整个分布式系统中传递的消息数量。
附图说明
下面结合附图对本发明的具体实施方式作进一步详细的说明。
图1示出基于边追踪的分布式系统死锁检测方法的流程图。
图2示出分布式系统对应的WFG示意图。
具体实施方式
为了更清楚地说明本发明,下面结合优选实施例和附图对本发明做进一步的说明。附图中相似的部件以相同的附图标记进行表示。本领域技术人员应当理解,下面所具体描述的内容是说明性的而非限制性的,不应以此限制本发明的保护范围。
如图1所示,本实施方式中的基于边追踪的分布式系统死锁检测方法包括如下步骤:
S1、分布式系统中的各节点根据自身的状态,例如操作是否超时,初步判断分布式系统中是否已经发生死锁,如果发生死锁,则初步判断发生死锁的节点作为死锁检测的发起节点开始执行死锁检测;
S2、发起节点向其自身所依赖的节点发送探针消息;
S3、收到探针消息的非发起节点将探针消息传递给其自身所依赖的节点;
S4、在非发起节点收到所有来自依赖于自身的节点的探针消息之后,非发起节点将其自身依赖消息发送给发起节点;
S5、发起节点收到所有非发起节点的依赖消息之后根据各节点之间的依赖关系判断是否发生死锁。
其中,
在步骤S5之后,如果系统发生死锁,则发起节点可以根据WFG使用死锁解决算法解决死锁。
步骤S1进一步包括如下子步骤:
S1.1、分布式系统中的所有节点分别分配一个唯一的且大于0的节点id,设置各节点自身的优先级值的初始值,设置各节点自身的权值为0;
S1.2、系统正常运行,各节点根据自身的状态初步判断分布式系统中是否已经发生死锁,如果发生死锁,即如果发生操作超时等事件时,则初步判断发生死锁的节点作为死锁检测的发起节点开始执行死锁检测。
步骤S2进一步包括如下子步骤:
S2.1、发起节点根据当前的系统时间和其自身的id,生成一个大于优先级初始值的表示优先级的优先级值,并赋给探针消息,其中,优先级值为由发起节点的id和当前的时间戳组成的二元组;
S2.2、发起节点初始化并设置一个权值1,将权值1根据其自身所依赖的节点数平均分配并赋给每一个探针消息;
S2.3、发起节点向其自身所依赖的节点发送携带权值和优先级值的探针消息。
步骤S3进一步包括如下子步骤:
S3.1、收到探针消息的非发起节点比较探针消息中优先级值和自身的优先级值:
如果探针消息中的优先级值小于非发起节点自身的优先级值,则非发起节点丢弃探针消息;
如果探针消息中的优先级值大于非发起节点自身的优先级值,则非发起节点将自身的优先级值更新为探针消息中的优先级值,之后转入步骤Step3.2;
S3.2、非发起节点读取收到的探针消息中的权值,设置本地用于统计探针消息条数的计数器值为1;
S3.3、令n表示非发起节点所依赖的节点总数,非发起节点将收到的探针消息中的权值中的1/(n+1)取出作为该节点自身的权值;
S3.4、非发起节点将剩余的权值根据其自身所依赖的节点数平均分配并赋给每一个待其传递的探针消息;
S3.5、非发起节点向其依赖的节点传递携带权值和优先级值的探针消息。
步骤S4进一步包括如下子步骤:
S4.1、当探针消息的优先级与非发起节点自身的优先级相等时,非发起节点将探针消息中的所有权值累加至本地保留的权值上,并更新用于统计探针消息条数的计数器;
S4.2、当非发起节点收到的探针消息的条数等于依赖于其自身的节点数时,也即不会收到新的探针消息时,非发起节点向发起节点发送依赖消息。
步骤S5进一步包括如下子步骤:
S5.1、发起节点在收到依赖消息时,将依赖消息中的权值累加,同时将消息中的依赖信息存入一个依赖信息集合中,当权值累计为1时,转入步骤S5.2;
S5.2、发起节点遍历所有节点的依赖信息,对于任一节点,如果其依赖可以满足就将依赖信息对应的节点id加入一个集合A中,否则将依赖信息对应的节点id加入到另一个集合B中;
S5.3、发起节点检查集合B中所有的依赖信息,如果集合B中依赖信息包含集合A中的节点id,用true替换集合B中依赖信息中相应节点id所处的位置;
S5.4、对替换后的依赖信息,发起节点重复执行S5.2至S5.3,直到集合B的大小不变;
S5.5、如果集合B非空,则判断分布式系统中存在死锁。
下面代入一个具体的分布式系统对基于边追踪的分布式系统死锁检测方法作进一步地说明。
图2所示为某个分布式系统的WFG。图2中的一个圆圈表示系统中的一个节点,圆圈中的字母表示节点的id,节点之间的有向线段表示依赖关系。
对图2所示的分布式系统实施基于边追踪的分布式系统死锁检测方法的具体过程如下:
步骤1、节点a发生超时,认为系统发生了死锁,因此,节点a开始执行本算法的一个实例;
步骤2、节点a分别给节点b和c发送一条探针消息,其中,探针消息包含节点a的id和一个权值1/2;
步骤3、当节点b收到来自节点a的探针消息,它将先存储一部分权值,在此处为1/6,然后分别向节点d和节点e发送一个探针消息;节点b发送的探针消息中包含发起节点a的id和一个新的权值1/6;同时,因为依赖于b的节点只有a,并且b已经收到来自a的探针消息,所以节点b向发起节点a发送一条依赖消息;依赖消息中包含一个逻辑表达式和保留在节点b的权值;
步骤4、当节点c收到探针消息时,它向节点e发送一个权值为1/4并且携带了发起节点id的探针消息;同时,因为节点c已经收到所有来自依赖于它的节点的探针消息,所以节点c会将自己的依赖信息和保留的1/4权值通过依赖消息发送给发起节点a;。
步骤5、当节点a收到依赖消息时,它将其中的权值累加在本地变量中,并把依赖信息存入一个集合RC当中;因此,当节点a收到来自节点b和c的依赖消息后,节点a的权值为5/12并且集合RC中包含了节点b和c的依赖信息;
步骤6、当节点d收到来自节点b的探针消息时,它会给e发送一个权值为1/12的探针消息,然后给节点a发送一个携带了自身依赖信息和1/12权值的依赖信息;
步骤7、当节点e先收到来自节点c的探针,那么它先保存自身的权值1/8,然后向节点a发送权值为1/8的探针消息;
步骤8、由于节点e还没收到所有来自依赖于它的节点的探针消息,所以它会等待来自节点b和d的探针消息;此后,当节点e收到来自于节点b和d的探针消息时,它会向节点a发送权值为3/8的依赖消息;
步骤9、当发起节点a收到来自于节点d和e的依赖消息之后,权值累计的和已经为1,并且已经收集完WFG中各个节点的依赖信息;所以,发起节点a可以开始死锁的检测与解决。
显然,本发明的上述实施例仅仅是为清楚地说明本发明所作的举例,而并非是对本发明的实施方式的限定,对于所属领域的普通技术人员来说,在上述说明的基础上还可以做出其它不同形式的变化或变动,这里无法对所有的实施方式予以穷举,凡是属于本发明的技术方案所引伸出的显而易见的变化或变动仍处于本发明的保护范围之列。