목차
1. 읽기 요청이 오랫동안 차단됩니다.
2. 읽기 요청의 동시성이 너무 높습니다
3. 다중 서비스 인스턴스 배포를 위한 요청 라우팅
4. 핫한 제품의 라우팅 문제로 인해 편향된 요청이 발생합니다
Java Java베이스 Java 구현은 캐시와 데이터베이스 간의 이중 쓰기 일관성을 보장합니다.

Java 구현은 캐시와 데이터베이스 간의 이중 쓰기 일관성을 보장합니다.

Dec 30, 2020 pm 05:51 PM
mysql sql 데이터 베이스

기본 Java 튜토리얼이 열은 캐시와 데이터베이스 간의 이중 쓰기 일관성을 보장합니다.

Java 구현은 캐시와 데이터베이스 간의 이중 쓰기 일관성을 보장합니다.

머리를 들어주세요, 공주님. 그렇지 않으면 왕관이 떨어질 것입니다.

분산 캐시는 오늘날 많은 분산 애플리케이션에 없어서는 안 될 구성 요소이지만, 분산 캐시를 사용하면 캐시와 데이터베이스의 이중 저장 및 이중 쓰기가 발생할 수 있으므로 데이터 일관성 문제가 발생합니다. 일관성 문제를 해결하고 있나요?

캐시 따로 패턴

가장 고전적인 캐싱 + 데이터베이스 읽기 및 쓰기 모드는 캐시 따로 패턴입니다.
읽을 때는 캐시를 먼저 읽고 캐시가 없으면 데이터베이스를 읽은 후 데이터를 꺼내어 캐시에 넣고 동시에 응답을 반환합니다.

업데이트 시 데이터베이스를 먼저 업데이트한 후 캐시를 삭제하세요.

캐시를 업데이트하지 않고 왜 캐시를 삭제하나요?

이유는 매우 간단합니다. 많은 경우 복잡한 캐싱 시나리오에서 캐시는 데이터베이스에서 직접 가져온 값이 아닙니다.

예를 들어 특정 테이블의 필드가 업데이트되면 해당 캐시가 다른 두 테이블의 데이터를 쿼리하고 캐시의 최신 값을 계산하는 작업을 수행해야 합니다.

또한 캐시 업데이트 비용이 매우 높을 때도 있습니다. 데이터베이스가 수정될 때마다 해당 캐시도 업데이트되어야 한다는 뜻인가요? 일부 시나리오에서는 그럴 수 있지만 더 복잡한 캐시된 데이터 계산 시나리오에서는 그렇지 않습니다. 캐시와 관련된 여러 테이블을 자주 수정하는 경우 캐시도 자주 업데이트됩니다. 하지만 문제는 이 캐시에 자주 액세스할 것인가 하는 것입니다.

예를 들어, 캐시에 포함된 테이블의 필드가 1분에 20번 또는 100번 수정되면 캐시는 20번 또는 100번 업데이트되지만 이 캐시는 1분에 1번만 읽혀집니다. 콜드 데이터가 많아요. 실제로 캐시만 삭제하면 1분에 한 번만 캐시가 다시 계산되므로 오버헤드가 크게 줄어들게 됩니다.

사실 캐시를 업데이트하는 대신 캐시를 삭제하는 것은 게으른 계산 아이디어입니다. 사용 여부와 상관없이 매번 복잡한 계산을 다시 수행하지 말고, 필요할 때 다시 계산하도록 하세요. mybatis 및 hibernate와 마찬가지로 모두 지연 로딩에 대한 아이디어를 가지고 있습니다. 부서를 조회하면 부서에서 직원 목록을 가져온다. 부서를 조회할 때마다 그 안에 있는 직원 1,000명의 데이터도 동시에 검색된다는 것은 말할 필요도 없다. 80%의 경우 이 부서를 확인하려면 이 부서의 정보에만 액세스하면 됩니다. 먼저 부서를 확인하고 동시에 내부 직원에 접근해야 합니다. 그런 다음 내부 직원에 접근하려는 경우에만 직원 1,000명에 대한 데이터베이스를 쿼리합니다.

가장 기본적인 캐시 불일치 문제 및 해결 방법

문제: 데이터베이스를 먼저 수정한 후 캐시를 삭제하세요. 캐시 삭제에 실패하면 데이터베이스에는 새 데이터가, 캐시에는 이전 데이터가 생성되어 데이터 불일치가 발생합니다.
Java 구현은 캐시와 데이터베이스 간의 이중 쓰기 일관성을 보장합니다.

