这是 Beta 探索课程,内容结构、实验步骤和示例可能会继续调整。
合并写入
写放大问题
系统运行一段时间后,我发现了一个新问题。
监控数据:
Redis 状态:
- QPS:约 8000
- 其中 INCR/DECR:约 6000 次/秒
- 其中 SADD/SREM:约 2000 次/秒
数据库状态:
- QPS:约 1500
- 其中同步写入:约 500 次/秒
- 其中查询:约 1000 次/秒
问题:每次点赞都要同步写入数据库!
每次点赞的流程:
1. 更新 Redis(INCR)
2. 同步写入数据库(INSERT)
3. 更新数据库计数(UPDATE)
影响:
- 数据库压力大
- 响应时间长
- 吞吐量受限
能否减少数据库写入次数?
我想到了合并写入。
合并写入原理
核心思想:
- 先更新 Redis(立即返回)
- 将写操作放入队列
- 定时批量写入数据库
- 减少数据库写入次数
示意图:
原来:
用户点赞 → 更新 Redis → 写入数据库 → 返回
↑______________|
同步操作,耗时长
合并写入:
用户点赞 → 更新 Redis → 返回(快速)
↓
写入队列
↓
定时批量写入数据库(异步)
优势:
- 响应时间短(不等待数据库)
- 吞吐量高(批量写入)
- 数据库压力小
劣势:
- 数据可能延迟
- 实现复杂度高
实现方案
方案 1:内存队列 + 定时写入
点赞接口
方案 2:Redis Stream
方案 3:优化的合并策略
性能对比
测试代码
实际效果
监控数据
合并写入上线后:
Redis 状态:
- QPS:约 8000(不变)
- 响应时间:平均 0.5ms(更快)
数据库状态:
- QPS:从 1500 降到 150(降低 90%)
- 其中写入:从 500 降到 50(批量写入)
- 响应时间:平均 10ms
系统吞吐量:
- 从 200 req/s 提升到 2000 req/s
- 提升 10 倍!
数据一致性
延迟分析:
- 最大延迟:1 秒(刷新间隔)
- 平均延迟:0.5 秒
- 对用户影响:几乎无感知
数据准确性:
- 最终一致性
- 定期对账验证
- 不一致率 < 0.1%
课后练习
练习 1
合并写入时,如何处理”用户点赞后立即取消”的情况?
参考答案(3 个标签)
合并写入去重优化
方案:操作去重
练习 2
合并写入队列满时如何处理?
参考答案(3 个标签)
合并写入流控降级
方案:限流 + 降级
练习 3
如何保证合并写入的数据不丢失?
参考答案(3 个标签)
可靠性持久化容灾
方案:持久化队列
练习 4
合并写入时如何监控”延迟”?
参考答案(3 个标签)
监控延迟性能指标
方案:记录时间戳
练习 5
合并写入时,如何处理”数据库故障”?
参考答案(3 个标签)
容错故障处理可靠性
方案:重试 + 死信队列
思考题
-
合并写入的”刷新间隔”如何设置?
-
如果用户点赞后立即查询,可能查不到数据,如何处理?
-
合并写入和”延迟双删”如何配合使用?
💡 提示:这些问题没有标准答案,建议结合实际情况深入思考。
