代码改变世界

开发中学习——物理节点之间数据一致性保证

2013-06-15 10:43  Peter87  阅读(257)  评论(0编辑  收藏  举报

项目开发中与大伙儿一起分享、讨论是项目中一件有趣、有意义的事情。有趣在于成员间你思我辩的认真劲儿,其中有怒、有羞、有笑,都是真情实感;有意义在于可以集思广义,在讨论中找到问题的症结所在,给出更优的解决问题的方法。今天下午的讨论让自己了解到自己在一个功能上实现的不足,同时也看到其他成员给出更好的方案,还意外的了解到了控制论当中的负反馈理论。我觉得这是一次在真实项目中使用到书本上理论的地方,有点激动,所以便决定记录下来。


特性背景

见下图,图中有四个PU,两个SU和一个CU,这些都是物理上独立的系统单元,各个物理单元之间通过光线进行通信。PU为基本的处理单元,完成系统控制数据和业务数据的处理,分别对应自身设备的管理和产品应用的业务;SU为交换单元,此种场景下主要是交换各个SU的控制和业务数据,可下联多个SU(图中为2个),可上联一个CUCU为通信单元,其作用与SU类似,也是作为PU数据交换之用,只是CU用来连接各个SU,也就是当业务场景需求的PU大于一个SU可以下联的PU的时候就必须要使用到CU

PU当中会存在多个通信子模块,当多个PU之间需要进行通信时就需要PU当中的通信子模块之间存在通信的链路。通常,在整个组网稳定之后,PU当中的产品应用会下发所有通信链路的创建请求给PU当中的链路管理模块,由链路管理模块来完成具体的链路创建。


图中的PU-A当中的通信子模块要与PU-D之间的通信子模块进行通信,就需要创建一条PU-A的通信子模块到PU-D中通信子模块当中的链路(粒度到PU中的通信子模块)。一条PU-APU-D的通信链路数据会保存在这一条链路路经的所有物理单元上(PU-ASU-LCUSU-RPU-D)。特性的工作就是要保证各个物理单元之间链路数据的一致行,有如下具体要求。


  • 当链路创建者需要删除某一条链路数据时,删除掉各个处理单元当中存放的该条链路对应的数据

  • 当链路路径上各个物理单元链路数据不一致的时候需要进行处理(通信子模块发生故障,链路数据残留,链路数据创建时导致的带宽不一致)

  • 当链路路径上物理单元之间通信有问题时需要删除链路的数据


最初方案

在特性的要求当作,第一条和第三条较容易处理,因为都有主动的触发源,链路创建者删除某一条链路数据时由链路创建者发起;物理单元通信有问题时有对应事件触发。而第二条则需要各个物理单元进行主动检测。

所以,在特性实现上要使用到定时检测机制:


  • 各个物理单元每隔一段时间向邻居的物理单元发起检测请求

  • 物理单元在接收到检测请求之后,查找本地有关请求物理单元的链路数据并回送响应

  • 物理单元在接收到检测响应之后,检查本端与被检测端的链路数据,如果不一致则进行删除操作


在检测处理当中,因为有效的链路数据依据“最小集”,也就是只会删除对端不存在而本端存在的链路数据,不会处理对端存在而本端不存在的链路数据,所以可以在基本上保证到一些不一致的链路数据得到清除。但是在一些情况下确会存在误删的情况。


创建路由的时候,各个物理单元之间的处理有一定的同步耗时。比如,创建一条PU-APU-D的链路(当前仅考虑单向),会经历下面的几个流程:


  • 第一步:检测PU-A的条件,看是否满足创建一条出口链路,满足继续下一步,不满足返回失败;

  • 第二步:检测SU-L的条件,继续第一步条件判断;

  • 第三步:检测CU的条件,继续第一步条件判断;

  • 第四步:检测SU-R的条件,继续第一步条件判断;

  • 第五步:检测PU-D的条件,如果满足则进行该链路的数据分配,并返回可创建消息给SU-R

  • 第六步:SU-R接收到可创建消息,进行该链路的数据分配,并将消息上报给CU

  • 第七步:CU接收到可创建消息,进行该链路的数据分配,并将消息上报给SU-L

  • 第八步:SU-L接收到可创建消息,进行该链路的数据分配,并将消息上报给PU-A

  • 第九步:PU-A接收到可创建消息后,进行数据分配,认为该跳链路创建成功,将创建成功消息回送给应用。


所以,如果当一条路由正在创建的时候发起了链路检测,由于链路正在创建当中,各个物理节点之间的状态随时可能变化,就会出现链路在检测时被误删的情况。比如,某条链路的可创建消息刚好回送到SU-L的时候PU-A发起了检测,此时检测响应消息当中携带了该跳链路的数据,但是PU-A当中不存在,所以这条新创建的链路会被删除掉。


考虑到上面叙述的这一种情况,在实现的时候使用了定时器平滑机制。处理是在接收到邻居的检测响应数据之后,先缓存该组数据,等到N秒的平滑时间之后,再次对比本地的链路数据和缓存的链路数据,如果仍旧不一致就进行删除处理(note:总结写到这里的时候发现这个定时器平滑机制本身就用错了,上面的本端数据变化的情况和下面的对段数据变化的情况其实就是一种情况)。

使用“反馈机制”

上面使用的定时器平滑看起来似乎解决了链路创建与链路检测同时发生导致的恶劣的链路误删,实际上仍旧没有解决问题。如此做能够保证本地的数据是最新的,但是缓存的数据本身可能在平滑的时间内变化,同样会出现使用了“错误”的链路数据,导致链路被误删。最为典型的就在SU-L回送链路可创建消息给PU-A的过程当中SU-L发起了检测,这个时候PU-A(对端)当中还没有该链路的数据,而SU-L(本端)当中则有,这一条链路在创建成功之后,却在进行链路检测的时候被误删除。


上面的链路被误删的情况归结于一点,便是因为平滑之后的获取操作为本端的数据而产生。经过讨论之后,如果在平滑之后再次获取对端的数据来进行对比并决策就能够很好的避免链路被误删的情况。这种主动检测机制大致如下:

  • 定时器超时之后,物理单元A主动向物理单元B发起检测请求;

  • A在收到B的响应之后,进行对比,将不一致的链路信息进行缓存并启动平滑定时器;

  • 平滑定时器超时之后,A再次发起请求获取B中有关A的数据;

  • 再次进行对比,如果缓存表中的某条链路依旧不一致则删除或者触发其他操作;如果缓存表中的某条链路变好则从缓存表当中移除;如果有新的不一致的链路则加入缓存表当中。

  • 等待下一轮定时器超时处理。


这种机制的提出者当时说想到这个方法得益于自动化当中的负反馈机制,并画了一个示意图(如下)。简单点说,就是让输出影响输入,慢慢的达到一个稳定的状态。

总结后记

当时讨论的时候我觉得很兴奋,因为觉得在实际开发当中使用到了书中讲到的理论。同时也觉得非常奇怪,我们学习书本上知识不就本是为了在实际生活当中进行运用并创造价值吗?怎么会如此大惊小怪,一副终于体会到了“课本中的理论还是有用的!”的样子?



2013/5/5