模拟面试场景
面试官:请你解释一下数据库的“读写分离”是什么意思?为什么很多系统要用它?它是怎么实现的?有什么优缺点?
(请你像真实面试一样,用清晰、结构化的方式回答。可以控制在1-2分钟的口语表达长度)
参考答案框架(你可以直接用这个结构回答,或根据自己的风格调整)
好的,我来完整解释一下。
1. 读写分离是什么?
读写分离(Read-Write Separation)是指把数据库的写操作和读操作分流到不同的数据库实例上去处理。最经典的模式是:
- 写请求(INSERT、UPDATE、DELETE) → 全部发到主库(Master / Primary)
- 读请求(SELECT) → 大部分或全部发到从库(Slave / Replica / Read Replica)
一句话总结:写走主,读走从。
2. 为什么要做读写分离?(核心价值)
因为现代互联网业务最典型的特点是读多写少:
- 一个商品详情页:可能被几千人同时读,但一天可能只被修改几次
- 用户个人中心:读个人资料的请求远多于修改资料
- 推荐feed、评论列表、排行榜:几乎全是读
在高并发场景下,单台数据库的读压力往往远高于写压力。如果所有读写都打到同一台机器,很容易把主库的CPU、IO、连接数打满,导致写也变慢,甚至整个服务不可用。
通过读写分离,我们可以:
- 把90%+ 的读流量分散到多台从库
- 主库专注于写 + 少量强一致读
- 实现横向扩展读能力(加从库就能线性提升读吞吐)
- 大幅提高系统整体QPS和可用性
3. 常见的实现方式(从简单到复杂)
| 实现方式 | 谁做读写分离决策? | 优点 | 缺点 / 限制 | 典型中间件 / 方案 |
|---|---|---|---|---|
| 客户端直连 | 业务代码 / ORM | 实现最简单,延迟最低 | 业务侵入大,切换主从麻烦 | MyBatis多数据源、Spring AbstractRoutingDataSource |
| 代理层分离 | 中间件代理 | 业务无感知,兼容性好 | 引入额外一层,单点风险 | MyCat、ShardingSphere-Proxy、ProxySQL、MaxScale |
| 数据库中间件 + 分库分表 | ShardingSphere 等 | 支持读写分离 + 分库分表一体化 | 配置稍复杂 | Apache ShardingSphere |
| 云厂商托管 | 云控制台 + SDK | 开箱即用,运维简单 | 绑定云厂商,成本较高 | AWS Aurora、阿里云 PolarDB、腾讯云 TDSQL |
4. 读写分离带来的挑战 & 解决方案
| 问题 | 表现 | 常见解决方案 |
|---|---|---|
| 数据延迟(主从复制延迟) | 从库读到旧数据 | 1. 强一致读强制走主库 2. 业务容忍最终一致 3. 监控延迟 + 降级 |
| 主从不一致窗口 | 写完立刻读,可能读不到 | 1. 读主策略(key读) 2. 延迟读(等几百ms) 3. 一致性路由 |
| 主库单点故障 | 主挂了写不了 | 主从自动切换(MHA、Orchestrator、云厂商HA) |
| 从库负载不均 | 某个从库压力大 | 服务发现 + 客户端负载均衡、代理层权重分配 |
5. 总结一句话(面试收尾常用)
读写分离本质上是用空间换时间、用从库数量换读性能的一种经典架构手段。它特别适合读远多于写、对实时性要求不是极致强一致的业务场景,是大多数中大型互联网系统标配的数据库扩展方案之一。
面试官追问可能方向(你可以提前准备):
- 你项目里是怎么判断一条查询走主还是走从的?
- 主从复制延迟怎么处理的?
- 如果要做到跨机房读写分离呢?
- 读写分离和分库分表有什么区别和联系?
你想现在直接模拟回答一遍吗?或者我帮你针对某个追问方向再深入展开?