高性能商品库存更新系统内存聚合写库的容错解决方案
库存聚合更新防数据丢失优化方案
1. 用分布式消息队列做操作日志兜底
- 所有库存增减请求先写入持久化消息队列(比如开启持久化的Kafka、RabbitMQ),再同步到应用内存做聚合
- 内存聚合数据定期同步数据库,服务器宕机重启后,重新消费队列里未同步的操作日志,要么恢复内存聚合状态,要么直接基于日志计算差值同步到DB
- 注意给每个操作加唯一ID,保证消息至少消费一次且不重复计算
2. 内存聚合数据本地持久化
- 给内存里的库存聚合值定时做快照,写入本地磁盘(比如每分钟把各商品的库存差值序列化存成文件)
- 也可以用**内存映射文件(MMAP)**替代普通内存存储,让聚合数据实时落盘,既保留内存操作的高性能,又不怕宕机丢数据
- 重启时先读取本地快照/MMAP文件恢复聚合数据,再用消息队列补全快照之后的操作
3. 换成分布式持久化缓存做聚合
- 放弃单节点内存聚合,用Redis Cluster这类带持久化的分布式缓存来存聚合数据:Redis的RDB/AOF持久化能保证宕机后数据可恢复
- 库存增减直接调用Redis的原子命令
INCRBY/DECRBY,定期把Redis里的库存值同步到数据库 - 这样既享内存操作的高性能,又靠Redis的分布式和持久化避免单节点宕机丢数据,还能横向扩容扛高并发
4. 操作日志双写+补偿校验
- 内存聚合的同时,异步把操作记录写到数据库的库存操作流水表(比如
stock_operation_log,存product_id、变更量、操作时间) - 定期同步库存时,先对比内存聚合值和流水表的累计变更量,一致后再更新主库存表
- 宕机重启后,直接从流水表重新计算未同步的库存差值,同步到主表后再初始化内存聚合状态
5. 本地内存+远程缓存双聚合层
- 应用本地内存做一级聚合,同时异步把聚合后的差值同步到远程持久化缓存(比如Redis)
- 本地服务器宕机重启后,从Redis拉取最新的聚合差值恢复本地状态,再继续处理新请求
- 双层聚合既保证本地操作的低延迟,又用远程缓存的持久化能力做兜底
内容的提问来源于stack exchange,提问作者Ast15
相关产品推荐
相关产品推荐

