TIPC协议和实现解析

1 TIPC简介

        TIPC是爱立信公司提出的透明进程间通信协议,主要用于高可用(HA)和集群系统中。它允许设计人员能够创建可以和其它应用快速可靠地通信应用,无须考虑在其它需要通信的应用在集群环境中的位置。

        在可信网络环境下,TCP/IP协议的很多操作是冗余的,例如三次握手,增加了应用程序的通信时间,不利于对时间响应要求比较高的应用,比如 处理集群成员节点由于重启,down机等各种原因导致的增加和减少。 TIPC针对可信网络环境,减少了建立通信连接的步骤和寻址目标地址的操作 (在TCP/IP协议里, 完成这些操作节点间最少也需要9次包交换, 而使用TIPC则可以减少到2次)。这可以提高节点间信息交换的频率以及减少节点间等待的时间。

        平时我们使用的socket,TCP也好,UDP也好,用来标识一对socket的通信,无非是用两个socket的IP地址和端口号,即五元组。比如使用UDP的socket,要发一个datagram到另一个socket,需要指定对端的地址,这个地址是由那台机的IP和端口组成。socket是在内核中管理,当内核检测到socket有数据可读时,就会通知拥有这个socket的进程去读取里面的数据。

  这里的不方便之处在于,要指定对端地址,我们必须知道这个socket在哪台机,端口是多少,才能发送数据出去。能不能只提供一些应用层的信息,就可以让内核自己去查到socket的位置,再把消息发过去?TIPC做的就是这样的事。

       使用TIPC,我们在创建socket的时候在内核中注册自己的服务类型service type,那么在发送端,只需要指定服务类型就可以由内核路由到相应的socket。这个时候,对应用层来说,对端地址仅仅是一个服务类型service type!很显然,内核维护着这么一张TIPC的路由表,即由服务去查找socket。而每台机都有这样的路由表,他们之间信息就像能够共享一样地为整个集群的TIPC socket服务。有了TIPC,这个socket使用了哪个IP,那个端口,我们都不再需要知道,很好很强大。

       TIPC还具有如下特性:

  • 有些时候多个进程提供同样的服务,仅仅是为了负载平衡或其他原因,这种情况可以用一个整数变量instance来标识不同socket,但是指定同样的service type。这个时候socket的地址是由service type和instance共同来指定。发送数据时候只需要指定service type和一个instance的值,也可以指定service type和instance的一个区间。对于后者,就是broadcast你的datagram。
  • 管理前面说的TIPC路由表的是内核当中的一个进程叫做name server。它知晓着集群中所有的TIPC socket。在发送datagram给服务某个service的socket之前,你可以向它请求服务这个service的socket是否已经在工作了,它会告诉你service的状态。并且注册了一个observer,当你关心的socket起来之后发消息通知你,这样就可以避免你把datagram发给一个根本不存在的socket。
  • 特点:网路中服务位置透明,自动发现机制,可靠性,标准套接字接口的支持,无连接,有链接,多播。

2 TIPC的socket接口分析

2.1 socket地址

socket地址是个16字节的结构,如下所示:

struct sockaddr

{
   unsigned short sa_family; /* 地址家族, AF_xxx */
   char sa_data[14]; /*14字节协议地址*/
};

为了编程可以更加方便通常我们会针对不同的协议定义不同的并行结构,如tipc的socket地址定义如下:

struct sockaddr_tipc {

    unsigned short family;          /* AF_TIPC */

unsigned char  addrtype;        /* TIPC_ADDR_NAME */

    signed   char  scope;           /* TIPC_CLUSTER_SCOPE */

    union {        struct tipc_portid id;

        struct {        unsigned long type;

            unsigned long instance;

            unsigned long domain; /* 0: own zone */

        } name;

    } addr;

};

2.2 tipc的地址

tipc的地址描述如下:port。Z表示zone, C表示cluster,N表示node。Port可以看成是一个socket

