系统设计组件选型
2019年,某技术团队在设计一个新项目时,爆发了一场激烈的技术争论。
争论的焦点是:消息队列用Kafka还是RabbitMQ?
Kafka派说:Kafka吞吐量大、支持百万QPS、适合大数据场景。
RabbitMQ派说:RabbitMQ功能丰富、支持复杂路由、社区活跃。
吵了两天,最后CTO拍板:先用RabbitMQ,如果扛不住再换Kafka。
一年后,系统日活从100万增长到1000万,RabbitMQ的集群被打成筛子,性能急剧下降。
迁移到Kafka花了3个月,损失不可估量。
这是一个典型的技术选型失误案例。选型时不考虑业务增长预期,等出了问题再补救,代价往往是选型的10倍。
【架构权衡】
技术选型的核心不是"哪个技术更先进",而是"哪个技术最适合当前和未来的业务需求"。理解每个技术的适用场景和局限性,才能做出正确的选型决策。
一、数据库选型 🔴
1.1 关系型 vs NoSQL
选型决策树:
需要强事务支持(ACID)?
是 → 关系型数据库(MySQL/PostgreSQL)
否 → 下一步
数据结构是否固定(表结构)?
是 → 关系型数据库
否 → 下一步
数据量 < 1亿条?
是 → MySQL + 分库分表
否 → 下一步
需要海量存储 + 高并发写入?
是 → NoSQL(HBase/ClickHouse)
否 → MongoDB / Cassandra
1.2 MySQL vs PostgreSQL
1.3 OLAP vs OLTP
OLTP(联机事务处理):
- 场景:订单、支付、用户
- 特点:高频写入、简单查询
- 推荐:MySQL / PostgreSQL / TiDB
OLAP(联机分析处理):
- 场景:报表、统计、数据分析
- 特点:海量数据、复杂查询
- 推荐:ClickHouse / Hive / Presto / StarRocks
二、缓存选型 🔴
2.1 Redis vs Memcached
2.2 Redis Cluster vs Codis
Redis Cluster(官方方案):
- 数据自动分片(16384个槽)
- 去中心化,无Proxy
- 优点:官方支持、简单
- 缺点:多键操作受限、迁移时阻塞
Codis(豌豆荚方案):
- 中间Proxy + Redis Group
- 支持多键操作
- 优点:兼容性好、功能全
- 缺点:需要维护Proxy
2.3 选型建议
简单缓存(无需持久化):
→ Memcached
复杂缓存(需要数据结构):
→ Redis 单机/主从
高可用集群(需要分片):
→ Redis Cluster(简单场景)
→ Codis(复杂场景)
分布式锁、序列号生成、限流:
→ Redis + RedLock
三、消息队列选型 🟡
3.1 Kafka vs RocketMQ vs RabbitMQ
3.2 选型决策树
消息队列选型:
吞吐量 > 10万QPS?
是 → Kafka / RocketMQ
否 → 下一步
需要事务消息?
是 → RocketMQ
否 → 下一步
需要复杂路由(Exchange)?
是 → RabbitMQ
否 → 下一步
大数据场景(日志、流处理)?
是 → Kafka
否 → RocketMQ / RabbitMQ
3.3 实际案例
案例1:日志采集系统
→ Kafka(高吞吐、大数据生态)
案例2:订单消息
→ RocketMQ(事务消息、可靠投递)
案例3:普通异步通知
→ RabbitMQ(简单路由、功能丰富)
案例4:实时计算
→ Kafka + Flink(流处理生态)
四、搜索引擎选型 🟡
4.1 Elasticsearch vs Solr
4.2 选型建议
全文搜索 + 日志分析:
→ Elasticsearch
复杂搜索场景(企业搜索):
→ Elasticsearch / Solr
简单搜索(< 1000万文档):
→ MySQL全文索引 / ES
时序数据:
→ InfluxDB / Prometheus
五、分布式存储选型 🟡
5.1 对象存储
对象存储选型:
自建(MinIO):
- 优点:兼容S3协议、运维可控
- 缺点:需要自己维护
云存储:
- 阿里OSS / 腾讯COS / AWS S3
- 优点:托管、稳定
- 缺点:成本、数据主权
选型建议:
- 小公司 → 云存储
- 大公司 → 自建 + 云存储备份
5.2 分布式文件系统
六、微服务框架选型 🟢
6.1 注册中心
注册中心选型:
Zookeeper:
- 优点:成熟、可靠
- 缺点:性能一般、需要维护
Nacos(阿里):
- 优点:配置+注册一体、轻量
- 缺点:相对年轻
Consul(HashiCorp):
- 优点:多数据中心支持、健康检查
- 缺点:国内社区相对小
选型建议:
- Spring Cloud生态 → Nacos
- 多语言 + 多数据中心 → Consul
- 简单场景 → Nacos
6.2 API网关
6.3 链路追踪
链路追踪选型:
Zipkin:
- 优点:轻量、简单
- 缺点:功能有限
Jaeger(CNCF):
- 优点:支持多语言、功能全
- 缺点:UI一般
SkyWalking:
- 优点:APM能力、UI好
- 缺点:Agent侵入性
Pinpoint:
- 优点:零侵入
- 缺点:社区相对小
选型建议:
- 简单场景 → Zipkin
- 全链路APM → SkyWalking
- 多语言 → Jaeger
七、面试高频追问 🟡
7.1 为什么选MySQL不用PostgreSQL?
常见回答:
1. MySQL社区更成熟,资料更多
2. MySQL性能更好(OLTP场景)
3. 公司技术栈是MySQL
更好的回答:
1. MySQL的InnoDB引擎在OLTP场景下性能更好
2. MySQL的分库分表方案更成熟(如ShardingSphere)
3. 团队MySQL经验更丰富,运维成本低
7.2 为什么选Kafka不用RocketMQ?
常见回答:
1. Kafka吞吐量大
2. Kafka生态好
更好的回答:
1. 我们是日志采集和大数据场景,Kafka的生态无缝对接
2. Kafka的顺序写性能在日志场景下优势明显
3. 但如果未来有交易类消息需求,我们会考虑RocketMQ的事务消息
【架构权衡】
技术选型的核心是根据业务需求选择最合适的技术。不要因为"XX技术更先进"就选择它,也不要因为"我们一直用这个"就拒绝新事物。理解每个技术的适用场景,权衡利弊,才能做出正确的决策。
八、选型自检清单 🟢
技术选型自检:
1. 需求匹配度
- [ ] 这个技术能解决我的核心问题吗?
- [ ] 这个技术的局限性是什么?
- [ ] 我的业务场景在技术适用范围内吗?
2. 团队能力
- [ ] 团队有相关经验吗?
- [ ] 学习曲线有多高?
- [ ] 有足够的运维能力吗?
3. 成本评估
- [ ] 开发成本
- [ ] 运维成本
- [ ] 基础设施成本
4. 扩展性
- [ ] 能支撑业务增长吗?
- [ ] 迁移成本有多高?
- [ ] 有Plan B吗?
5. 生态与社区
- [ ] 社区活跃吗?
- [ ] 有足够的资料吗?
- [ ] 有商业支持吗?
九、真实面试回放 🟡
面试官:你们项目里为什么选RocketMQ不用Kafka?
候选人(订单架构师):有三个原因:
一是事务消息。我们有下单 -> 扣库存 -> 发送消息的场景,需要RocketMQ的事务消息保证一致性。
二是我们的日均消息量是1000万,Kafka的百万QPS吞吐量对我们来说是过度设计,反而增加运维复杂度。
三是RocketMQ支持延迟消息,我们的订单超时取消需要这个功能。
面试官:如果将来日活增长到1亿呢?
候选人:1亿日活时,RocketMQ的十万QPS可能不够。我们有两种方案:
一是扩容:增加RocketMQ的Broker和Consumer。
二是分层:关键交易消息用RocketMQ,日志类消息迁移到Kafka。
但这是以后的问题。现在用RocketMQ是最合适的。
【面试官手记】
订单架构师这场面试的亮点:
-
有量化依据:日均1000万 vs Kafka的百万QPS
-
知道功能需求:事务消息、延迟消息
-
有扩展意识:知道将来的瓶颈和应对方案
这场面试属于P7级别,技术选型是架构师的核心能力。
技术选型没有绝对的对错,只有合适与否。记住三个要点:
- 需求匹配:选最合适的,而非最先进的
- 成本评估:考虑开发成本 + 运维成本 + 基础设施成本
- 扩展性:考虑未来增长,留下迁移空间
理解了这些,你就掌握了技术选型的精髓。