读写分离 → 分库分表 → 分布式ID 追问链#
追问路径#
Q: 单库扛不住了,第一步通常怎么扩展?
→ 读写分离:主库写、从库读,靠主从复制同步;读多写少场景能成倍提升读能力
Q: 主从复制怎么实现的?延迟怎么解决?
→ 主库binlog→从库IO线程拉取写relay log→SQL线程重放;延迟靠并行复制、半同步复制、强一致读走主库
Q: 读写分离后写还是瓶颈怎么办?
→ 分库分表:垂直拆(按业务拆库/按字段拆表) + 水平拆(按规则把一张表的数据分散到多张/多库)
├─ Q: 分片键(sharding key)怎么选?分片算法有哪些?
│ → 选高频查询且分布均匀的字段(如user_id);range(易热点但好扩容)/hash(均匀但扩容要迁移)/一致性哈希(减少迁移)
│ Q: 水平分表后跨片查询和分页怎么办?
│ → 跨片聚合后内存归并(性能差)、禁止深分页、用ES/宽表做多维查询、避免跨片join改冗余字段
│ Q: 分库分表后扩容(从8个分片到16个)怎么平滑迁移?
│ → 翻倍扩容+一致性哈希减少迁移量;双写迁移(新老库同时写)→数据校验→灰度切读→下线老库
│ Q: 分库后还能用本地事务吗?
│ → 不能跨库本地事务,要用分布式事务(Seata/事务消息)或拆分业务避免跨库
└─ Q: 分表后自增主键冲突,ID怎么生成?
→ 不能再用单库自增;要全局唯一+趋势递增(利于B+树插入)的分布式ID
Q: 雪花算法(Snowflake)的结构和问题?
→ 64位=1符号+41时间戳+10机器ID+12序列号;问题是时钟回拨导致重复,靠等待/抛异常/备用位解决
Q: 除了雪花还有哪些方案?怎么选?
→ 号段模式(Leaf-segment, DB批量取号缓存)、Redis incr、UUID(无序不推荐做主键);高并发趋势递增首选号段或改进雪花plaintext涉及知识点#
- 读写分离方案 — 主从架构与读流量分发
- 主从复制原理 — binlog/relay log与复制延迟
- MySQL执行计划与主从延迟实战 — 延迟监控与强一致读
- 分库分表方案 — 垂直/水平拆分与中间件
- 自增ID与分布式ID — 单库自增的局限
- 分布式ID生成方案 — 号段/雪花/Redis对比
- 雪花算法原理 — 64位结构与时钟回拨
- 一致性哈希 — 扩容时减少数据迁移
- 大表分页优化 — 分片后深分页问题
- 分布式事务方案 — 分库后跨库一致性
核心串联逻辑#
- 扩展三段式:读写分离(读扩展)→垂直拆分(按业务解耦)→水平分库分表(写扩展+突破单机容量)
- 主从延迟应对:并行复制+半同步复制降低延迟,强一致读(刚写完就读)直接走主库或缓存
- 分片键是核心决策:要高频查询+分布均匀;hash均匀但扩容迁移多,一致性哈希/翻倍扩容缓解迁移
- 分片后的代价:跨片查询/分页/join变难(靠冗余字段、ES、宽表绕开),本地事务失效要上分布式事务
- 分布式ID三要求:全局唯一、趋势递增(对B+树主键友好)、高性能;雪花要处理时钟回拨,号段模式更稳
- 代码示例:
plaintext// 雪花算法64位结构 | 1bit 符号(恒0) | 41bit 毫秒时间戳 | 10bit 机器ID | 12bit 序列号 | // 41位时间戳可用约69年,10位支持1024台机器,12位每毫秒每机4096个ID // 时钟回拨处理:回拨小则等待追上,回拨大则抛异常或切用备用机器位
面试回答串联#
30秒速答#
“扩展顺序一般是读写分离→垂直拆分→水平分库分表。读写分离靠主从复制,延迟用并行/半同步复制缓解、强一致读走主库。水平分表要选分布均匀的分片键,跨片查询和分页靠冗余字段或ES解决,扩容用翻倍+一致性哈希减少迁移。分表后主键用分布式ID,雪花算法64位带时间戳保证趋势递增,但要处理时钟回拨,更稳的是号段模式。“
2分钟展开答#
“数据库扩展通常分三步走。第一步读写分离,主库负责写、从库负责读,靠主从复制同步——主库写binlog,从库IO线程拉过来写relay log,再由SQL线程重放。主从延迟是核心问题,可以用并行复制、半同步复制降低,对刚写完立刻要读的强一致场景直接走主库或读缓存。第二步如果写还是瓶颈或单表太大就分库分表,垂直拆分是按业务把表拆到不同库、把大字段拆出去,水平拆分是按规则把一张表的数据分散到多张表多个库。分片键的选择是最关键的决策,要选高频查询且分布均匀的字段比如user_id,分片算法range好扩容但容易热点、hash均匀但扩容要迁移数据、一致性哈希能减少迁移量。分片后最大的痛点是跨片查询和分页,深分页基本要禁掉,多维查询用ES或者做冗余宽表,join靠冗余字段避免。扩容比如从8片到16片用翻倍扩容配合双写迁移:新老库同时写、数据校验、灰度切读、最后下线老库。分库后跨库本地事务用不了,要上Seata或事务消息。分表之后单库自增主键会冲突,需要分布式ID,要求全局唯一、趋势递增(对B+树主键插入友好)、高性能。雪花算法是64位:1位符号、41位毫秒时间戳、10位机器ID、12位序列号,问题是依赖时钟、回拨会重复,小回拨等待、大回拨抛异常或切备用位。比雪花更稳的是号段模式比如美团Leaf,从DB批量取一段ID缓存在内存发,减少DB压力又不依赖时钟。“
相关追问链#
- MySQL锁-隔离级别-幻读-死锁追问链 — 分库前的单机事务与锁
- MySQL事务-分布式事务-CAP追问链 — 分库后跨库事务方案
- MySQL索引-慢SQL-优化实战追问链 — 分表前先做索引和SQL优化
- 秒杀系统-限流-库存扣减-分布式锁追问链 — 高并发下的分段与ID生成