评估和选择备选方案
列出我们需要关注的质量属性点,然后分别从这些质量属性的维度去评估每个方案,再综合挑选适合当时情况的最优方案。
常见的方案质量属性点有:性能、可用性、硬件成本、项目投入、复杂度、安全性、可扩展性等。
- 备选方案 1:采用开源 Kafka 方案
业务主管倾向于采用 Kafka 方案,因为 Kafka 已经比较成熟,各个业务团队或多或少都了解过 Kafka。中间件团队部分研发人员也支持使用 Kafka,因为使用 Kafka 能节省大量的开发投入;但部分人员认为 Kafka 可能并不适合我们的业务场景,因为 Kafka 的设计目的是为了支撑大容量的日志消息传输,而我们的消息队列是为了业务数据的可靠传输。运维代表提出了强烈的反对意见:首先,Kafka 是 Scala 语言编写的,运维团队没有维护Scala 语言开发的系统的经验,出问题后很难快速处理;其次,目前运维团队已经有一套成熟的运维体系,包括部署、监控、应急等,使用 Kafka 无法融入这套体系,需要单独投入运维人力。
测试代表也倾向于引入 Kafka,因为 Kafka 比较成熟,无须太多测试投入。
- 备选方案 2:集群 + MySQL 存储
中间件团队的研发人员认为这个方案比较简单,但部分研发人员杜宇这个方案的性能持怀疑态度,毕竟使用MySQL来存储消息数据,性能肯定不如使用文件系统;并且有的研发人员担心做这样的方案是否会影响中间件团队的技术声誉,毕竟用MySQL做消息队列,看起来比较"土",比较另类。
运维代表赞同这个方案,因为这个方案可以融入到现有的运维体系中,而且使用 MySQL存储数据,可靠性有保证,运维团队也有丰富的 MySQL 运维经验;但运维团队认为这个方案的成本比较高,一个数据分组就需要 4 台机器(2 台服务器 + 2 台数据库)。
测试代表认为这个方案测试人力投入较大,包括功能测试、性能测试、可靠性测试等都需要大量地投入人力。
业务主管对这个方案既不肯定也不否定,因为反正都不是业务团队来投入人力来开发,系统维护也是中间件团队负责,对业务团队来说,只要保证消息队列系统稳定和可靠即可。
- 备选方案 3:集群 + 自研存储系统
中间件团队部分研发人员认为这是一个很好的方案,既能够展现中间件团队的技术实力,性能上相比 MySQL 也要高;但另外的研发人员认为这个方案复杂度太高,按照目前的团队人力和技术实力,要做到稳定可靠的存储系统,需要耗时较长的迭代,这个过程中消息队列系统可能因为存储出现严重问题,例如文件损坏导致丢失大量数据。
运维代表不太赞成这个方案,因为运维之前遇到过几次类似的存储系统故障导致数据丢失的问题,损失惨重。例如,MongoDB 丢数据、Tokyo Tyrant 丢数据无法恢复等。运维团队并不相信目前的中间件团队的技术实力足以支撑自己研发一个存储系统(这让中间件团队的人员感觉有点不爽)。
测试代表赞同运维代表的意见,并且自研存储系统的测试难度也很高,投入也很大。业务主管对自研存储系统也持保留意见,因为从历史经验来看,新系统上线肯定有bug,而存储系统出 bug 是最严重的,一旦出 bug 导致大量消息丢失,对系统的影响会严重。
架构师经过思考后,给出了最终选择备选方案 2,原因有:
排除备选方案 1 的主要原因是可运维性,因为再成熟的系统,上线后都可能出问题,如果出问题无法快速解决,则无法满足业务的需求;并且 Kafka 的主要设计目标是高性能日志传输,而我们的消息队列设计的主要目标是业务消息的可靠传输。
排除备选方案 3 的主要原因是复杂度,目前团队技术实力和人员规模(总共 6 人,还有其他中间件系统需要开发和维护)无法支撑自研存储系统(参考架构设计原则 2:简单原则)。
备选方案 2 的优点就是复杂度不高,也可以很好地融入现有运维体系,可靠性也有保障。
针对备选方案 2 的缺点,架构师解释是:
备选方案 2 的第一个缺点是性能,业务目前需要的性能并不是非常高,方案 2 能够满足,即使后面性能需求增加,方案 2 的数据分组方案也能够平行扩展进行支撑(参考架构设计原则 3:演化原则)。
备选方案 2 的第二个缺点是成本,一个分组就需要 4 台机器,支撑目前的业务需求可能需要 12 台服务器,但实际上备机(包括服务器和数据库)主要用作备份,可以和其他系统并行部署在同一台机器上。
备选方案 2 的第三个缺点是技术上看起来并不很优越,但我们的设计目的不是为了证明自己(参考架构设计原则 1:合适原则),而是更快更好地满足业务需求。
思考题
RocketMQ 和 Kafka 有什么区别,阿里为何选择了自己开发 RocketMQ?