大家好,我是易安!
在完成备选方案设计后,如何挑选最终的方案是一个很大的挑战,因为每个备选方案都是可行的。但是,没有哪个备选方案是完美的,因为每个方案都存在一些缺点或风险。此外,评价备选方案的标准也具有一定的主观性,可能会导致设计师之间产生争论。
因此,在实践中,许多设计师或架构师采取了下面几种指导思想来选择备选方案:
- 易用型
设计师挑选一个看起来最简单、最容易实现的方案。例如,如果要做全文搜索功能,MySQL的查询功能比较简单,而Elasticsearch的倒排索引设计要复杂得多,所以可能会选择MySQL。
- 高端型
高端型的做法与易用型正好相反,设计师会倾向于选择技术上看起来最牛的方案。例如,如果要选择一个搭配MySQL使用的缓存,可能会选择Redis,因为它支持持久化、数据字典、主备、集群等功能。
- 经验型
设计师基于自己的过往经验,选择自己最熟悉的方案。例如,如果设计师曾经是一个C++经验丰富的开发人员,现在要设计一个运维管理系统,因为对Python或Ruby on Rails不熟悉,可能会继续选择C++来做运维管理系统。
- 统筹规划型
统筹规划型,就是让老板来决定最终方案。这种做法可能会让设计师自己拿捏不定,但最终的责任会由领导来承担。
不同的做法本身并不存在绝对的正确或者绝对的错误,关键是要根据不同的场景选择不同的方式。有时候要选择最简单的方案,有时候要选择最优秀的方案,有时候要选择最熟悉的方案,甚至有时候需要领导来拍板。因此,关键问题是如何判断何时采用这些不同的选择方式。在架构设计流程的第3步:评估和选择备选方案中,选择备选方案的方法应该根据具体场景和实际情况进行评估和决策。
方案评估
在评估和选择备选方案时,我们应该采用全方位评估的方法。具体来说,我们需要列出我们需要关注的质量属性点,并从这些质量属性的维度去评估每个备选方案,再综合挑选适合当时情况的最优方案。
常见的方案质量属性点包括性能、可用性、硬件成本、项目投入、复杂度、安全性、可扩展性等。在评估这些质量属性时,需要遵循架构设计原则1“合适原则”和原则2“简单原则”,避免贪大求全,基本上某个质量属性能够满足一定时期内业务发展就可以了。
例如,在设计一个购物网站时,如果我们预期1年内能够发展到TPS 2000(业务一年翻倍已经是很好的情况了),在评估方案的性能时,只要能超过2000的都是合适的方案,而不是按照淘宝的标准要实现TPS 10万。
在评估未来业务发展的规模时,需要考虑架构设计原则3“演化原则”,避免过度设计、一步到位的想法。即使出现业务迅猛发展,也要遵循这个原则,尽可能让系统能够简单地扩容来跟上业务的发展。
通常情况下,如果某个质量属性评估和业务发展有关系(例如,性能、硬件成本等),可以通过将当前的业务规模乘以2 ~4来评估未来的业务发展规模。例如,现在的TPS是1000,则按照TPS 4000来设计方案;如果现在TPS是10000,则按照TPS 20000来设计方案。
完成方案的360度环评后,我们可以基于评估结果整理出360度环评表,一目了然地看到各个备选方案的优劣点。但是360度环评表也只能帮助我们分析各个备选方案,还是没有告诉我们具体选哪个方案。因为没有哪个方案是完美的,不同备选方案之间的差异要比较明显,差异明显的备选方案不可能所有的优缺点都是一样的。
如何选择备选方案
面临多个备选方案的选择时,我们应该按照优先级选择备选方案。即综合当前的业务发展情况、团队人员规模和技能、业务发展预测等因素,按照优先级选择,即架构师综合当前的业务发展情况、团队人员规模和技能、业务发展预测等因素,将质量属性按照优先级排序,首先挑选满足第一优先级的,如果方案都满足,那就再看第二优先级,以此类推。
有时候会出现两个或者多个方案,每个质量属性的优缺点都一样的情况。理论上是可能的,但实际上不太可能。因为在备选方案设计时,不同的备选方案之间的差异要比较明显,差异明显的备选方案不可能所有的优缺点都是一样的。
实战
备选方案评审会议
以之前讲过的微博系统设计为例,针对提出的3个备选方案,架构师组织了备选方案评审会议,参加的人有研发、测试、运维和几个核心业务的主管。
备选方案1:采用开源Kafka方案
- 业务主管意见: 倾向于采用Kafka方案,因为Kafka已经比较成熟,各个业务团队或多或少都了解过Kafka。
- 中间件团队意见: 部分研发人员支持使用Kafka,因为使用Kafka能节省大量的开发投入;但部分人员认为Kafka可能并不适合我们的业务场景,因为Kafka的设计目的是为了支撑大容量的日志消息传输,而我们的消息队列是为了业务数据的可靠传输。
- 运维代表意见: 提出强烈反对意见。首先,Kafka是Scala语言编写的,运维团队没有维护Scala语言开发的系统的经验,出问题后很难快速处理;其次,目前运维团队已经有一套成熟的运维体系,包括部署、监控、应急等,使用Kafka无法融入这套体系,需要单独投入运维人力。
- 测试代表意见: 倾向于引入Kafka,因为Kafka比较成熟,无须太多测试投入。
备选方案2:集群 + MySQL存储
- 中间件团队意见: 部分研发人员认为这个方案比较简单,但部分研发人员认为使用MySQL来存储消息数据,性能肯定不如使用文件系统;并且有的研发人员担心做这样的方案是否会影响中间件团队的技术声誉,看起来比较“土”、比较另类。
- 运维代表意见: 赞同这个方案,因为这个方案可以融入到现有的运维体系中,而且使用MySQL存储数据,可靠性有保证,运维团队也有丰富的MySQL运维经验。但运维团队认为这个方案的成本比较高,一个数据分组就需要4台机器(2台服务器 + 2台数据库)。
- 测试代表意见: 认为这个方案测试人力投入较大,包括功能测试、性能
- 测试、可靠性测试等都需要大量地投入人力。
- 业务主管意见: 既不肯定也不否定,因为反正都不是业务团队来投入人力来开发,系统维护也是中间件团队负责,对业务团队来说,只要保证消息队列系统稳定和可靠即可。
备选方案3:集群 + 自研存储系统
- 中间件团队意见: 部分研发人员认为这是一个很好的方案,既能够展现中间件团队的技术实力,性能上相比MySQL也要高;但另外的研发人员认为这个方案复杂度太高,按照目前的团队人力和技术实力,要做到稳定可靠的存储系统,需要耗时较长的迭代,这个过程中消息队列系统可能因为存储出现严重问题,例如文件损坏导致丢失大量数据。
- 运维代表意见: 不太赞成这个方案,因为运维之前遇到过几次类似的存储系统故障导致数据丢失的问题,损失惨重。例如,MongoDB丢数据、Tokyo Tyrant丢数据无法恢复等。运维团队并不相信目前的中间件团队的技术实力足以支撑自己研发一个存储系统。
- 测试代表意见: 赞同运维代表的意见,并且自研存储系统的测试难度也很高,投入也很大。
- 业务主管意见: 持保留意见,因为从历史经验来看,新系统上线肯定有bug,而存储系统出bug是最严重的,一旦出bug导致大量消息丢失,对系统的影响会严重。
以上备选方案的评审意见都有利有弊,因此在架构设计流程的第3步:评估和选择备选方案中,需要对这些意见进行综合考虑,权衡各自的利弊,并根据实际情况选择最优方案。在选择备选方案时,应该根据具体的场景和需求,选择最适合自己的方案,而不是盲目追求某一种派别的方案。
针对3个备选方案的讨论初步完成后,架构师列出了3个方案的全方位评估表:
列出这个表格后,无法一眼看出具体哪个方案更合适,于是大家都把目光投向架构师,决策的压力现在集中在架构师身上了。
架构师经过思考后,给出了最终选择备选方案2,原因有:
- 排除备选方案1的主要原因是可运维性,因为再成熟的系统,上线后都可能出问题,如果出问题无法快速解决,则无法满足业务的需求;并且Kafka的主要设计目标是高性能日志传输,而我们的消息队列设计的主要目标是业务消息的可靠传输。
- 排除备选方案3的主要原因是复杂度,目前团队技术实力和人员规模(总共6人,还有其他中间件系统需要开发和维护)无法支撑自研存储系统(参考架构设计原则2:简单原则)。
- 备选方案2的优点就是复杂度不高,也可以很好地融入现有运维体系,可靠性也有保障。
针对备选方案2的缺点,架构师解释是:
- 备选方案2的第一个缺点是性能,业务目前需要的性能并不是非常高,方案2能够满足,即使后面性能需求增加,方案2的数据分组方案也能够平行扩展进行支撑(参考架构设计原则3:演化原则)。
- 备选方案2的第二个缺点是成本,一个分组就需要4台机器,支撑目前的业务需求可能需要12台服务器,但实际上备机(包括服务器和数据库)主要用作备份,可以和其他系统并行部署在同一台机器上。
- 备选方案2的第三个缺点是技术上看起来并不很优越,但我们的设计目的不是为了证明自己(参考架构设计原则1:合适原则),而是更快更好地满足业务需求。
最后,大家针对一些细节再次讨论后,确定了选择备选方案2。
通过微博这个案例我们可以看出,备选方案的选择和很多因素相关,并不单单考虑性能高低、技术是否优越这些纯技术因素。业务的需求特点、运维团队的经验、已有的技术体系、团队人员的技术水平都会影响备选方案的选择。因此,同样是上述3个备选方案,有的团队会选择引入Kafka(例如,很多创业公司的初创团队,人手不够,需要快速上线支撑业务),有的会选择自研存储系统(例如,阿里开发了RocketMQ,人多力量大,业务复杂是主要原因)。
总结
备选方案评估和选择是架构师工作的一个重要方面。架构师需要根据当前业务的实际情况,对备选方案进行全方位的评估,从各个质量属性的维度去评估每个方案,再综合挑选适合当时情况的最优方案。在评估备选方案时,需要遵循架构设计原则1“合适原则”和原则2“简单原则”,避免贪大求全,基本上某个质量属性能够满足一定时期内业务发展就可以了。同时也要遵循原则3“演化原则”,避免过度设计,一步到位的想法。最后,在选择备选方案时,需要按照质量属性的优先级排序,逐个选择最适合的方案。
总之,备选方案评估和选择是一个全方位的过程,需要综合考虑多方面的因素。只有在评估和选择过程中遵循合适原则、简单原则和演化原则,并按照优先级逐个选择最适合的方案,才能设计出高质量、可扩展、易维护、高性能的系统架构。