当启动tipc服务的时候,确定当前node(可以是一块单板,也可以是一台主机)的地址。我们创建一个socket就创建了一个port。Tipc提供名字服务,在sockaddr_tipc中指定name,把sockaddr_tipc和port绑定起来,向指定的名字发送消息就会发到对应的socket,而下层的则不需要用户去感知。名字和端口支持1对多的关系,一个名字对应多个端口

2.3 创建socket

int socket(int domain, int type, int protocol);这个函数的目的是创建一个socket,然后返回一个socket描述符。Domain在这里是AF_TIPC,type通常有SOCK_STREAM,SOCK_DGRAM两种,表示面向流或面向包。Protocol通常设置为0。

2.4 bind操作

一旦有一个socket,我们可能要将socket和机器上的某个地址关联起来,这个操作由bind来完成。

Bind和connect,原socket在应用bind的时候我们需要自己指定端口,connect则会自动为我们选定接口,但对于tipc应用层,不存在这种关系。(待确认)

2.5 getsockname

根据socket描述符获取当前的地址。

 2.6 setsockopt

其参数如下:int sockfd, int level, int optname, const void *optval, socklen_t optlen

当level为SOL_TIPC,也就是使用tipc时,optname有如下值可以选择。

1)      TIPC_IMPORTANCE

          这个值用来标识本socket消息的重要性,设置为重要时本socket在发生拥塞时,消息丢失的可能性很小。 从下面的字面意思可以看出其含义,不再赘述。

TIPC_LOW_IMPORTANCE,      低优先级

TIPC_MEDIUM_IMPORTANCE,  中优先级

TIPC_HIGH_IMPORTANCE      高优先级

TIPC_CRITICAL_IMPORTANCE. 紧急优先级

默认是TIPC_LOW_IMPORTANCE

2)TIPC_SRC_DROPPABLE

      同样是作为拥塞控制,如果设置为此值,则在拥塞发生时,tipc会丢弃消息,否则,将吧消息放入队列缓存。

 默认情况下: 对SOCK_SEQPACKET, SOCK_STREAM, SOCK_RDM 三种传输方式,也就是可靠链接,则将消息缓存,对SOCK_DGRAM,也就是不可靠链接,将消息丢弃。

3)TIPC_DEST_DROPPABLE

     仍然为拥塞控制服务。针对下面三种情况有用,消息不能发送到目的地址,或者目的地址不存在,或者目的地址发生了拥塞。如果使能这个功能,在发生以上三种情况是,消息将被丢弃,否则会将消息返回给发送者。

      默认情况下:SOCK_SEQPACKET ,SOCK_STREAM两种传输方式,返回给发送者。

  对SOCK_RDM and SOCK_DGRAM则将消息丢弃。这样做的目的是在在使用面向链接的情况下发生通信失败时进行合适的处理,同时不增加面向无链接的情况下通信失败的处理的复杂性。

3)TIPC_CONN_TIMEOUT

设置connect的超时时间,单位是毫秒

用sendto时,这个选项是没有意义的。

3 TIPC协议简介

3.1 协议基础

一些假设:

  • 通过协议发送的大部分message都是直接到达目的地
  • 大部分message的传输时间都很短
  • 大部分message都在集群内部节点间传递
  • 包丢失率很低, 重传不经常发生
  • 可用带宽和内存都很大
  • 所有带戳包的校验和都由硬件校验
  • 通信节点的数量在一定时间内是相对受限和静态的
  • 安全在封闭的集群环境里相对Internet来说不是关键因素

         这些基础假定允许TIPC是一个基于流量驱动(traffic-driven)和固定大小滑动窗口的信号链路层协议。 而不是定时器驱动(timer-driven)的传输层协议。这使得TIPC拥有更早释放发送buffer, 更早侦测到包丢失并重传,更早侦测到节点不可用等优点。

3.2 TIPC网络结构

      TIPC网络是由单个的处理单元或节点组成. 网络节点是严格分层的, 规则如下:

