21架构设计第二步设计备用方案(下)

菜鸟程序员到架构师之路

每个程序员都有一个成为架构师的梦想,奈何手里无枪无法点燃心中奇梦。本系列文章分享如何让你手里有枪,只要努力,技术的梦想一定能实现,这应该是众多梦想中离地表最近的一个。

设计备选方案实战

接着上篇 跨境电商系统 的场景,我们通过排查法识别了消息队列的复杂性主要体现在:高性能消息读取、高可用消息写入、高可用消息存储、高可用消息读取。
接下来进行第2步,设计备选方案。

备选方案1:采用开源的Kafka
Kafka是成熟的开源消息队列方案,功能强大,性能非常高,而且已经比较成熟,很多大公司都在使用

备选方案2:集群 + MySQL存储
首先考虑单服务器高性能。
高性能消息读取属于“计算高性能”的范畴,单服务器高性能备选方案有很多种。
考虑到团队的开发语言是Java,虽然有人觉得C++语言更加适合写高性能的中间件系统,但综合来看,认为无须为了语言的性能优势而让整个团队切换语言,消息队列系统继续用Java开发。
由于Netty是Java领域成熟的高性能网络库,因此选择基于Netty开发消息队列系统。

由于系统设计的QPS是13800,即使单机采用Netty来构建高性能系统,单台服务器支撑这么高的QPS还是有很大风险的,
因此需要选择采取集群方式来满足“高性能消息读取”,集群的负载均衡算法采用简单的轮询即可。

“高可用写入”和“高性能读取”一样,可以采取集群的方式来满足。
因为消息只要写入集群中一台服务器就算成功写入,因此“高可用写入”的集群分配算法和“高性能读取”也一样采用轮询, 即正常情况下,客户端将消息依次写入不同的服务器;某台服务器异常的情况下,客户端直接将消息写入下一台正常的服务器即可。

整个系统中最复杂的是“高可用存储”和“高可用读取”,“高可用存储”要求已经写入的消息在单台服务器宕机的情况下不丢失;
“高可用读取”要求已经写入的消息在单台服务器宕机的情况下可以继续读取。可以利用MySQL的主备复制功能来达到“高可用存储“的目的,通过服务器的主备方案来达到“高可用读取”的目的。

具体方案如下:

简单描述一下方案:

  • 采用数据分散集群的架构,集群中的服务器进行分组,每个分组存储一部分消息数据
  • 每个分组包含一台主MySQL和一台备MySQL,分组内主备数据复制,分组间数据不同步
  • 正常情况下,分组内的主服务器对外提供消息写入和消息读取服务,备服务器不对外提供服务;主服务器宕机的情况下,备服务器对外提供消息读取的服务
  • 客户端采取轮询的策略写入和读取消息

备选方案3:集群 + 自研存储方案
在备选方案2的基础上,将MySQL存储替换为自研实现存储方案,因为MySQL的关系型数据库的特点并不是很契合消息队列的数据特点,参考Kafka的做法,可以自己实现一套文件存储和复制方案。
可以看出,高性能消息读取单机系统设计这部分时并没有多个备选方案可选,备选方案2和备选方案3都采取基于Netty的网络库,用Java语言开发,
原因就在于团队的Java背景约束了备选的范围。通常情况下,成熟的团队不会轻易改变技术栈,反而是新成立的技术团队更加倾向于采用新技术。

上面简单地给出了3个备选方案用来示范如何操作,实践中要比上述方案复杂一些。
架构师的技术储备越丰富、经验越多,备选方案也会更多,从而才能更好地设计备选方案。
例如,开源方案选择可能就包括Kafka、ActiveMQ、RabbitMQ;集群方案的存储既可以考虑用MySQL,也可以考虑用HBase,还可以考虑用Redis与MySQL结合等;
自研文件系统也可以有多个,可以参考Kafka,也可以参考LevelDB,还可以参考HBase等。

备用方案,不要只是PlanB,最好是“三方案”,又叫“第三选择”,可以防止思维狭隘,目光短浅,思维盲区等决策陷阱

发表评论
留言与评论(共有 0 条评论) “”
   
验证码:

相关文章

推荐文章