해결책: 먼저 캐시를 삭제한 다음 데이터베이스를 수정하세요. 데이터베이스 수정이 실패하면 데이터베이스에 오래된 데이터가 있고 캐시가 비어 있으므로 데이터가 불일치하지 않습니다. 읽을 때 캐시가 없기 때문에 데이터베이스의 오래된 데이터를 읽은 다음 캐시에 업데이트합니다.

더 복잡한 데이터 불일치 문제 분석

데이터가 변경되었습니다. 먼저 캐시를 삭제한 후 데이터베이스를 수정하세요. 요청이 들어오면 캐시를 읽어보니 캐시가 비어 있는 걸 발견하고, 데이터베이스에 질의를 해서 수정 전의 오래된 데이터를 찾아 캐시에 넣어두는 거죠. 그런 다음 데이터 변경 프로그램이 데이터베이스 수정을 완료합니다.

끝났습니다. 데이터베이스와 캐시의 데이터가 다릅니다. . .

수억 개의 트래픽이 발생하는 높은 동시성 시나리오에서 캐시에 이러한 문제가 발생하는 이유는 무엇입니까?

이 문제는 데이터 조각을 동시에 읽고 쓰는 경우에만 발생할 수 있습니다. 실제로 동시성이 매우 낮은 경우, 특히 읽기 동시성이 매우 낮은 경우(일일 방문 횟수가 10,000회에 불과한 경우) 드문 경우지만 위에서 설명한 일관되지 않은 시나리오가 발생합니다. 그런데 문제는 매일 수억 건의 트래픽이 발생하고 초당 수만 건의 동시 읽기가 발생하는 경우 매초마다 데이터 업데이트 요청이 있는 한 위에서 언급한 데이터베이스 + 캐시 불일치가 발생할 수 있다는 것입니다.

해결 방법은 다음과 같습니다.

데이터를 업데이트할 때 데이터의 고유 식별자를 기반으로 작업을 라우팅하고 이를 jvm 내부 대기열로 보냅니다. 데이터를 읽을 때 데이터가 캐시에 없는 것으로 확인되면 데이터를 다시 읽고 캐시를 업데이트합니다. 고유 식별자에 따라 라우팅한 후 동일한 jvm 내부 큐로 전송됩니다. .

큐는 작업자 스레드에 해당합니다. 각 작업자 스레드는 해당 작업을 순차적으로 가져온 다음 하나씩 실행합니다. 이 경우 데이터 변경 작업의 경우 캐시를 먼저 삭제한 후 데이터베이스를 업데이트하지만 아직 업데이트가 완료되지 않은 상태입니다. 이때 읽기 요청이 와서 빈 캐시를 읽으면 캐시 업데이트 요청을 먼저 큐에 보낼 수 있으며 이때 큐에 백로그된 후 캐시 업데이트를 기다릴 수 있습니다. 동기식으로 완료됩니다.

여기에 최적화 지점이 있습니다. 실제로 여러 업데이트 캐시 요청을 함께 묶는 것은 의미가 없습니다. 따라서 대기열에 캐시를 업데이트하라는 요청이 이미 있는 것으로 확인되면 필터링이 수행될 수 있습니다. , 그러면 다른 것을 넣을 필요가 없습니다. 업데이트 요청 작업이 들어왔으며 이전 업데이트 작업 요청이 완료될 때까지 기다리면 됩니다.

해당 큐에 해당하는 작업자 스레드는 이전 작업에 대한 데이터베이스 수정을 완료한 후 다음 작업인 캐시 업데이트 작업을 수행합니다. 이때 데이터베이스에서 최신 값을 읽은 다음 캐시에 기록되었습니다.

요청이 여전히 대기 시간 범위 내에 있고 지속적인 폴링을 통해 값을 얻을 수 있는 것으로 확인되면 요청이 특정 시간 이상 대기하면 직접 반환됩니다. 그러면 이번에는 현재 이전 값이 반환됩니다. 데이터베이스에서 직접 읽을 수 있습니다.

높은 동시성 시나리오에서 이 솔루션에 주의해야 할 문제는 다음과 같습니다.

1. 읽기 요청이 오랫동안 차단됩니다.

읽기 요청이 약간 비동기적이므로 읽기 시간 초과에 주의해야 합니다. 문제가 발생했습니다. 각 읽기 요청은 제한 시간 내에 반환되어야 합니다.

