MST

星途 面试题库

面试题:Redis实时同步MySQL数据并发处理中如何避免数据一致性问题

在实时同步MySQL数据到Redis的场景下,并发操作可能会导致数据一致性问题。请阐述你知道的几种可能引发数据不一致的情况,以及对应的解决方案。
15.6万 热度难度
数据库Redis

知识考点

AI 面试

面试题答案

一键面试

可能引发数据不一致的情况

  1. 缓存更新策略不当
    • 先更新数据库,再删除缓存:在高并发场景下,可能存在线程A更新数据库后,还未来得及删除缓存,此时线程B读取数据,从缓存中获取到旧数据,然后线程A删除缓存,线程B又将旧数据写入缓存,导致缓存与数据库数据不一致。
    • 先删除缓存,再更新数据库:如果在删除缓存后,更新数据库操作失败,而其他线程读取数据时发现缓存缺失,就会从数据库读取旧数据并写入缓存,造成缓存与数据库数据不一致。
  2. 主从复制延迟:MySQL采用主从复制架构时,主库数据更新后同步到从库存在一定延迟。若在从库同步完成前,读取数据并写入Redis,就可能将旧数据写入Redis,导致Redis与主库数据不一致。

解决方案

  1. 缓存更新策略优化
    • 双删策略:先删除缓存,更新数据库,然后延迟一定时间再次删除缓存。延迟时间根据业务情况调整,确保其他线程有足够时间从数据库读取新数据并更新缓存。示例代码(以Java为例):
public void updateData(String key, Object data) {
    redisTemplate.delete(key);
    // 更新数据库操作
    updateDatabase(data);
    try {
        Thread.sleep(500); // 延迟500毫秒
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
    redisTemplate.delete(key);
}
- **使用队列**:将缓存更新操作放入队列,按顺序执行,避免并发冲突。以RabbitMQ为例,先将更新操作发送到队列,消费者从队列中取出操作依次执行,先删除缓存再更新数据库。

2. 处理主从复制延迟: - 强制读主库:对于实时性要求高的数据读取操作,直接从主库读取数据,确保获取到最新数据后再写入Redis。可以在代码层面通过配置数据源切换,例如在Spring Boot中,可以通过自定义数据源路由规则实现。 - 缓存失效时间设置:合理设置Redis缓存的失效时间,在主从复制延迟期间,若缓存失效,再次读取时从主库获取最新数据并更新缓存。如:

redisTemplate.opsForValue().set(key, value, 300, TimeUnit.SECONDS); // 设置缓存300秒失效