기계 번역으로 제공되는 번역입니다. 제공된 번역과 원본 영어의 내용이 상충하는 경우에는 영어 버전이 우선합니다.
아마존 QLDB 동시성 모델
중요
지원 종료 알림: 기존 고객은 2025년 7월 31일 지원이 종료될 QLDB 때까지 Amazon을 사용할 수 있습니다. 자세한 내용은 아마존 QLDB 원장을 Amazon Aurora SQL Postgre로 마이그레이션을
QLDBAmazon은 고성능 온라인 트랜잭션 처리 (OLTP) 워크로드의 요구 사항을 해결하기 위한 것입니다. QLDBSQL유사한 쿼리 기능을 지원하고 전체 ACID 트랜잭션을 제공합니다. 또한 QLDB 데이터 항목은 문서이므로 스키마 유연성과 직관적인 데이터 모델링을 제공합니다. 저널을 중심으로 하면 데이터에 대한 모든 변경 사항의 완전하고 검증 가능한 기록에 액세스하고 필요에 따라 일관된 트랜잭션을 다른 데이터 서비스로 스트리밍할 수 있습니다. QLDB
낙관적 동시성 제어
QLDB에서는 낙관적 동시성 제어 () 를 사용하여 동시성 제어를 구현합니다. OCC OCC여러 트랜잭션이 서로 간섭하지 않고 자주 완료될 수 있다는 원칙에 따라 작동합니다.
를 사용하면 OCC 의 트랜잭션은 데이터베이스 리소스에 대한 잠금을 QLDB 획득하지 않고 직렬화가 가능한 완전한 격리 상태로 작동합니다. QLDB동시 트랜잭션을 순차적으로 실행하므로 해당 트랜잭션이 순차적으로 시작된 것과 동일한 결과를 생성합니다.
각 트랜잭션은 체결하기 전에 검증 검사를 수행하여 다른 체결된 트랜잭션이 액세스 중인 데이터를 수정하지는 않았는지 확인합니다. 이 검사에서 충돌하는 수정 사항이 발견되거나 데이터 상태가 변경되면 체결된 트랜잭션이 거부됩니다. 하지만 트랜잭션을 다시 시작할 수 있습니다.
트랜잭션이 에 QLDB 쓰면 OCC 모델의 유효성 검사가 저절로 QLDB 구현됩니다. 의 OCC 검증 단계에서 실패로 인해 트랜잭션을 저널에 기록할 수 없는 경우 응용 프로그램 OccConflictException
계층에 를 QLDB 반환합니다. 애플리케이션 소프트웨어는 트랜잭션이 다시 시작되도록 할 책임이 있습니다. 애플리케이션은 거부된 트랜잭션을 중단한 다음 처음부터 전체 트랜잭션을 다시 시도해야 합니다.
QLDB드라이버가 OCC 충돌 및 기타 일시적 예외를 처리하고 재시도하는 방법을 알아보려면 을 참조하십시오. Amazon 드라이버에 대한 재시도 정책 이해 QLDB
인덱스를 사용하여 전체 테이블 스캔 방지
QLDB에서는 모든 PartiQL 문 (SELECT모든 쿼리 포함) 이 트랜잭션에서 처리되며 트랜잭션 제한 시간이 적용됩니다.
인덱싱된 필드 또는 문서 ID를 기준으로 필터링하는 WHERE
조건자 절을 사용하여 명령문을 실행하는 것이 가장 좋습니다. QLDB문서를 효율적으로 검색하려면 인덱싱된 필드에 항등 연산자가 필요합니다 (예: 또는). WHERE indexedField = 123
WHERE indexedField
IN (456, 789)
이 인덱스 검색이 없으면 문서를 읽을 때 테이블 전체를 QLDB 스캔해야 합니다. 이로 인해 쿼리 지연 및 트랜잭션 시간 초과가 발생할 수 있으며 경쟁 트랜잭션과 OCC 충돌이 발생할 가능성도 높아집니다.
VIN
필드에만 인덱스가 있는 Vehicle
라는 명칭의 표를 예로 들어 보겠습니다. 여기에는 다음 문서가 포함됩니다.
VIN | Make | 모델 | 색상 |
---|---|---|---|
"1N4AL11D75C109151" |
"Audi" |
"A5" |
"Silver" |
"KM8SRDHF6EU074761" |
"Tesla" |
"Model S" |
"Blue" |
"3HGGK5G53FM761765" |
"Ducati" |
"Monster 1200" |
"Yellow" |
"1HVBBAANXWH544237" |
"Ford" |
"F 150" |
"Black" |
"1C4RJFAG0FC625797" |
"Mercedes" |
"CLK 350" |
"White" |
Alice와 Bob이라는 두 명의 동시 사용자가 원장에 있는 같은 표를 사용하고 있습니다. 그들은 다음과 같이 서로 다른 두 문서를 업데이트하려고 합니다.
Alice:
UPDATE Vehicle AS v
SET v.Color = 'Blue'
WHERE v.VIN = '1N4AL11D75C109151'
Bob:
UPDATE Vehicle AS v
SET v.Color = 'Red'
WHERE v.Make = 'Tesla' AND v.Model = 'Model S'
Alice와 Bob이 동시에 트랜잭션을 시작한다고 가정해 봅시다. Alice의 UPDATE
문은 VIN
필드에서 인덱싱된 조회를 수행하므로 해당 문서 하나만 읽으면 됩니다. Alice가 먼저 트랜잭션을 완료하고 트랜잭션을 성공적으로 체결합니다.
Bob의 명령문은 인덱싱되지 않은 필드를 필터링하므로 표 스캔을 수행한 후 OccConflictException
가 발생합니다. 그 이유는 Alice가 체결한 트랜잭션이 Bob의 문이 액세스하고 있는 데이터를 수정했기 때문입니다. 이러한 데이터에넌 Bob이 업데이트하는 문서뿐만 아니라 표의 모든 문서가 포함됩니다.
삽입 충돌 OCC
OCC충돌에는 이전에 존재했던 문서뿐만 아니라 새로 삽입된 문서가 포함될 수 있습니다. 두 명의 동시 사용자(Alice와 Bob)가 한 원장의 동일한 표로 작업하고 있는 다음 다이어그램을 생각해 봅시다. 둘 경우 조건자 값이 아직 존재하지 않는 경우에만 새 문서를 삽입하려고 합니다.
![두 동시 QLDB 사용자 간의 충돌 예외의 예를 보여주는 Amazon 낙관적 동시성 제어 (OCC) 다이어그램.](images/occ-example.png)
이 예에서 Alice와 Bob은 모두 단일 트랜잭션 내에서 다음 SELECT
및 INSERT
문을 실행합니다. 애플리케이션은 SELECT
문이 결과를 반환하지 않는 경우에만 INSERT
문을 실행합니다.
SELECT * FROM Vehicle v WHERE v.VIN = 'ABCDE12345EXAMPLE'
INSERT INTO Vehicle VALUE
{
'VIN' : 'ABCDE12345EXAMPLE',
'Type' : 'Wagon',
'Year' : 2019,
'Make' : 'Subaru',
'Model' : 'Outback',
'Color' : 'Gray'
}
Alice와 Bob이 동시에 트랜잭션을 시작한다고 가정해 봅시다. 두 SELECT
쿼리 모두 ABCDE12345EXAMPLE
의 VIN
이 있는 기존 문서를 반환하지 않습니다. 따라서 애플리케이션은 INSERT
문을 따라 진행됩니다.
Alice가 먼저 트랜잭션을 완료하고 트랜잭션을 성공적으로 체결합니다. 그런 다음 Bob은 트랜잭션을 커밋하려고 하지만 이를 QLDB 거부하고 트랜잭션을 실행합니다. OccConflictException
Alice의 커밋된 트랜잭션이 Bob의 SELECT
쿼리 결과 집합을 수정하고 Bob의 트랜잭션을 커밋하기 전에 이러한 OCC 충돌을 감지하기 때문입니다.
이 트랜잭션 예가 멱등성을 가지려면 SELECT
쿼리가 필요합니다. 그러면 Bob은 전체 트랜잭션을 처음부터 다시 시도할 수 있습니다. 하지만 다음 SELECT
쿼리는 Alice가 삽입한 문서를 반환하므로 Bob의 애플리케이션은 해당 INSERT
를 실행하지 않습니다.
트랜잭션에 멱등성 부여하기
이전 섹션의 삽입 트랜잭션도 멱등성 트랜잭션의 한 예입니다. 즉, 동일한 트랜잭션을 여러 번 실행하면 동일한 결과가 생성됩니다. Bob이 특정 VIN
가 이미 존재하는지 먼저 확인하지 않고 INSERT
를 실행하면 표에 중복된 VIN
값이 있는 문서가 생성될 수 있습니다.
충돌 외에도 다른 재시도 시나리오도 고려해 보세요. OCC 예를 들어 서버 측에서 트랜잭션을 QLDB 성공적으로 커밋했지만 응답을 기다리는 동안 클라이언트 제한 시간이 초과될 수 있습니다. 가장 좋은 방법은 동시 실행 또는 재시도 시 예상치 못한 부작용이 발생하지 않도록 쓰기 트랜잭션에 멱득성을 부여하는 것입니다.
수정 충돌 OCC
QLDB동일한 저널 블록의 수정 내용을 동시에 수정할 수 없도록 합니다. 두 명의 동시 사용자(Alice와 Bob)가 원장의 동일한 블록에서 체결된 서로 다른 두 개의 문서 수정본을 수정하려는 경우를 예로 들어 보겠습니다. 먼저 Alice는 다음과 같이 REDACT_REVISION
저장 프로시저를 실행하여 한 수정본의 수정을 요청합니다.
EXEC REDACT_REVISION `{strandId:"JdxjkR9bSYB5jMHWcI464T", sequenceNo:17}`, '5PLf9SXwndd63lPaSIa0O6', 'ADR2Ll1fGsU4Jr4EqTdnQF'
그러면 Alice의 요청이 아직 처리 중인 동안 Bob은 다음과 같이 다른 수정본의 수정을 요청합니다.
EXEC REDACT_REVISION `{strandId:"JdxjkR9bSYB5jMHWcI464T", sequenceNo:17}`, '8F0TPCmdNQ6JTRpiLj2TmW', '05K8zpGYWynDlEOK5afDRc'
QLDB서로 다른 두 개의 문서 수정본을 수정하려고 하는 OccConflictException
경우에도 Bob의 요청을 거부합니다. 이는 Bob의 수정본이 Alice가 수정 중인 수정본과 동일한 블록에 있기 때문입니다. Alice의 요청 처리가 완료되면 Bob은 수정 요청을 다시 시도할 수 있습니다.
마찬가지로, 두 개의 동시 트랜잭션이 동일한 수정 내용을 수정하려고 시도하는 경우 하나의 요청만 처리될 수 있습니다. 다른 요청은 수정이 완료될 때까지 OCC 충돌 예외가 발생하여 실패합니다. 이후에 동일한 수정본을 수정해 달라는 요청을 하면 해당 수정본이 이미 수정되었음을 나타내는 오류가 발생합니다.
동시 세션 관리
관계형 데이터베이스 관리 시스템 (RDBMS) 을 사용해 본 경험이 있다면 동시 연결 제한에 대해 잘 알고 있을 것입니다. QLDB트랜잭션이 HTTP 요청 및 응답 메시지로 실행되기 때문에 기존 RDBMS 연결과 같은 개념이 없습니다.
에서 QLDB 유사한 개념은 액티브 세션입니다. 세션은 개념적으로 사용자 로그인과 비슷합니다. 즉, 원장에 대한 데이터 트랜잭션 요청에 대한 정보를 관리합니다. 활성 세션은 트랜잭션을 활발하게 실행하는 세션입니다. 또한 서비스가 즉시 다른 트랜잭션을 시작할 것으로 예상하는, 트랜잭션을 최근에 완료한 세션일 수도 있습니다. QLDB세션당 하나의 활성 실행 트랜잭션을 지원합니다.
원장당 동시 활성 세션의 한도는 아마존의 할당량 및 한도 QLDB에 정의되어 있습니다. 이 한도에 도달한 후 트랜잭션을 시작하려는 모든 세션에서 오류(LimitExceededException
)가 발생합니다.
세션의 수명 주기 및 데이터 트랜잭션을 실행할 때 QLDB 드라이버가 세션을 처리하는 방법에 대한 자세한 내용은 을 참조하십시오드라이버를 사용한 세션 관리. 드라이버를 사용하여 애플리케이션에서 세션 풀을 구성하는 모범 사례는 Amazon QLDB QLDB 드라이버 권장 사항을 참조하십시오 QldbDriver 객체 구성.