1. Redis에 데이터가 있는 경우 데이터베이스의 값과 동일해야 합니다.
2. Redis에 데이터가 없으면 Redis는 데이터베이스의 최신 값으로 동기적으로 업데이트되어야 합니다.
데이터베이스에 쓰기 작업도 동시에 Redis 캐시에 기록되므로 읽기 및 쓰기 캐시가 필요합니다. 데이터베이스의 캐시와 데이터의 일관성을 보장하려면 동기식 직접 쓰기 전략을 보장해야 합니다.
일부 비즈니스 운영에서는 MySQL 데이터가 업데이트된 후 물류 시스템과 같이 일정 기간이 지난 후 Redis 데이터를 동기화하는 것이 허용됩니다.
비정상적인 상황이 발생하면 실패한 액션을 복구해야 하며, Rabbitmq나 kafka로 다시 작성해야 합니다.
여러 스레드가 데이터베이스에서 이 데이터를 동시에 쿼리하는 경우 첫 번째 요청에서 뮤텍스 잠금을 사용하여 데이터를 쿼리할 수 있습니다.
다른 스레드는 이 시점에서 잠금을 얻을 수 없을 때까지 기다렸다가 첫 번째 스레드가 데이터를 쿼리할 때까지 기다린 다음 캐시합니다.
다음 스레드가 들어와서 이미 캐시가 있는 것을 발견하고 바로 캐시로 이동합니다.
public String get(String key){ // 从Redis缓存中读取 String value = redisTemplate.get(key); if(value != null){ return value; } synchronized (RedisTest.class){ // 重新尝试从Redis缓存中读取 value = redisTemplate.get(key); if(value != null){ return value; } // 从MySQL数据库中查询 value = studentDao.get(key); // 写入Redis缓存 redisTemplate.setnx(key,value,time); return value; } }
상식적으로는 그래야겠죠? 그렇다면 이 경우에는 어떤 문제가 있는 걸까요?
데이터베이스를 성공적으로 업데이트한 후 Redis를 업데이트하기 전에 예외가 발생하면 어떻게 되나요?
데이터베이스가 Redis에 캐시된 데이터와 일치하지 않습니다.
멀티 스레드 상황에서는 문제가 발생할 수 있습니다.
예를 들어
스레드 1 업데이트 redis = 200;
스레드 2 업데이트 redis = 100;
스레드 2 업데이트 MySQL = 100; MySQL = 200
결과는 Redis=100, MySQL=200입니다.
스레드 1은 Redis 캐시 데이터를 삭제한 다음 MySQL 데이터베이스를 업데이트합니다.
MySQL 업데이트가 완료되기 전에 스레드 2는 캐시 데이터를 읽습니다. 이 당시에는 MySQL 데이터베이스가 업데이트되지 않았습니다. 스레드 2는 MySQL에서 이전 값을 읽은 다음 스레드 2도 이전 값을 데이터 캐시로 기록했습니다.
지연 이중 삭제
스레드 2가 데이터를 읽고 캐시에 쓰는 시간, 즉 두 번째 캐시 지우기 작업보다 대기 시간이 더 길면 지연 이중 삭제를 통해 위의 문제를 해결할 수 있습니다. 스레드 1의 스레드 2가 캐시에 쓴 후에는 Redis 캐시의 데이터가 최신 상태인지 확인할 수 있습니다.
/** * 延时双删 * @autor 哪吒编程 */ public void deleteRedisData(Student stu){ // 删除Redis中的缓存数据 jedis.del(stu); // 更新MySQL数据库数据 studentDao.update(stu); // 休息两秒 try { TimeUnit.SECONDS.sleep(2); } catch (InterruptedException e) { e.printStackTrace(); } // 删除Redis中的缓存数据 jedis.del(stu); }
Nezha는 네 번째 방법을 권장합니다. 먼저 데이터베이스를 삭제한 다음 캐시를 삭제하세요.
방법 ④는 더 포괄적인 솔루션이지만 학습 비용과 유지 비용이 증가합니다. 미들웨어.
2. 일정 시간 내에 마스터 서버의 바이너리 로그를 확인하여 변경 여부를 감지합니다. 마스터 서버의 바이너리 이벤트 로그가 변경된 것으로 감지되면 I/O 스레드를 시작하여 마스터 바이너리 이벤트 로그를 요청합니다. 3. 동시에 마스터 서버는 각 I/O 스레드에 대한 덤프 스레드를 시작하여 바이너리 이벤트 로그를 보냅니다.
5. Salve 슬레이브 서버는 SQL 스레드를 시작하여 릴레이 로그에서 바이너리 로그를 읽고 해당 데이터를 기본 서버와 일치하도록 로컬로 재생합니다.
6. 마지막으로 I/O 스레드와 SQL 스레드가 들어갑니다. 다음번에 일어나길 기다리는 잠 상태.
위 내용은 MySQL 데이터베이스 및 Redis 캐시 일관성을 위한 업데이트 전략은 무엇입니까?의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!