>데이터 베이스 >MySQL 튜토리얼 >Redis와 MySQL 간의 이중 쓰기 문제를 해결하는 방법

Redis와 MySQL 간의 이중 쓰기 문제를 해결하는 방법

WBOY
WBOY앞으로
2023-05-27 12:53:11924검색

앞에 작성

엄밀히 말하면 강력한 일관성을 달성하기 위해 읽기 및 쓰기 차단을 사용하지 않는 한 비원자적 작업에 대한 일관성을 보장하는 것은 불가능하므로 캐시 아키텍처에서 추구하는 목표는 최종 일관성입니다.
캐싱은 강력한 일관성을 희생하여 성능을 향상시킵니다.

이는 CAP 이론에 의해 결정됩니다. 캐시 시스템에 적용 가능한 시나리오는 CAP의 AP에 속하는 비강력 일관성 시나리오입니다.

다음 세 가지 캐시 읽기 및 쓰기 전략은 각각 장점과 단점이 있으며 가장 좋은 전략은 없습니다.

세 가지 읽기-쓰기 캐시 전략

Cache-Aside Pattern(캐시 우회 모드)

캐시와 데이터베이스 간의 데이터 불일치 문제를 최대한 해결하기 위해 캐시 우회 모드인 Cache-Aside 패턴이 제안되었습니다.

Read: 캐시에서 데이터를 읽고 읽은 후 바로 반환합니다. 읽을 수 없으면 데이터베이스에서 로드하고 캐시에 쓴 다음 응답을 반환합니다.
Write: 업데이트할 때 먼저 데이터베이스를 업데이트한 다음 캐시를 삭제하세요.

Read-Through/Write-Through(읽기-쓰기 침투)

Read/Write Through 패턴 서버 측에서 캐시는 데이터를 읽고 쓰는 주요 데이터 저장소로 간주됩니다. Cache 서비스는 DB 데이터를 읽고 쓰는 역할을 담당하므로 애플리케이션의 부담을 줄여줍니다.

우리가 자주 사용하는 분산 캐시인 Redis는 DB에 데이터를 쓰는 캐시 기능을 제공하지 않기 때문에 많이 사용되지는 않습니다.

Write: 캐시를 먼저 확인하고, 캐시에 없으면 DB를 직접 업데이트하세요. 캐시에 존재하는 경우 캐시를 먼저 업데이트한 후 캐시 서비스가 스스로 DB를 업데이트합니다(캐시와 DB를 동시에 업데이트).

Read: 캐시에서 데이터를 읽고 읽은 후 바로 반환합니다. 읽을 수 없으면 먼저 DB에서 로드하고 캐시에 쓴 다음 응답을 반환합니다.

Write Behind Pattern(Asynchronous Cache Write)

Write Behind Pattern은 Read/Write Through Pattern과 매우 유사합니다. 둘 다 캐시 서비스에서 캐시와 DB를 읽고 쓰는 데 사용됩니다.

그러나 둘 사이에는 큰 차이점이 있습니다. Read/Write Through는 캐시와 DB를 동기식으로 업데이트하는 반면, Write Behind Caching은 캐시만 업데이트하고 DB를 직접 업데이트하지 않는 대신 비동기식 일괄 업데이트 방식으로 업데이트합니다. DB

분명히 이 방법은 데이터 일관성에 더 큰 문제를 가져옵니다. 예를 들어 캐시 데이터가 DB에 비동기적으로 업데이트되지 않으면 캐시 서비스가 중단되어 더 큰 재앙이 발생할 수 있습니다.

이 전략은 일상적인 개발 프로세스에서도 매우 드물지만 애플리케이션 시나리오가 거의 없다는 의미는 아닙니다. 예를 들어 메시지 대기열의 메시지를 디스크에 비동기적으로 쓰는 것과 MySQL의 InnoDB 버퍼 풀 메커니즘이 모두 이 전략을 사용합니다.

Write Behind 패턴에서 DB의 쓰기 성능은 매우 높으며, 이는 데이터가 자주 변경되고 조회수 및 좋아요 수와 같이 데이터 일관성 요구 사항이 그다지 높지 않은 일부 시나리오에 매우 적합합니다.

우회 캐시 모드 분석

캐시 제외 패턴에 대한 몇 가지 질문

우회 캐시 모드는 우리가 일상생활에서 가장 많이 사용하는 모드입니다. 위에서 소개한 우회 캐시 모드를 바탕으로 다음과 같은 질문이 생길 수 있습니다.

쓰기 작업이 캐시를 업데이트하는 대신 캐시를 삭제하는 이유는 무엇입니까?

답변: 스레드 A가 먼저 쓰기 작업을 시작하고 첫 번째 단계는 데이터베이스를 업데이트하는 것입니다. 스레드 B는 또 다른 쓰기 작업을 시작하고 두 번째 단계에서 데이터베이스를 업데이트합니다. 네트워크 및 기타 이유로 인해 스레드 B는 캐시를 먼저 업데이트하고 스레드 A는 캐시를 업데이트합니다.

