DynamoDB에서 테이블 스캔
Amazon DynamoDB의 Scan
작업은 테이블 또는 보조 인덱스의 모든 항목을 읽어옵니다. 기본적으로 Scan
작업은 테이블이나 인덱스에 속한 항목의 데이터 속성을 모두 반환합니다. 하지만 Scan
작업에서 ProjectionExpression
파라미터를 사용하면 모두가 아닌 일부 속성만 가져올 수 있습니다.
Scan
은 항상 결과 집합을 반환합니다. 일치하는 항목이 없다면 결과 집합은 비어 있습니다.
단일 Scan
요청으로 최대 1MB의 데이터를 가져올 수 있습니다. 선택에 따라 DynamoDB가 이 데이터에 필터 표현식을 적용하여 사용자에게 반환되기 전에 결과의 범위를 좁힐 수 있습니다.
스캔에 대한 필터 표현식
Scan
결과를 한층 더 좁혀야 하는 경우 선택적으로 필터 표현식을 제공할 수 있습니다. 필터 표현식은 Scan
결과 내에서 어떤 항목을 반환할지를 결정합니다. 다른 모든 결과는 폐기됩니다.
필터 표현식은 Scan
이 완료된 후 결과가 반환되기 전에 적용됩니다. 따라서 필터 표현식이 있는지 여부와 상관없이 Scan
은 동일한 양의 읽기 용량을 사용합니다.
Scan
작업은 최대 1MB의 데이터를 가져올 수 있습니다. 이 제한은 필터 표현식이 평가되기 전에 적용됩니다.
Scan
을 사용하면 필터 표현식에 파티션 키와 정렬 키 속성을 포함하여 모든 속성을 지정할 수 있습니다.
필터 표현식의 구분은 조건 표현식의 구문과 같습니다. 필터 표현식은 동일한 비교기, 함수 및 논리적 연산자를 조건 표현식으로 사용할 수 있습니다. 논리 연산자에 대한 자세한 내용은 DynamoDB의 조건 및 필터 표현식, 연산자, 함수 섹션을 참조하세요.
예
다음 AWS Command Line Interface(AWS CLI) 예제에서는 Thread
테이블을 스캔하여 특정 사용자가 마지막으로 게시한 항목만 반환합니다.
aws dynamodb scan \ --table-name Thread \ --filter-expression "LastPostedBy = :name" \ --expression-attribute-values '{":name":{"S":"User A"}}'
결과 세트의 항목 수 제한
Scan
작업을 사용하여 결과에 반환되는 항목 수를 제한할 수 있습니다. 이렇게 하려면 필터 표현식 평가 전에 Limit
파라미터를 Scan
작업에서 반환할 최대 항목 수로 설정합니다.
예를 들어 Limit
값이 6
이고 필터 표현식이 없는 상태에서 테이블을 Scan
한다고 가정합니다. Scan
결과에 테이블의 처음 6개 항목이 포함됩니다.
이제 필터 표현식을 Scan
에 추가한다고 가정합니다. 이 경우 DynamoDB는 반환된 6개 항목에 필터 표현식을 적용하고 일치하지 않는 항목을 무시합니다. 최종 Scan
결과에는 필터링된 항목 수에 따라 6개 이하의 항목이 포함됩니다.
결과 페이지 매김
DynamoDB는 Scan
작업 결과의 페이지를 매깁니다. 페이지를 매기면 Scan
결과는 크기가 1MB 이하인 데이터 ‘페이지’로 분리됩니다. 애플리케이션은 결과의 첫 번째 페이지를 처리한 다음 두 번째 페이지를 처리하고 이런 식으로 계속할 수 있습니다.
단일 Scan
은 1MB 크기 한도 내에 맞는 결과 집합만 반환합니다.
추가 결과가 있는지 확인하고 이러한 결과를 한번에 한 페이지에 가져오려면 애플리케이션에서 다음을 수행해야 합니다.
-
하위 수준
Scan
결과를 확인합니다.-
결과에
LastEvaluatedKey
요소가 포함되는 경우 2단계로 계속합니다. -
결과에
LastEvaluatedKey
가 없는 경우 더 이상 가져올 항목이 없습니다.
-
-
이전과 동일한 파라미터를 이용해 새로운
Scan
요청을 구성합니다. 그러나 이번에는 1단계에서LastEvaluatedKey
값을 가져와서 새로운Scan
요청의ExclusiveStartKey
파라미터로 사용합니다. -
새로운
Scan
요청을 실행합니다. -
1단계로 이동합니다.
다시 말해서, Scan
응답의 LastEvaluatedKey
를 다음 Scan
요청에 대한 ExclusiveStartKey
로 사용해야 합니다. Scan
응답에 LastEvaluatedKey
요소가 없는 경우 결과의 최종 페이지를 검색한 것입니다. 결과 집합의 마지막에 도달했음을 알 수 있는 유일한 방법은 LastEvaluatedKey
가 없는지 확인하는 것입니다.
AWS CLI를 사용하여 이 동작을 볼 수 있습니다. AWS CLI는 LastEvaluatedKey
가 결과에 더 이상 없을 때까지 하위 수준 Scan
요청을 DynamoDB에 반복적으로 보냅니다. 전체 Movies
테이블을 스캔하여 특정 장르의 영화만 반환하는 다음 AWS CLI 예제를 살펴보겠습니다.
aws dynamodb scan \ --table-name Movies \ --projection-expression "title" \ --filter-expression 'contains(info.genres,:gen)' \ --expression-attribute-values '{":gen":{"S":"Sci-Fi"}}' \ --page-size 100 \ --debug
일반적으로 AWS CLI에서는 페이지 매김이 자동으로 처리됩니다. 그러나 이 예제에서는 AWS CLI --page-size
파라미터가 페이지당 항목 수를 제한합니다. --debug
파라미터는 요청 및 응답에 대한 하위 수준 정보를 출력합니다.
참고
페이지 매김 결과는 전달한 입력 매개 변수에 따라 달라집니다.
aws dynamodb scan --table-name Prices --max-items 1
사용 시NextToken
을(를) 반환합니다.aws dynamodb scan --table-name Prices --limit 1
사용 시LastEvaluatedKey
을(를) 반환합니다.
특히 --starting-token
사용 시 NextToken
값이 필요하다는 점에 유의하십시오.
예제를 실행하면 DynamoDB의 첫 응답이 다음과 유사합니다.
2017-07-07 12:19:14,389 - MainThread - botocore.parsers - DEBUG - Response body: b'{"Count":7,"Items":[{"title":{"S":"Monster on the Campus"}},{"title":{"S":"+1"}}, {"title":{"S":"100 Degrees Below Zero"}},{"title":{"S":"About Time"}},{"title":{"S":"After Earth"}}, {"title":{"S":"Age of Dinosaurs"}},{"title":{"S":"Cloudy with a Chance of Meatballs 2"}}], "LastEvaluatedKey":{"year":{"N":"2013"},"title":{"S":"Curse of Chucky"}},"ScannedCount":100}'
응답의 LastEvaluatedKey
는 가져온 항목이 전부가 아님을 나타냅니다. 그러면 AWS CLI는 DynamoDB에 다른 Scan
요청을 보냅니다. 이 요청과 응답 패턴은 마지막 응답이 반환될 때까지 계속됩니다.
2017-07-07 12:19:17,830 - MainThread - botocore.parsers - DEBUG - Response body: b'{"Count":1,"Items":[{"title":{"S":"WarGames"}}],"ScannedCount":6}'
LastEvaluatedKey
가 없으면 가져올 항목이 더 이상 없음을 나타냅니다.
참고
AWS SDK는 하위 수준 DynamoDB 응답(LastEvaluatedKey
의 유무 포함)을 처리하여 Scan
결과 페이지 매김에 대해 다양한 추상을 제공합니다. 예를 들어, SDK for Java 문서 인터페이스는 java.util.Iterator
지원을 제공하므로 한 번에 하나씩 결과를 볼 수 있습니다.
다양한 프로그래밍 언어의 코드 예제를 보려면 Amazon DynamoDB 시작 안내서 및 해당 언어의 AWS SDK 설명서를 참조하세요.
결과 내 항목 수 계산
Scan
응답에는 기준과 일치하는 항목 외에도 다음 요소가 포함됩니다.
-
ScannedCount
-ScanFilter
를 적용하기 전에 평가되는 항목 수입니다.ScannedCount
값이 높지만Count
결과가 거의 없거나 전혀 없는 경우Scan
작업이 비효율적이라는 것을 나타냅니다. 요청에 필터를 사용하지 않은 경우ScannedCount
는Count
와 동일합니다. -
Count
- 필터 표현식(있는 경우)을 적용한 후에 남아 있는 항목 수입니다.
참고
필터 표현식을 사용하지 않으면 ScannedCount
와 Count
는 동일한 값을 갖습니다.
Scan
결과 집합의 크기가 1MB보다 크면 ScannedCount
와 Count
는 총 항목 수의 일부만 표시합니다. 모든 결과를 검색하려면 여러 Scan
작업을 수행해야 합니다(결과 페이지 매김 참조).
각 Scan
응답에는 해당하는 특정 Scan
요청에 따라 처리된 항목의 ScannedCount
와 Count
가 포함됩니다. 모든 Scan
요청의 총계를 가져오려면 ScannedCount
와 Count
의 누계를 계산할 수 있습니다.
스캔에서 사용된 용량 단위
테이블이나 보조 인덱스를 Scan
할 수 있습니다. Scan
작업은 다음과 같이 읽기 용량 단위를 사용합니다.
다음을 Scan 하는 경우... |
DynamoDB는 다음에서 읽기 용량 단위를 사용합니다... |
---|---|
표 | 테이블의 할당된 읽기 용량. |
글로벌 보조 인덱스 | 인덱스의 할당된 읽기 용량. |
로컬 보조 인덱스 | 기본 테이블의 프로비저닝된 읽기 용량. |
기본적으로, Scan
작업은 얼마나 많은 읽기 용량을 사용하는지에 대한 데이터를 반환하지 않습니다. 하지만 Scan
요청에서 ReturnConsumedCapacity
파라미터를 지정하여 이 정보를 얻을 수 있습니다. 다음은 ReturnConsumedCapacity
에 대한 유효한 설정입니다.
-
NONE
- 사용된 용량 데이터가 반환되지 않습니다. (이 값이 기본값입니다.) TOTAL
- 사용된 읽기 용량 단위의 집계 수가 응답에 포함됩니다.INDEXES
- 액세스한 각 테이블 및 인덱스에 사용된 용량과 함께 사용된 읽기 용량 단위의 집계 수가 응답에 표시됩니다.
DynamoDB는 애플리케이션에 반환되는 데이터 양이 아닌 항목 개수와 항목 크기를 기준으로 사용된 읽기 용량 단위의 수를 계산합니다. 이러한 이유로, 모든 속성을 요청하든(기본 동작) 또는 일부 속성만 요청하든(프로젝션 표현식 사용) 상관없이 사용된 용량 단위의 수는 동일합니다. 필터 표현식 사용 여부와 관계없이 숫자는 동일합니다. Scan
는 최대 4KB의 항목에 대해 초당 강력히 일관된 읽기 1회 또는 초당 최종적으로 일관된 읽기 2회를 수행하기 위해 최소한의 읽기 용량 단위를 사용합니다. 보다 큰 항목을 읽어야 하는 경우, DynamoDB에 추가 읽기 요청 단위가 필요합니다. 파티션 키의 양이 적은 빈 테이블과 매우 큰 테이블에서는 스캔된 데이터 양을 초과하여 일부 추가 RCU에 요금이 부과될 수 있습니다. 여기에는 데이터가 없는 경우에도 Scan
요청을 처리하는 데 드는 비용이 포함됩니다.
스캔에 대한 읽기 정합성
기본적으로 Scan
작업은 최종적 일관된 읽기를 수행합니다. 따라서 최근 완료된 PutItem
또는 UpdateItem
작업으로 인해 Scan
결과에 변경 사항이 반영되지 않을 수 있습니다. 자세한 내용은 DynamoDB 읽기 일관성 섹션을 참조하세요.
Scan
이 시작되는 시점을 기준으로 강력한 일관된 읽기가 필요한 경우 Scan
요청에서 ConsistentRead
파라미터를 true
로 설정합니다. 그러면 Scan
작업 시작 전에 마친 쓰기 작업까지 모두 Scan
응답에 포함됩니다.
ConsistentRead
를 true
로 설정하면 DynamoDB Streams를 함께 사용하는 테이블 백업 또는 복제 시나리오에서 유용할 수 있습니다. 처음에는 ConsistentRead
을 true로 설정한 상태에서 Scan
를 사용하여 테이블 데이터에 대한 일관된 복사본을 얻습니다. 그러면 DynamoDB Streams가 Scan
작업 중에 테이블에서 추가로 발행하는 쓰기 활동을 기록합니다. Scan
작업을 마치면 스트림의 쓰기 연산을 테이블에 적용할 수 있습니다.
참고
ConsistentRead
를 true
로 설정한 상태에서 Scan
작업을 수행하면 ConsistentRead
를 기본값(false
)으로 그대로 두는 경우와 비교할 때 2배 더 많은 읽기 용량 단위를 사용합니다.
병렬 스캔
기본적으로 Scan
작업은 데이터를 순차적으로 처리합니다. Amazon DynamoDB는 애플리케이션에 1MB 단위로 데이터를 반환하고 애플리케이션은 추가 Scan
작업을 수행하여 다음 1MB의 데이터를 가져옵니다.
스캔할 테이블 또는 인덱스가 클수록 Scan
을 완료하는 데 걸리는 시간이 늘어납니다. 또한 순차적 Scan
은 프로비저닝된 읽기 처리 용량을 항상 최대한 사용할 수 있는 것은 아닙니다. DynamoDB가 여러 물리적 파티션 간에 큰 테이블 데이터를 분산해도 Scan
작업은 한 번에 한 파티션만 읽을 수 있습니다. 이러한 이유로 Scan
의 처리량은 단일 파티션의 최대 처리량에 따라 제약을 받습니다.
이 문제를 해결하기 위해 Scan
작업에서는 테이블 또는 보조 인덱스를 여러 세그먼트로 논리적으로 나눠 여러 애플리케이션 작업자가 세그먼트를 병렬로 처리하도록 할 수 있습니다. 각 작업자는 스레드(멀티스레딩을 지원하는 프로그래밍 언어에서) 또는 운영 체제 프로세스일 수 있습니다. 병렬 스캔을 수행하려면 각 작업자가 다음 파라미터를 사용하여 Scan
요청을 발행합니다.
-
Segment
- 특정 작업자가 스캔할 세그먼트입니다. 각 작업자는Segment
에 서로 다른 값을 사용해야 합니다. -
TotalSegments
- 병렬 스캔에 사용되는 총 세그먼트 수입니다. 이 값은 애플리케이션에서 사용할 작업자 수와 같아야 합니다.
다음 다이어그램은 멀티스레드 애플리케이션이 3 병렬 처리 수준을 사용하여 병렬 Scan
을 수행하는 방법에 대해 설명합니다.
이 다이어그램에서 애플리케이션은 세 개의 스레드를 생성하여 각 스레드에 번호를 지정합니다. (세그먼트는 0부터 시작하므로 첫 번째 번호는 항상 0입니다.) 각 스레드는 Scan
요청을 실행하며, Segment
를 해당 지정 번호로 설정하고 TotalSegments
를 3으로 설정합니다. 각 스레드는 해당 지정 세그먼트를 스캔하며 한 번에 1MB의 데이터를 가져와서 애플리케이션의 기본 스레드에 데이터를 반환합니다.
Segment
및 TotalSegments
값을 개별 Scan
요청에 적용하여 언제든지 다른 값을 사용할 수 있습니다. 애플리케이션이 최적의 성능을 발휘하려면 이러한 값과 사용하는 작업자 수에 대한 여러 번의 시도가 필요할 수 있습니다.
참고
작업자 수가 많은 병렬 스캔 작업은 스캔할 테이블 또는 인덱스에 대한 모든 할당된 처리량을 족히 소비할 수 있습니다. 테이블 또는 인덱스가 다른 애플리케이션에서 과도한 읽기 또는 쓰기 작업을 발생시키는 경우 이러한 스캔을 수행하지 않아야 합니다.
요청당 반환되는 데이터 양을 제어하려면 Limit
파라미터를 사용하십시오. 이를 사용하면 다른 모든 작업자가 이용할 비용으로 한 작업자가 할당된 모든 처리량을 소비하게 되는 상황을 방지할 수 있습니다.