1:相关节点的集合构成一个cluster:

      如果cluster中的每一个节点都至少有一条直达其他每个节点的路径(即cluster的节点是全连通的), 那么这些节点构成一个cluster, 每个cluster有1~4095个节点.

2:相关cluster的集合构成一个zone:

      如果zone中的每一个cluster都至少有一条直达其他每个cluster的路径(即zone的cluster是全连通的), 那么这些cluster构成一个zone, 每个zone有1~4095个cluster, 每个cluster的大小不必相同.

3:相关zone的集合构成一个TIPC网络:

      如果网络中的每一个zone都至少有一条直达其他每个zone的路径(即网络的zone是全连通的), 那么这些zone构成一个TIPC网络, 每个TIPC网络有1~255个zone, 每个zone的大小不必相同.

       节点一般是按照邻近关系分组, TIPC的通信质量随着节点距离增加而下降,在一个典型的TIPC网络中,同一cluster中的节点间通信最频繁,其次是同一zone而不同cluster的节点,而不同zone中的节点基本没有通信。

       TIPC网络地址是和整个物理结点相关联的,地址模式映射到逻辑网络拓扑。<z.c.n>方式。 Z(zone 8位),C(cluster, 12位), N(node, 12位), 共32位。 一个网络可包括255个域(zone)。zone:区域;cluster:集群;node:节点。
       TIPC网络中的每个节点都有一个由zone ID,cluster ID和node ID组成的地址,一般标记为<Z.C.N>。其中: 1<=Z<=255,1<=C,N<=4095。如果一个TIPC网络节点还没有被分配地址,那么就以<0.0.0>标记它。TIPC网络一般也有自己的ID。这样可以使多个逻辑TIPC网络共同使用相同的物理介质(如以太网LAN等)而不相互干扰。

注意: 

  1. TIPC2.0只支持单cluster的网络。
  2. TIPC网络节点的地址和IP有很大区别, 每个TIPC节点最多只有一个地址, 没有网络接口(interface)的概念。
  3. 每个节点的地址以及TIPC网络的ID都由网络管理员负责分配, 程序员不用关心这些。

4 Port

4.1 Port标识

Port 是TIPC网络协议的通信标识,具有网络唯一性,由运用程序创建port时由TIPC自动生成。

Port ID 典型标识是<z.c.n,:ref>, ref 是32位参考值,在node结点上是唯一的

Port ID属于TIPC网络通信的物理地址标识, 用于TIPC协议消息通信的内部路由。

4.2 Port name  (功能地址)

Port name 形式  a{type, instance}  #名字

               B{type, lower, bound}   #名字序列

Port name 和port ID 的映射是由TIPC的port 发布关联的,当应用bind指定的port name 时,TIPC自动生成关联port ID ,并在指定的网络区域发布。

5 消息发送

     若node结点在本地,则直接挂消息到目的port队列,若非本地结点,则由可用的链路发到目的结点。

     message是TIPC节点端口间信息交换的基本单元. TIPC中有2种基本消息:

  1. payload message: 在应用程序和应用程序或应用程序和TIPC服务之间传送应用程序相关的内容.
  2. internal message: 在TIPC子系统之间传送TIPC相关的内容.

        每个TIPC消息都包含消息头部和数据2部分,消息头部的格式和用户相关, 大小从6个字到11字(word)不等(TIPC支持头部将来最大扩展到60字节)。头部是以网络字节序编码的32字节整形存储的。

6 常创建发消息失败的原因

a.长度大于66000字节,返回EINVAL;

b.TIPC用的内存不是使用的低端的内存,返回ENOMEM;

C.目的port链路阻塞,且发送端不期望阻塞,返回ELINKCONG;

d.基于有链接的链路对应的目的的port阻塞,且发送端不期望阻塞;

 

感谢:

TIPC协议和实现解析

TIPC协议 (含实验)

TIPC协议及示例

另附两篇最近发现的好文:

tipc编程

TIPC 透明通信协议

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 大白 设计师:CSDN官方博客 返回首页