评论

收藏

[Linux] redis缓存一致性延时双删代码实现方式详解

服务系统 服务系统 发布于:2022-09-11 13:32 | 阅读数:330 | 评论:0

redis缓存一致性延时双删代码
不废话、、、如下
1、自定义注解
/**
*@author caoyue
*延时双删
**/
@Retention(RetentionPolicy.RUNTIME)
@Documented
@Target(ElementType.METHOD)
public @interface ClearCache {
  boolean open() default true;
}
2、刪除逻辑
/**
 * @author caoyue
 */
@Component
@Aspect
@Slf4j
public class DoubleClearCacheAop {
  @Autowired
  private UserService userService;
  //声明一个用于延时的定时线程池代替线程sleep
  ScheduledExecutorService task = new ScheduledThreadPoolExecutor(10, new BasicThreadFactory.
      Builder().namingPattern("clearCache-schedule-pool-%d").build());
  @Pointcut("@annotation(com.inspur.henan.uac.modules.open.util.ClearCache)")
  private void clearCachePoint() {
  }
  @Around("clearCachePoint()")
  public Object clearCacheAop(ProceedingJoinPoint proceeds) throws Throwable {
    Method method = ((MethodSignature) proceeds.getSignature()).getMethod();
    ClearCache annotation = method.getAnnotation(ClearCache.class);
    Object proceed = null;
    //如果清除注解开启了
    if (annotation.open()) {
      //上下文获取信息
      IPubUser user = MsySecurityContextHolder.getUser();
      if (Objects.nonNull(user)) {
        //执行清除缓存的动作
        userService._clearCache(user);
        //业务处理
        proceed = proceeds.proceed();
        //延时两秒后再删
        task.schedule(() -> {
          userService._clearCache(user);
          if (log.isInfoEnabled()) {
            log.info(Thread.currentThread().getName() + ":double delete cache completed");
          }
        }, 2L, TimeUnit.SECONDS);
      } else {
        proceed = proceeds.proceed();
      }
    }
    return proceed;
  }
}
redis缓存延迟双删问题
高并发场景使用redis作为缓存存储数据,当数据更新时,如何保证缓存一致性,
延迟双删的策略:
先删除缓存,然后更新数据库数据,休眠sleep,最后再次删除缓存数据。
休眠的时间略微大于从数据库查询数据的时间。
当读写分离时,考虑到主从数据同步延迟,休眠时间约1s。
休眠时间不能太大,否则会影响更新的速度。