이 솔루션의 가장 큰 위험 점은 데이터가 자주 업데이트되어 대기열에 대규모 업데이트 작업 백로그가 발생하고 읽기 요청에 대해 많은 시간 초과가 발생하여 결국 큰 폭의 오류가 발생한다는 것입니다. 데이터베이스로 직접 이동하는 요청 수입니다. 시뮬레이션된 실제 테스트를 실행하여 데이터가 얼마나 자주 업데이트되는지 확인하십시오.

또 다른 점은 대기열에 있는 여러 데이터 항목에 대한 업데이트 작업의 백로그가 있을 수 있으므로 자체 비즈니스 조건에 따라 테스트해야 할 수 있으며 여러 서비스를 배포해야 할 수 있으며 각 서비스는 일부 데이터 업데이트를 공유합니다. 운영. 메모리 큐가 실제로 100개 제품의 재고 수정 작업을 압축하고 각 재고 수정 작업을 완료하는 데 10ms가 걸리는 경우 마지막 제품에 대한 읽기 요청은 데이터를 얻을 수 있기 전에 10 * 100 = 1000ms = 1s 동안 기다릴 수 있습니다. 이로 인해 읽기 요청이 장기간 차단됩니다.

비즈니스 시스템의 실제 운영을 기반으로 몇 가지 스트레스 테스트를 수행하고 온라인 환경을 시뮬레이션하여 가장 바쁜 시간 동안 메모리 큐가 얼마나 많은 업데이트 작업을 압박할 수 있는지 확인하고, 이로 인해 마지막 업데이트 작업이 얼마나 오래 걸릴 수 있는지 확인하세요. 해당 읽기 요청이 200ms 내에 반환되면 가장 바쁜 시간에도 10개의 업데이트 작업 백로그가 있고 최대 대기 시간이 200ms라고 계산하면 괜찮습니다.

메모리 대기열에 백로그될 수 있는 업데이트 작업이 많은 경우 각 컴퓨터에 배포된 서비스 인스턴스가 더 적은 데이터를 처리하도록 더 많은 컴퓨터를 추가해야 합니다. 그러면 각 메모리 대기열의 업데이트 작업 백로그가 발생합니다. 소수가 됩니다.

사실 이전 프로젝트 경험에 따르면 일반적으로 데이터 쓰기 빈도가 매우 낮으므로 일반적으로 대기열의 업데이트 작업 백로그가 매우 작아야 합니다. 높은 읽기 동시성과 읽기 캐싱 아키텍처를 목표로 하는 이와 같은 프로젝트의 경우 일반적으로 초당 QPS가 수백에 도달할 수 있으면 쓰기 요청이 거의 없습니다.

대략적인 계산

초당 500개의 쓰기 작업이 있고 5개의 시간 조각으로 나누어지면 200ms마다 100개의 쓰기 작업이 있으며 각 메모리 큐는 20개에 배치됩니다. 5개의 쓰기 작업이 백로그되었습니다. 각 쓰기 작업 성능 테스트 후 일반적으로 약 20ms 내에 완료되므로 각 메모리 큐의 데이터에 대한 읽기 요청은 최대 잠시 동안만 중단되며 반드시 200ms 이내에 반환됩니다.

지금까지 간단한 계산을 통해 단일 머신에서 지원하는 쓰기 QPS는 수백 개에서도 문제가 없다는 것을 알 수 있습니다. 쓰기 QPS가 10배 증가하면 머신은 10배로 확장되고 각 머신은 대기열은 20개입니다.

2. 읽기 요청의 동시성이 너무 높습니다

위 상황이 발생하면 또 다른 위험이 있는지 확인하기 위해 여기에서 스트레스 테스트를 수행해야 합니다. 즉, 많은 수의 읽기 요청이 갑자기 중단될 수 있습니다. 수십 밀리초의 지연은 서비스가 이를 처리할 수 있는지 여부와 최대 극한 상황을 처리하는 데 필요한 시스템 수에 따라 다릅니다.

그러나 모든 데이터가 동시에 업데이트되는 것은 아니며 캐시가 동시에 만료되지 않기 때문에 소수의 데이터 캐시는 매번 유효하지 않을 수 있으며, 그런 다음 해당 데이터에 해당하는 읽기 요청은 동시성이 매우 클 것입니다.

3. 다중 서비스 인스턴스 배포를 위한 요청 라우팅

