前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >巧解Redis主从切换引发的库存同步地狱

巧解Redis主从切换引发的库存同步地狱

原创
作者头像
疯狂的KK
发布2023-09-04 17:55:28
4680
发布2023-09-04 17:55:28
举报
文章被收录于专栏:Java项目实战

一、问题复现

我们知道,Redis主从复制可以实现读写分离,通过使从节点提供读取服务,来分担主节点的读取压力。但是主从切换时,可能会导致严重的库存同步问题。

以下用Java代码模拟一个商品售卖的场景,看看主从切换会引发什么问题:

java

// 初始化商品库存数量

int inventory = 10;

// 主节点代码

public void sellItemOnMaster(){

inventory--;

System.out.println("主节点卖出库存,剩余:"+inventory);

}

// 从节点代码

public void sellItemOnSlave(){

// 从节点读取主节点的inventory值

int inventory = getInventoryFromMaster();

inventory--;

System.out.println("从节点卖出库存,剩余:"+inventory);

}

假设主从节点间复制是异步的,如果在主节点处理请求“sellItemOnMaster”后,还没来得及同步到从节点,此时从节点也处理了“sellItemOnSlave”的请求,读取到的库存仍是10,那么从节点执行结束后,实际的库存数量会变成8,小于记录的9,出现超卖情况。

二、问题原因

引发这个问题的原因在于:

1. 主从节点的数据存在同步延迟

Redis的主从复制是异步的,主节点写入新数据后,需要一定的时间同步到从节点,这段时间内,从节点的数据是旧的。

2. 从节点可以处理写请求

默认情况下,Redis的从节点同时处理读写请求,这当主从数据不同步时,可能导致从节点的处理逻辑错误。

3. 缺乏必要的业务校验逻辑

从节点在处理写请求时,没有考虑主从数据可能存在时间窗口,直接使用了主节点旧数据,导致逻辑错误。

三、解决方案

知道了引发问题的原因,我们来看看解决方案:

1. 尽量减少主从延迟

可以适当减小主节点写入批量大小,加快主从同步频率,缩小主从数据同步的时间窗口。

2. 使从节点只读

设置Redis从节点为只读模式,不处理写命令,可以避免直接在从节点写数据带来的问题。

3. 加入业务层校验机制

在从节点处理读请求时,加入必要的业务校验,例如再次检查库存数量,避免直接使用存在时差的旧数据。

4. 主从切换后重建索引

主从切换后,可以重建索引,保证主从数据强一致性。

5. 队列承接强一致性写入

使用消息队列来承接需要强一致性的写入操作,顺序写入主从节点,确保数据一致性。

以上这些方法各有优劣,可以根据实际业务需求进行选用。我们来看一个改进后的代码示例:

代码语言:java
复制
// 初始化库存数量
int inventory = 10;// 主节点代码
public void sellItemOnMaster(){
  // 从Redis主节点减库存
  decreaseInventoryInRedisMaster();
  // 将减库存请求发送到消息队列
  sendDecreaseInventoryMsgToMQ(productId);
}
// 从节点代码
public void sellItemOnSlave(){
  // 从Redis从节点读取库存
  int inventory = getInventoryFromRedisSlave();
  // 校验库存数量
  if(inventory > 0){
    // 售卖商品逻辑 
    System.out.println("从节点卖出商品");
  }else{
    // 没有库存,返回售罄
    System.out.println("商品售罄");
  }
}
// 消息队列消费端代码
public void handleDecreaseInventoryMsg(Message msg){
   // 从消息队列中获取商品减库存请求
   String productId = msg.getProductId();
   // 在从节点减库存
   decreaseInventoryInRedisSlave(productId); 
}

通过消息队列顺序写入Redis主从,并加上必要的业务校验,可以避免库存数量的错误。

四、小结

通过对Redis主从切换问题的剖析,我们可以得出以下结论:

  1. 明确问题根源,才能有针对性地解决问题。
  2. 采取技术手段缩小主从延迟,是治标不治本。
  3. 从业务层面设计如“不在从节点写数据”、“多层校验”等机制,才是根本解决之道。
  4. 综合运用多种手段,才能构建一个稳定可靠的分布式系统。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一、问题复现
  • 二、问题原因
  • 三、解决方案
  • 四、小结
相关产品与服务
云数据库 Redis®
腾讯云数据库 Redis®(TencentDB for Redis®)是腾讯云打造的兼容 Redis 协议的缓存和存储服务。丰富的数据结构能帮助您完成不同类型的业务场景开发。支持主从热备,提供自动容灾切换、数据备份、故障迁移、实例监控、在线扩容、数据回档等全套的数据库服务。
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档