历史悠久的微博中转

作者: | 更新日期:

这个中转有点年代了。

本文首发于公众号:天空的代码世界,微信号:tiankonguse

大家好,这里是tiankonguse的公众号(tiankonguse-code)。
tiankonguse曾是一名ACMer,现在是鹅厂视频部门的后台开发。
这里主要记录算法,数学,计算机技术等好玩的东西。

这篇文章从公众号tiankonguse-code自动同步过来。
如果转载请加上署名:公众号tiankonguse-code,并附上公众号二维码,谢谢。

零、背景

之前在《浅谈中转系统》中介绍了中转的作用:数据通知的解耦。
然后在《简单粗暴的ZMQ通知中转》中介绍了2013年视频为解决资料变更通知的问题实现了ZMQ通知中转。
最终遇到一个核心问题让我们放弃了这个ZMQ中转, 那就是中心节点重启时,客户端的api不会重连中心节点,这导致客户端不重启就不能接收到消息了。

上篇文章提到ZMQ中转没有任何配置,所以有哪些客户端是消费者没有人知道,现在链接有断了,彻底找不到客户端了,想通知他们重启也做不到了。
对于其他的问题如生产者消息量不可控,中心是单点,消费者接收全部消息,数据分类是口头约定其实都还可以容忍的,但是链接断了收不到消息这个没办法容忍,大家又没有接手改造这个系统的意思,于是最好转向微博中转了。

关于ZMQ中转系统和微博中转系统这两个名字,我多说几句。
对于大部分开发,其实起名字都很踏实,比如ZQM中转系统是使用ZMQ网络框架实现的一套中转,微博中转系统是微博部门自己实现的一套中转。
偶尔会听到很多系统, 如特斯拉系统,奥特曼系统,火箭系统,萨德系统等等,给这些系统起名字的开发的情商应该相对比较高的,但是大家看到这个系统名字肯定不知道这个系统是做什么的,只是给人一种高大上的感觉。
关于名字这个,之前在《杂谈(一)》中提到过,这里只是简单提一下。

好了,现在我们既然转向微博中转了,这里就介绍一下微博中转的架构吧。

一、系统架构

微博中转的架构比ZMQ的架构多了一层和两个辅助模块,即中心节点拆为接入层和转发层,然后加了配置中心模块和监控模块。
生成者连接接入层,消费者连接转发层,生产者和消费者解耦互不感知。
理论上写少读多,接入机不会成为瓶颈,转发机的CPU和网卡可能成为瓶颈,到时候只需要给转发机扩容即可。

整体架构如下:

二、模块架构

1. 生产者模块

生成者分为三部分:配置进程,收数据进程,发数据进程。
接受数据进程使用UDP方式本机接受数据,然后写到共享内存队列中。
发送数据进程根据配置,把共享内存的数据TCP的方式发给一台接入机。

2. 接入机模块

接入机分为四部分:配置进程,接收进程,调度进程,发送进程。 这个分了两个队列,我认为一个队列就够了,但是这样设计了那就这样吧。

3. 转发机模块

转发机模块与接入机模块一模一样, 所里这里就不上图了。

4. 消费者模块

消费者模块特别简单,从转发模块拉倒数据后UDP发给对应的业务即可。
这里看着少了点什么,如果收到数据放到一个队列里,然后有一个发送进程发送数据的话就完美了。

三、架构分析

1. 关于架构

如果看整体架构的话,设计的相当简洁明了。
但是细看的话,发现设计的相当冗余,接入模块与转发模块内部都有两个小队列,实际没这个必要的。
网络操作也看出队列的话,数据从业务生产到转发机准备发送共copy了15次,然后转发机发给每个消费者到业务都copy了3次。

实际应用中接入模块和转发模块是同机部署的,此时接入机和转发机的个数相等,接入模块和转发模块中的4个队列加一个网络操作就显得过度设计了。
表面上看着中心有6个数据转发进程,两个配置进程,但是他们和ZMQ中转的中心节点的作用完全一样的,但是没有ZQM中转简洁了。

只不过微博中转把队列使用的出神入化,但是剩下最后一个消费者时,竟然没有了队列。
缺少历史背景,为什么这样设计已经不清楚了。

2. 关于配置

假设我们要做一个中转,配置的目的有下面几个。

  1. 这个生产者允许生产哪些消息。
  2. 生产者连接哪些接入机。
  3. 接入机连接哪些转发机。
  4. 转发机将消息发给哪些消费者。
  5. 消费者将消息发给哪些业务。

正常情况下接入了新的生产者,配置一下步骤1即可;接入了消费者配置一下步骤4和步骤5即可。

微博中转支持的功能并没有这么简单。
有人说:对于某一类消息,我希望只走部分接入机和部分转发机。
于是中转支持了这样一个看起来很简单的功能,后续维护成本无比巨大。

实际上微博中转支持的配置功能还有很多,而且配置设计的特别冗余(一个功能必须在两个地方同时配置才能生效),现在已经没有人能够了解具体配置了。
我曾梳理过几次微博中转的配置,每次梳理后看着配置表还可以在心里勾画出配置图,过了几分钟就忘记了,还是需要多梳理几遍多配置几遍把。

3. 关于容灾

容灾有几方面。

比如中心节点过了几台机器,现在仍旧可以服务了。
生产者消息量过大,监控模块用起来的话也可以知道谁在发大量消息了(实际还没监控模块)。

还有一个就是消费者挂了怎么办。
很多业务希望自己的服务挂了,起来后能够拉倒挂的那段时间的数据。
简单思考就会知道这个有个度的,也就是要保存多久的数据、保存多少条数据。

某个业务十分钟前修改全量数据,有千万级别的数据,中转肯定不会保存这个多数据的。
这个时候某个业务挂了,不管任何形式的中转都不能做到消费者不丢数据吧,或者做到时成本就会很高吧。
其实微博中转以前也支持在客户端缓存一些数据的(有个小队列),不过后来废弃了,再又来重构了之后就不兼容了,导致没有这个功能了。

中转的另一个问题是业务处理失败怎么办?
业务说中转应该支持ACK,业务确认收到数据了才能下发下个数据。
这个问题其实和业务挂了类似,有个度的问题,这里点到为止,不多说了。

四、总结

好了,微博中转就聊到这里了。
微博中转从11年就在微博使用了,现在17年了,使用了6年多了,其实还是相当稳定的,期间很多人说中转丢消息的最终发现都是业务自身的问题。
这个系统不看配置的话,架构还是相当简单的,配置过度设计过度冗余使的这个系统成为一个包袱了。

以后设计系统要谨记一件事:简单、简单、再简单。

对了现在开通了公众号和小密圈。
博客记录所有内容。
技术含量最高的文章放在公众号发布。
比较好玩的算法放在小密圈发布。
小密圈这周接受免费加入,欢迎大家加入看各种算法的思路。

长按图片关注公众号,接受最新文章消息。

本文首发于公众号:天空的代码世界,微信号:tiankonguse
如果你想留言,可以在微信里面关注公众号进行留言。

关注公众号,接收最新消息

tiankonguse +
穿越