이 서비스는 여러 인스턴스를 배포할 수 있으므로 데이터 업데이트 작업 및 캐시 업데이트 작업을 수행하는 요청이 Nginx 서버 상위를 통해 동일한 서비스 인스턴스로 라우팅되도록 해야 합니다.

예를 들어, 동일한 제품에 대한 모든 읽기 및 쓰기 요청은 동일한 시스템으로 라우팅됩니다. 특정 요청 매개변수에 따라 서비스 간 자체 해시 라우팅을 수행하거나 Nginx의 해시 라우팅 기능 등을 사용할 수 있습니다.

4. 핫한 제품의 라우팅 문제로 인해 편향된 요청이 발생합니다

특정 제품의 읽기 및 쓰기 요청이 유난히 많고 모두 동일한 머신의 동일한 대기열로 전송되는 경우 제품에 과도한 부담이 발생할 수 있습니다. 특정 기계. 즉, 제품 데이터가 업데이트될 때만 캐시가 지워지고 읽기 및 쓰기 동시성이 발생하기 때문에 실제로 업데이트 빈도가 너무 높지 않으면 이 영향은 비즈니스 시스템에 따라 다릅니다. 문제는 특별히 크지는 않지만 일부 시스템의 부하가 더 높을 수 있는 것은 사실입니다.

위 내용은 Java 구현은 캐시와 데이터베이스 간의 이중 쓰기 일관성을 보장합니다.의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

본 웹사이트의 성명
본 글의 내용은 네티즌들의 자발적인 기여로 작성되었으며, 저작권은 원저작자에게 있습니다. 본 사이트는 이에 상응하는 법적 책임을 지지 않습니다. 표절이나 침해가 의심되는 콘텐츠를 발견한 경우 admin@php.cn으로 문의하세요.

핫 AI 도구

Undresser.AI Undress

Undresser.AI Undress

사실적인 누드 사진을 만들기 위한 AI 기반 앱

AI Clothes Remover

AI Clothes Remover

사진에서 옷을 제거하는 온라인 AI 도구입니다.

Undress AI Tool

Undress AI Tool

무료로 이미지를 벗다

Clothoff.io

Clothoff.io

AI 옷 제거제

AI Hentai Generator

AI Hentai Generator

AI Hentai를 무료로 생성하십시오.

뜨거운 도구

메모장++7.3.1

메모장++7.3.1

사용하기 쉬운 무료 코드 편집기

SublimeText3 중국어 버전

SublimeText3 중국어 버전

중국어 버전, 사용하기 매우 쉽습니다.

스튜디오 13.0.1 보내기

스튜디오 13.0.1 보내기

강력한 PHP 통합 개발 환경

드림위버 CS6

드림위버 CS6

시각적 웹 개발 도구

SublimeText3 Mac 버전

SublimeText3 Mac 버전

신 수준의 코드 편집 소프트웨어(SublimeText3)

PHP에서 MySQL 백업 및 복원을 사용하는 방법은 무엇입니까? PHP에서 MySQL 백업 및 복원을 사용하는 방법은 무엇입니까? Jun 03, 2024 pm 12:19 PM

PHP에서 MySQL 데이터베이스를 백업하고 복원하는 작업은 다음 단계에 따라 수행할 수 있습니다. 데이터베이스 백업: mysqldump 명령을 사용하여 데이터베이스를 SQL 파일로 덤프합니다. 데이터베이스 복원: mysql 명령을 사용하여 SQL 파일에서 데이터베이스를 복원합니다.

PHP에서 MySQL 쿼리 성능을 최적화하는 방법은 무엇입니까? PHP에서 MySQL 쿼리 성능을 최적화하는 방법은 무엇입니까? Jun 03, 2024 pm 08:11 PM

선형 복잡성에서 로그 복잡성까지 조회 시간을 줄이는 인덱스를 구축하여 MySQL 쿼리 성능을 최적화할 수 있습니다. SQL 삽입을 방지하고 쿼리 성능을 향상하려면 PREPAREDStatements를 사용하세요. 쿼리 결과를 제한하고 서버에서 처리되는 데이터의 양을 줄입니다. 적절한 조인 유형 사용, 인덱스 생성, 하위 쿼리 사용 고려 등 조인 쿼리를 최적화합니다. 쿼리를 분석하여 병목 현상을 식별하고, 캐싱을 사용하여 데이터베이스 로드를 줄이고, 오버헤드를 최소화합니다.

