DigitalTwins/data/chapter3.tex
2023-04-10 06:58:52 +08:00

196 lines
14 KiB
TeX
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

\chapter{分布式消息网络设计}
\section{概述}
现代软件应用程序通常不是孤立存在的而是依赖于服务或远程实体提供的信息。在这种分布式架构中集成至关重要。近年来消息传递已成为解决分布式系统挑战的主流方案例如网络不可靠性、生产者与消费者之间的紧密耦合以及应用的异质性。得益于强大的社区支持以及对标准和集成的共同努力消息代理现已成为许多项目和服务的传输层构建模块近年来涌现出许多消息服务如MQTT、RabbitMQ、RocketMQ和Kafka等。
现代分布式消息网络是一种基于分布式系统和消息传递模式的网络架构,支持高可用性、可扩展性和可靠性的通信。这种网络通常由多个节点组成,这些节点可以是物理机器、虚拟机或容器。
消息网络的核心是消息队列它采用一种异步通信模式在多个节点之间传递消息。消息队列通常包括生产者、消费者和代理broker其中生产者将消息发送到队列中消费者从队列中接收消息进行处理代理作为消息队列的中心节点负责维护队列、路由消息和确保消息的可靠传递。
现代分布式消息网络通常采用发布/订阅模式或点对点模式进行消息传递。在发布/订阅模式中消息生产者将消息发布到主题topic消费者订阅感兴趣的主题并接收相应的消息。在点对点模式中消息生产者将消息发送到队列只有一个消费者能够接收并处理该消息。
尽管这些消息框架已经非常成熟但它们并不适用于本文的使用场景。这些框架通常用于云服务之间的消息通信而单纯的工控PLC通信又显得过于僵硬不适合构建信息物理系统CPS。目前尚无适合涉及大量设备、服务、人和虚拟实体四方消息互动的通信方案。如图\ref{fig-f11}所示,这四方之间的消息传递需求和性能要求各不相同,因此尝试设计一套新的消息网络以解决数字孪生下的数据困境是非常有必要的。
\begin{figure}[h!]
\centering
\includegraphics[width=0.8\textwidth]{figure/f11.png}
\caption{分部性能要求}
\label{fig-f11}
\end{figure}
\section{通讯机制}
\begin{figure}[h!]
\centering
\includegraphics[width=0.8\textwidth]{figure/f3.png}
\caption{通讯网络}
\label{fig-f3}
\end{figure}
\ref{fig-f3}为具体某一集群内的消息节点图在同一子网下的client节点上线时会进行广播发现内网节点后进行选举产生一个子网内核心节点其余节点连接该节点核心节点在向上连接最终链接到核心服务器集群服务器集群也会选举产生一个核心节点这个节点为整个网络的核心节点用来维护节点状态并向下同步状态整体网络中任意节点下线皆会触发重新选举或状态更新核心节点因故障下线时会导致当前层次子网重新选举中断服务1s但是不影响其余层次网络集群功能最终上线后会同步节点状态实现整体网络的最终一致性。
对于任意节点来说其上级节点其实与下级节点一致在功能逻辑上存在上下级但是在消息分发上不存在上级连接的所有节点都是下级或者说同级会维护一套消息表记录消息标记和需要发往的目标节点。如节点A刚开始上线时该表为空当A需要订阅消息时就广播给周边的节点 B 收到记录下消息类型和目标A以及路径长度1 在广播给除了A以外的临近节点同时路径长度加1每个节点收到同步消息时根据表内数据没有则添加有则根据路径长度比较短则替换目标长则抛弃。这样任意节点订阅消息时将会在整个消息网络广播其订阅记录并在每个节点记录的是最短传播路径。当节点收到消息时根据消息表内记录存在标记则转发不存在则抛弃。
\section{通讯协议}
如表\ref{tab-c1}所示,消息通讯协议采用了类似于以太网的帧结构,消息帧由前缀、长度、类型、标记、源节点、目标节点、数据组成,其中前缀用于判断消息帧的开始,长度用于判断消息帧的结束,类型用于区分消息类型,标记用于区分消息,源节点用于标识消息来源,目标节点用于标识消息目标,数据用于携带消息内容。
\begin{table}
\centering
\caption{通讯帧}
\begin{tabular}{|l|l|l|l|l|l|l|l|}
\hline
\multicolumn{4}{|c|}{prefix} & \multicolumn{4}{c|}{count} \\
\hline
typ & \multicolumn{3}{c|}{tag} & \multicolumn{4}{c|}{source} \\
\hline
\multicolumn{4}{|c|}{target} & \multicolumn{4}{c|}{data} \\
\hline
\multicolumn{8}{|c|}{data} \\
\multicolumn{8}{|c|}{....} \\
\multicolumn{8}{|c|}{data} \\
\hline
\end{tabular}
\label{tab-c1}
\end{table}
\begin{itemize}
\item prefix(8bit): 帧前缀,用于判断消息帧的开始
\item count(8bit): 消息长度
\item typ(4bit): 消息类型数字、字符串、二进制、文件地址、json等
\item tag(12bit): 消息标记
\item source(8bit): 消息来源节点
\item target(8bit): 消息目标节点
\item payload: 搭载的数据
\end{itemize}
\section{路由算法}
在订阅消息时存在父子订阅需求对于很多节点来说可能需要订阅的是某个具体的消息对于某些规则类节点或者虚拟节点来说订阅的是某个类别的消息所以设计树状订阅机制其订阅子树仅会收到子树消息订阅父节点则会收到下属所有子树消息这样在进行消息分发时不能简单的通过判断标记想到与否转发所以采用了trie树算法加速消息分发。
trie树又被称为前缀树、字典树是一种用于快速检索的多叉树结构。字典树把字符串看成字符序列根据字符串中字符序列的先后顺序构造从上到下的树结构树结构中的每一条边都对应着一个字符。字典树上存储的字符串被视为从根节点到某个节点之间的一条路径并在终点节点上做个标记"该节点对应词语的结尾",正因为有终点节点的存在,字典树不仅可以实现简单的存储字符串,还可以实现字符串的映射,只需要将相对应的值悬挂在终点节点上即可。
Trie的核心思想是空间换时间有如下基本性质
\begin{itemize}
\item - 根节点不包含字符,除根节点外每一个节点都只包含一个字符
\item - 从根节点到某一节点,路径上经过的字符连接起来,为该节点对应的字符串
\item - 每个节点的所有子节点包含的字符都不相同
\end{itemize}
字典树能够利用字符串中的公共前缀,这样可能会节省内存,利用字符串的公共前缀可以减少查询字符串的时间,能够最大限度的减少无谓的字符串比较,同时在查询的过程中不需要预知待查询字符串的长度,沿着字典树的边进行匹配,查询效率比较高。
\section{分布式选举协议}
\begin{figure}[h!]
\centering
\includegraphics[width=0.8\textwidth]{figure/f2.png}
\caption{选举协议}
\label{fig-f2}
\end{figure}
每个节点上线时如果有现有的消息网络会直接连入现有的消息网络,当大量节点同时上线或者子网间关键节点下线时会触发节点选举,选举产生一位核心节点代表他们和其他集群进行消息通信,并在这些核心节点中再次选举产生一个核心节点,这样所有的节点会自动的根据网络环境分层出消息层,并在消息传递之间保持最小路径
在分布式选举协议中,一个节点任一时刻处于以下三个状态之一:
\begin{itemize}
\item 从动
\item 候选者
\item 主控
\end{itemize}
如上图所示,可以看出所有节点启动时都是从动状态;在一段时间内如果没有收到来自主控的心跳,从从动切换到候选者,发起选举;如果收到大多数的同意票(含自己的一票)则切换到主控状态;如果发现其他节点比自己更新,则主动切换到从动。
总之,系统中最多只有一个主控节点,如果在一段时间里发现没有主控,则大家通过选举-投票选出主控。主控会不停的给从动发心跳消息,表明自己的存活状态。如果主控节点故障,那么从动节点会转换成候选状态,重新选出主控。
\section{硬实时通信}
在工业控制领域实时性Real-Time是一个关键性的需求。实时系统是一类计算系统其准确性取决于计算逻辑的正确性以及产生结果的时机。这意味着实时系统需要在预定的时间限制内完成特定任务否则可能导致系统失效。实时性在工业控制领域的重要性表现在以下几个方面
\begin{enumerate}
\item 生产过程监控:实时系统能够实时监测生产过程中的各种关键参数(例如温度、压力和流量),以确保生产过程的连续性和稳定性。如果实时系统无法在预定的时间限制内对异常情况做出响应,可能会导致生产流程中断,甚至发生安全事故。
\item 设备运行与维护:实时性对于设备的运行和维护具有关键意义。实时系统可以收集和分析设备状态数据,及时发现设备故障,并为操作人员提供故障诊断和处理建议。如果实时系统无法在预定的时间限制内完成这些任务,设备可能会因故障而停机,从而影响生产进度。
\item 工业自动化与优化:实时性在工业自动化和优化过程中起着至关重要的作用。实时系统可以在短时间内完成大量复杂数学计算任务,为生产过程提供智能决策支持。这有助于提高生产效率、降低成本,并确保产品质量。
\item 安全与事故防范:在工业领域,实时系统在安全和事故防范方面发挥着重要作用。实时监控和报警功能可以帮助工作人员及时发现潜在的安全隐患,并采取必要的措施防范事故。若实时性要求得不到满足,可能会导致灾难性的后果,如设备损坏、生产中断,甚至人员伤亡。
\end{enumerate}
因此,为满足设备间实时性消息和硬中断响应的需求,需要根据硬件单独编写相应的通信库去支持该性能要求。
在CPU资源调度时OS主要提供一个多任务(multitasking)的运行环境,以方便应用的开发。在开发某个应用时首先把工作拆解成多个任务(Task/Thread),每个任务都可以简化成一个简单的无限循环:
\begin{lstlisting}[
language={C},
caption={基本调度过程},
label={code-c-sample},
]
void MyTask (void)
{
while (1) {
Wait for an event to occur;
Perform task operation;
}
}
\end{lstlisting}
如上面代码所示,任务(Task)都是等待event然后处理事务。任何一个任务得以运行都是因为它收到了一个Event这个Event可能是一个中断、也可能是超时到期、还有可能是其他任务发出的IPC信号继续追查发出IPC信号的任务最后的源头Event肯定是一个外部设备硬件中断或者是内部的Timer中断。中断引起了Event传递形成了逐个运行多个任务的链条(Chain)。一个系统内部会存在很多条这种链条。
对实时系统来说不仅仅要求OS能提供多任务环境更要求任务能在极短的时间之内响应外部的中断事件。
对于终端节点来说硬实时通讯较好实现,利用时钟定时中断即可强制切换到高级别消息发送,但是终端节点一般作为信息发送和执行节点,不具备逻辑处理功能,在整体通讯延迟受最慢一级也就是逻辑处理层一般也是主机节点影响最大,为处理此问题,对消息进行分级,高优先级消息会先触发中断响应,并切换到执行状态,且不可被抢占。
\section{终端通信}
在上述协议下可以实现在场景内部的毫秒级硬中断响应通信需要对于已有的不同终端根据通信协议和线材不同可连入已有的物理节点进行消息转发同时目前已开发了c/rust通信依赖库可供开发使用直接在设备内嵌入通信逻辑。用户可以选择是外接设备还是内嵌代码接入到整个数字孪生平台该物联终端接口可同样应用于自定义仿真算法和逻辑算法节点通信接入。
\section{性能分析}
以下性能测试皆使用 2.4 GHz 八核Intel Core i9 作为测试芯片,并进行相关内核性能调优后得到的测试结果。
\begin{figure}[h!]
\centering
\includegraphics[width=0.8\textwidth]{figure/f4.png}
\caption{消息编码速率分布}
\label{fig-f4}
\end{figure}
\begin{figure}[h!]
\centering
\includegraphics[width=0.8\textwidth]{figure/f5.png}
\caption{消息编码速率拟合曲线}
\label{fig-f5}
\end{figure}
\begin{table}
\centering
\caption{消息编码}
\label{tab-c2}
\begin{tabular}{cccc}
\toprule
编码时间 & 下限 & 估值 & 上限 \\
\midrule
回归斜率 & 296.52 ns & 298.26 ns & 300.04 ns \\
拟合度 & 0.9228055 & 0.9263008 & 0.9225949 \\
均值 & 295.37 ns & 297.35 ns & 299.41ns \\
样本标准偏差 & 8.6420 ns & 10.325 ns & 11.813 ns \\
中值 & 293.45 ns & 295.80 ns & 297.40 ns\\
绝对中位差 & 6.1489 ns & 8.4741 ns & 11.089 ns\\
\bottomrule
\end{tabular}
\end{table}
由图\ref{fig-f4}和表\ref{tab-c2}可知消息分发网络中消息编码时间在300ns左右设备负载对消息编码速率分布有较大影响.
针对消息分发速率使用wrk 工具对系统进行压力测试得到图5
\begin{figure}[h!]
\centering
\includegraphics[width=0.8\textwidth]{figure/f6.png}
\caption{消息分发速率压测结果}
\label{fig-f6}
\end{figure}
由图\ref{fig-f6}可以看出消息分发在未绑定任何响应函数的情况下单机可以达到每秒157651条在未读取数据库情况下消息分发延迟6.33ms,以上数据目前满足数字孪生平台要求。