이때, 캐시는 A의 데이터(기존 데이터)를 저장하고, 데이터베이스는 B의 데이터(새 데이터)를 저장하며, 데이터가 일관되지 않고 더티 데이터가 나타납니다. 캐시를 업데이트하는 대신 캐시를 삭제하면 이러한 더티 데이터 문제는 발생하지 않습니다.

실제로 쓰기 작업이 필요할 때 캐시를 업데이트할 수 있지만, 캐시를 업데이트할 때 스레드 안전 문제가 없도록 잠금/분산 잠금을 추가해야 합니다.

데이터를 쓰는 과정에서 DB를 먼저 업데이트한 다음 캐시를 삭제해야 하는 이유는 무엇인가요?

Answer: 예를 들어 요청 1이 쓰기 작업이라면 캐시 A가 먼저 삭제되고, 요청 2는 읽기 작업이고, 캐시 A를 먼저 읽습니다. 캐시가 삭제된 것으로 확인(요청 1에 의해 삭제됨)된 후 데이터베이스를 읽었지만, 이때 요청 1은 데이터를 업데이트할 시간이 없었습니다. 따라서 요청 2는 이전 데이터를 읽고 요청 2도 이전 데이터를 읽으므로 데이터 불일치가 발생합니다.

실제로는 캐시를 먼저 삭제한 다음 데이터베이스를 업데이트할 수 있습니다. 예를 들어 지연 이중 삭제 전략
을 사용하여 1초 동안 대기한 다음 캐시를 다시 삭제할 수 있습니다. 1초 이내에 발생한 데이터는 다시 삭제할 수 있습니다. 1초일 필요는 없으며 비즈니스에 따라 다릅니다. 그러나 이 접근 방식은 권장되지 않습니다. 이 1초 안에 많은 요인이 발생할 수 있고 불확실성이 너무 크기 때문입니다.

데이터를 쓰는 과정에서 DB를 먼저 업데이트한 후 캐시를 삭제해도 괜찮나요?

답변: 이론적으로는 데이터 불일치가 여전히 발생할 수 있지만 확률은 매우 낮습니다.

A에게 쿼리 작업을 수행하도록 요청하는 요청과 B에게 업데이트 작업을 수행하도록 요청하는 두 개의 요청이 있다고 가정하면 다음과 같은 상황이 발생합니다

(1) 캐시가 방금 만료되었습니다.
(2) A에게 데이터베이스를 쿼리하고 이전 값을 가져오도록 요청합니다.
(3) B에게 데이터베이스에 새 값을 쓰도록 요청합니다.
(4) B에게 캐시를 삭제하도록 요청합니다.
(5 ) A에게 이전 값을 찾아달라고 요청합니다. 위와 같은 상황이 발생하면 실제로 더티 데이터가 발생합니다.

그러나 이런 일이 일어날 확률은 높지 않습니다

위의 상황이 발생하기 위한 선천적인 조건이 있습니다. 즉, 단계 (3)의 데이터베이스 쓰기 작업은 단계의 데이터베이스 읽기 작업보다 시간이 덜 걸립니다. (2)단계가 (5)단계보다 앞설 수도 있습니다.

하지만 잘 생각해보면 데이터베이스의 읽기 작업은 쓰기 작업보다 훨씬 빠릅니다(그렇지 않으면 왜 읽기와 쓰기를 분리하는 걸까요? 읽기와 쓰기 분리를 한다는 의미는 읽기 작업이 더 빠르기 때문입니다) (3) 단계는 (2) 단계보다 시간이 덜 소요됩니다. 이러한 상황은 거의 발생하지 않습니다.

일관되지 않는 다른 이유가 있나요?

답변: 캐시 삭제에 실패하면 불일치 문제가 발생합니다.

어떻게 해결하나요?
Canal을 사용하여 데이터베이스의 binlog를 구독하고 운영에 필요한 데이터를 가져옵니다. 다른 프로그램을 시작하여 이 구독 프로그램에서 정보를 얻고 캐시를 삭제하십시오.

Cache Aside 패턴의 결함

결함 1: 처음 요청한 데이터가 캐시에 있어서는 안 됩니다

해결책: 핫스팟 데이터를 미리 캐시에 넣을 수 있습니다.

결함 2: 빈번한 쓰기 작업으로 인해 캐시의 데이터가 자주 삭제되어 캐시 적중률에 영향을 미칩니다.

데이터베이스와 캐시 데이터 간의 강력한 일관성 시나리오: DB를 업데이트할 때 캐시도 업데이트되지만 캐시를 업데이트할 때 스레드 안전 문제가 없는지 확인하기 위해 잠금/분산 잠금을 추가해야 합니다. 데이터베이스와 캐시 데이터가 일치하지 않는 시나리오는 일시적으로 허용될 수 있습니다. DB를 업데이트할 때 캐시도 업데이트되지만 상대적으로 짧은 만료 시간이 캐시에 추가됩니다. 이를 통해 데이터가 일치하지 않더라도 영향을 미칠 수 있습니다. 상대적으로 작을 것입니다.

위 내용은 Redis와 MySQL 간의 이중 쓰기 문제를 해결하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

성명:
이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제