PHP를 사용하여 MySQL 테이블에 데이터를 삽입하는 방법은 무엇입니까? PHP를 사용하여 MySQL 테이블에 데이터를 삽입하는 방법은 무엇입니까? Jun 02, 2024 pm 02:26 PM

MySQL 테이블에 데이터를 삽입하는 방법은 무엇입니까? 데이터베이스에 연결: mysqli를 사용하여 데이터베이스에 대한 연결을 설정합니다. SQL 쿼리 준비: 삽입할 열과 값을 지정하는 INSERT 문을 작성합니다. 쿼리 실행: query() 메서드를 사용하여 삽입 쿼리를 실행하면 확인 메시지가 출력됩니다.

PHP를 사용하여 MySQL 테이블을 만드는 방법은 무엇입니까? PHP를 사용하여 MySQL 테이블을 만드는 방법은 무엇입니까? Jun 04, 2024 pm 01:57 PM

PHP를 사용하여 MySQL 테이블을 생성하려면 다음 단계가 필요합니다. 데이터베이스에 연결합니다. 데이터베이스가 없으면 작성하십시오. 데이터베이스를 선택합니다. 테이블을 생성합니다. 쿼리를 실행합니다. 연결을 닫습니다.

MySQL 8.4에서 mysql_native_password가 로드되지 않음 오류를 수정하는 방법 MySQL 8.4에서 mysql_native_password가 로드되지 않음 오류를 수정하는 방법 Dec 09, 2024 am 11:42 AM

MySQL 8.4(2024년 최신 LTS 릴리스)에 도입된 주요 변경 사항 중 하나는 "MySQL 기본 비밀번호" 플러그인이 더 이상 기본적으로 활성화되지 않는다는 것입니다. 또한 MySQL 9.0에서는 이 플러그인을 완전히 제거합니다. 이 변경 사항은 PHP 및 기타 앱에 영향을 미칩니다.

iOS 18에는 손실되거나 손상된 사진을 검색할 수 있는 새로운 '복구된' 앨범 기능이 추가되었습니다. iOS 18에는 손실되거나 손상된 사진을 검색할 수 있는 새로운 '복구된' 앨범 기능이 추가되었습니다. Jul 18, 2024 am 05:48 AM

Apple의 최신 iOS18, iPadOS18 및 macOS Sequoia 시스템 릴리스에는 사진 애플리케이션에 중요한 기능이 추가되었습니다. 이 기능은 사용자가 다양한 이유로 손실되거나 손상된 사진과 비디오를 쉽게 복구할 수 있도록 설계되었습니다. 새로운 기능에는 사진 앱의 도구 섹션에 '복구됨'이라는 앨범이 도입되었습니다. 이 앨범은 사용자가 기기에 사진 라이브러리에 포함되지 않은 사진이나 비디오를 가지고 있을 때 자동으로 나타납니다. "복구된" 앨범의 출현은 데이터베이스 손상으로 인해 손실된 사진과 비디오, 사진 라이브러리에 올바르게 저장되지 않은 카메라 응용 프로그램 또는 사진 라이브러리를 관리하는 타사 응용 프로그램에 대한 솔루션을 제공합니다. 사용자는 몇 가지 간단한 단계만 거치면 됩니다.

PHP에서 MySQLi를 사용하여 데이터베이스 연결을 설정하는 방법에 대한 자세한 튜토리얼 PHP에서 MySQLi를 사용하여 데이터베이스 연결을 설정하는 방법에 대한 자세한 튜토리얼 Jun 04, 2024 pm 01:42 PM

MySQLi를 사용하여 PHP에서 데이터베이스 연결을 설정하는 방법: MySQLi 확장 포함(require_once) 연결 함수 생성(functionconnect_to_db) 연결 함수 호출($conn=connect_to_db()) 쿼리 실행($result=$conn->query()) 닫기 연결( $conn->close())

PHP에서 데이터베이스 연결 오류를 처리하는 방법 PHP에서 데이터베이스 연결 오류를 처리하는 방법 Jun 05, 2024 pm 02:16 PM

PHP에서 데이터베이스 연결 오류를 처리하려면 다음 단계를 사용할 수 있습니다. mysqli_connect_errno()를 사용하여 오류 코드를 얻습니다. 오류 메시지를 얻으려면 mysqli_connect_error()를 사용하십시오. 이러한 오류 메시지를 캡처하고 기록하면 데이터베이스 연결 문제를 쉽게 식별하고 해결할 수 있어 애플리케이션이 원활하게 실행될 수 있습니다.

See all articles