一、背景
假如要做一个消息队列系统,现在有3个方案,你会怎么选:
1、采用开源Kafka
Kafka是开源消息队列,功能强大,性能强大,性能也非常高。
2、集群+Mysql存储
基于Netty开发系统处理前端用户请求,实际存储在Mysql中,为了支持扩展性,Mysql分为多个组,每个组有相应的主实例和从实例,当主实例挂掉后通过切换机制将从提升为主,以保证高可用。
3、集群+自研存储
存储这块自己实现,要支持水平扩展及主从切换等高可用设计。
如果是一个中、小型公司,相信大部分人可能会选择方案1。
二、方案选型
上面这个问题是我最近看的一本书《从零开始学架构》里的一个例子,如果你是直接选择1,只能说大家还不到架构师的水平~,因为真实的方案需要考虑一些实际情况和约束条件的,书中举例的团队是这样的:
1、中间件团队规模不大,只有6人左右;
2、开发平台是Linux,数据库是Mysql;
书中给的答案是2,以下是作者的选择过程;
先从要考察的维度考察各方案的优劣:
质量属性 | Kafka | Mysql存储 | 自研存储 |
---|---|---|---|
性能 | 高 | 中 | 高 |
复杂度 | 低 | 中,只需开发复制集群就可以 | 高 |
硬件成本 | 低 | 中,一个分组就需要至少2台服务器 | 低 |
可运维性 | 低,运维团队无Kakfa、Scala经验 | 高,运维对Mysql比较熟悉 | 高,可以融入运维体系 |
可靠性 | 高,开源成熟 | 高,Mysql存储很成熟 | 低,最初阶段难以保证 |
人力投入 | 低 | 中 | 高 |
即方案选型要从多个角度去考察,每个角度代表团队当前的一些现状,或者说一些约束条件,当然可能还有后期一些扩展性的考虑,总体来说要从以下角度考察:成本、稳定性、性能等方面,成本包括人力投入、机器投入,稳定性包括可靠性、可运维性等,这里就不一一展开了。
架构师最终给的答案是方案2,理由如下:
1、首先排除方案1,主要原因是可运维性,因为再怎么成熟的系统,后期都有可能出问题,如果无法快速解决,则无法满足业务需求。
2、方案3也被排除,目前团队技术实力和人员规模还无法支撑自研存储系统。
3、方案3也有些问题,但都有相应的解决方案:
性能:业务目前性能不高,即使后面性能要求再增加,可以通过增加更多的组来扩容;
成本:大部分的Mysql从实例可以放在一台机器上,以节约硬件资源;
不够优雅:方案3看起来并不高大上,但我们做方案并不是为了追求高大上的东西,要能快速解决业务问题。
三、方案细化
针对方案3,上面只是大概的选型,到具体落地,还有很多工作要做,主要如下:
1、数据库设计
消息怎么存储,可以分2类,一是消息表,一是日志表;
这里还可以考虑不同业务隔离,采用分库分表,即一个大的业务单独一张表;
2、数据如何复制
Mysql主从复制即可满足;
3、主备服务器如何切换
采用Zookeeper做主备决策,业界还有MHA等方案,根据运维经验决定;
4、业务服务器如何写入消息
为了方便使用者使用,可以采用SDK的方案,SDK会轮询各主服务器,将消息写入到相应的主服务器;
5、业务如何读消息
也是采用SDK的方式,服务端通过数据库保存消费者最后读取消息的位置
四、总结
技术选型需要考虑我们当前的一些现状态,这些现状态代表你对团队和业务的理解,需要根据这些现状去找出约束条件,从而选择适合我们自己业务的最好的方案,而不是照搬把别人的方案复制过来;至于每个需要考察的维度需要自己去总结,一些非功能性的是可以总结出来的,如稳定性、成本和效率、性能。