作为架构师,工作内容并非迷雾重重。一个经验丰富的架构师必须对现有技术有深刻的了解,并且对已被实践证明的架构模式胸有成竹。基于对业务需求的深入理解,他们会选择并组合恰当的架构模式,进而对这些方案进行必要的修改和优化。
尽管软件技术经历了几十年的发展,并且持续涌现新技术,成熟的技术仍占主导,因为这些技术已被众多应用场景所验证。例如,涉及高可用性的主备方案、集群技术,高性能的负载均衡、多路复用技术,以及可扩展的分层和插件化技术等,这些都是在明确目标后可以迅速找到的解决方案。
通常情况下,只有当现有方案无法满足特定需求时,我们才考虑创新。然而,这些创新大多仍然建立在成熟的技术之上。
例如,NoSQL 中的 Key-Value 存储与数据库索引本质上相似,而 Memcache 实际上是将数据库索引转变成独立的缓存系统。
Hadoop 的大文件存储解决方案,基于的是集群和数据复制的技术。
Docker 的虚拟化技术是建立在 Linux 容器(LXC)之上的。
同样,LevelDB 使用的文件存储结构是跳表(Skip List)。
在《技术的本质》一书中,对技术的组合有清晰的阐述:新技术都是在现有技术的基础上发展起来的,现有技术又来源于先前的技术。将技术进行功能性分组,可以大大简化设计过程,这是技术“模块化”的首要原因。技术的“组合”和“递归”特征,将彻底改变我们对技术本质的认识。
尽管在很多情况下,通过组合和调整现有的技术或架构模式,我们可以得到所需的解决方案,但这并不意味着架构设计是一项简单的工作。由于可供选择的模式众多,可能的组合方案更是数不胜数,常常导致同一个问题可能有多种解决方案。如果在这些组合方案中加入创新元素,可选的解决方案则会增加更多。因此,设计最终的方案并不是一件容易的事,这一阶段也常是许多架构师易于出错的环节。
首先,一个常见的错误是追求设计出最完美的架构。许多架构师在设计时常常怀有一种技术情结,认为只有设计出一流的架构才能展示他们的技术水平。例如,在设计高可用性方案时,他们可能会偏好使用集群方案而不是主备方案,因为前者更加优越和强大;在高性能方案中,可能会倾向于使用业界领先的技术如淘宝的某种方案。
然而,根据“适用原则”和“简单原则”,选择适合自己业务、团队和技术能力的方案才是更为理智的选择。否则,可能会造成资源的浪费,如开发了远超实际需要的系统,或者设计出的系统根本无法由现有团队实现。
第二个常见错误是只制定一个方案。许多架构师可能会在心中简单比较几个方案,然后选择一个看似最佳的方案进行深入设计。这种做法存在多个缺点:评估可能过于肤浅,没有全面考虑,或是由于某个方案的一个缺点就草率地否决了它,而忽略了这可能是综合最优的选择。架构师的经验和知识是有限的,有时候他们的评估标准可能已过时或不适用于新情况,或者某些评估标准本身就是错误的。
因此,架构师应该设计多个备选方案,理想的方案数量是三到五个。少于三个可能由于思考不够全面,多于五个则可能花费过多时间和精力,且方案间的差异可能不明显。备选方案应具有较大的差异性,如主备和集群方案的区别,或者不同技术实现主备的差异明显,如使用ZooKeeper与使用Keepalived。
最后,第三个错误是备选方案过于详细。一些架构师可能会将备选方案写得非常详细,这不仅消耗大量时间和精力,还可能使人过于关注细节而忽视整体设计,从而导致备选方案数量不足或差异不大。正确的方法是在备选阶段关注技术选型的显著差异,而不是深入到技术细节。例如,使用ZooKeeper与Keepalived来实现主备就是一个较大的技术差异,而在使用相同技术的方案中进行细节上的区分,如节点设计的微小变化,这样的区分在备选阶段并不必要,具体的节点设计可以在最终方案中决定。
方案:
图片
方案概述如下:
- 实施一个分散数据的集群架构,集群内的服务器按组划分,每组负责存储特定部分的消息数据。
- 每个服务器组配置一台主用 MySQL 和一台备用 MySQL,组内实现主备数据复制,而组间数据保持独立不进行同步。
- 在正常运行时,每组的主服务器负责处理外部的消息写入和读取请求,备服务器则不提供服务。若主服务器发生故障,备服务器将接管并提供消息读取服务。
- 客户端使用轮询策略进行消息的写入和读取操作。
备选方案 3:自主研发存储系统的集群方案
在备选方案 2 的基础上,我们考虑替换 MySQL 存储,因为关系型数据库的特性并不完全符合消息队列的数据处理需求。借鉴 Kafka 的设计思路,可以自行开发一套专门的文件存储和复制系统(具体方案细节将在实际设计阶段详细阐述)。
从高性能消息读取的单机系统设计来看,由于团队主要使用 Java,备选方案 2 和 3 均采用了基于 Netty 的高性能网络库。这反映了团队的技术背景对选择范围的影响。一般而言,成熟的团队不易频繁更换技术栈,而新成立的团队则更可能尝试新技术。
以上简要介绍了三种备选方案以示范设计流程,实际应用中方案会更为复杂。架构师的技术储备和经验越丰富,能够提供的备选方案就越多,这有助于更有效地制定设计方案。例如,在开源方案中不仅可以选择 Kafka,还可以考虑 ActiveMQ、RabbitMQ 等;在考虑集群的存储方案时,除了 MySQL,还可以考虑使用 HBase 或将 Redis 与 MySQL 结合使用;自研的文件系统也可以参考 Kafka、LevelDB 或 HBase 等多种模型。这里由于篇幅限制,不再详细展开。