一、需要解决的问题:
最近在着手重构我们分布式系统节点之间的通信模块,系统可以抽象成这样一个具体的问题:网络中有许多的物理节点(n,可能为数千),每个节点上有m个consumer进程和producer进程,
producer线程负责主要的计算任务,每个节点上的consumer需要汇聚所有节点上的producer的计算结果,然后做进一步处理。对于每个consumer来说,需要建立通信关系的数目为m*n个连接;对于每个producer节点,需要建立连接的数目为m*n;这样对于每个节点来说,并行k次计算需要建立的连接个数为2*k*m*(m*n)。如果使用TCP协议进行连接,会耗费很多系统资源,而且随着节点规模的逐渐扩大,可能会超过系统的连接数端口上限(Linux下是65535)。
在我们实际的系统中,对连接的稳定性要求很高,所有的计算并发执行,如果其中一个连接失败,会导致整个计算失败;还有一个问题是,在并发执行的任务中,有的producer不停的发送数据,但consumer此时因为某原因不会接收数据,此时需要producer不会影响其他的producer,如果使用每个连接使用独立的tcp物理连接,因为tcp实现了拥塞控制,这个问题就不会暴露出来。
二、初步方案:
1、使用基于TCP的socket的方案,每个物理节点和其他节点之间有一个固定大小的socket连接池,每次运算时consumer都从这连接池里面取连接和其他的producer建立,这里需要注意的是任务的排队、拥塞控制、以及死锁的预防;
2、使用基于UDP的socket方案,需要自行处理数据包的顺序、丢失、重复发送等问题;
3、使用某个高级消息队列(AMPQ)进行通信,由消息队列处理物理连接共享的问题,目前候选的产品由zeromq和rabitmq;
网友评论