Amazon DynamoDB
개발자 안내서 (API 버전 2012-08-10)

DynamoDB에서 스캔 작업

Amazon DynamoDB의 Scan 작업은 테이블 또는 보조 인덱스의 모든 항목을 읽어옵니다. 기본적으로 Scan 작업은 테이블이나 인덱스에 속한 항목의 데이터 속성을 모두 반환합니다. 하지만 Scan 작업에서 ProjectionExpression 파라미터를 사용하면 모두가 아닌 일부 속성만 가져올 수 있습니다.

Scan은 항상 결과 집합을 반환합니다. 일치하는 항목이 없다면 결과 집합은 비어 있습니다.

단일 Scan 요청은 최대 1 MB개의 데이터를 가져올 수 있습니다. 선택에 따라 DynamoDB가 이 데이터에 필터 표현식을 적용하여 사용자에게 반환되기 전에 결과의 범위를 좁힐 수 있습니다.

스캔에 대한 필터 표현식

Scan 결과를 한층 더 좁혀야 하는 경우 선택적으로 필터 표현식을 제공할 수 있습니다. 필터 표현식Scan 결과 내에서 어떤 항목을 반환할지를 결정합니다. 다른 모든 결과는 폐기됩니다.

필터 표현식은 Scan이 완료된 후 결과가 반환되기 전에 적용됩니다. 따라서 필터 표현식이 있는지 여부와 상관없이 Scan은 동일한 양의 읽기 용량을 사용합니다.

Scan 작업은 최대 1 MB개의 데이터를 가져올 수 있습니다. 이 제한은 필터 표현식이 평가되기 전에 적용됩니다.

Scan을 사용하면 필터 표현식의 속성(파티션 키 및 정렬 키 속성 포함)을 지정할 수 있습니다.

필터 표현식의 구분은 조건 표현식의 구문과 같습니다. 필터 표현식은 동일한 비교기, 함수 및 논리적 연산자를 조건 표현식으로 사용할 수 있습니다. 자세한 내용은 조건식 단원을 참조하십시오.

다음 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 결과는 크기가 1 MB 이하인 데이터 "페이지"로 분리됩니다. 응용 프로그램은 결과의 첫 번째 페이지를 처리한 다음, 두 번째 페이지를 처리하고 이런 식으로 계속할 수 있습니다.

단일 Scan는 1 MB 크기 한도 내에 맞는 결과 집합만 반환합니다. 추가 결과가 있는지 확인하고 이러한 결과를 한번에 한 페이지에 가져오려면 애플리케이션에서 다음을 수행해야 합니다.

  1. 하위 수준 Scan 결과를 확인합니다.

    • 결과에 LastEvaluatedKey 요소가 포함되는 경우 2단계로 계속합니다.

    • 결과에 LastEvaluatedKey없으면 검색할 항목이 없는 것입니다.

  2. 이전과 동일한 파라미터를 이용해 새로운 Scan 요청을 구성합니다. 그러나 이번에는 1단계에서 LastEvaluatedKey 값을 가져와서 새로운 Scan 요청의 ExclusiveStartKey 파라미터로 사용합니다.

  3. 새로운 Scan 요청을 실행합니다.

  4. 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 파라미터는 요청 및 응답에 대한 하위 수준 정보를 출력합니다.

예제를 실행하면 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 결과 페이지 매김에 대해 다양한 추상을 제공합니다. 예를 들어, Java용 SDK 문서 인터페이스는 java.util.Iterator 지원을 제공하므로 한 번에 하나씩 결과를 볼 수 있습니다.

다양한 프로그래밍 언어의 코드 예제를 보려면 Amazon DynamoDB 시작 안내서 및 해당 언어의 AWS SDK 설명서를 참조하십시오.

결과 내 항목 수 계산

Scan 응답에는 기준과 일치하는 항목 외에도 다음 요소가 포함됩니다.

  • ScannedCountScanFilter를 적용하기 전에 평가되는 항목 수입니다. ScannedCount 값이 높지만 Count 결과가 거의 없거나 전혀 없는 경우 Scan 작업이 비효율적이라는 것을 나타냅니다. 요청에 필터를 사용하지 않은 경우 ScannedCountCount와 동일합니다.

  • Count — 필터 표현식(있는 경우)을 적용한 에 남아 있는 항목 수입니다.

참고

필터 표현식을 사용하지 않으면 ScannedCountCount는 동일한 값을 갖습니다.

Scan 결과 집합의 크기가 1 MB보다 크면 ScannedCountCount는 총 항목 수의 일부만 표시합니다. 모든 결과를 검색하려면 여러 Scan 작업을 수행해야 합니다(결과 페이지 매김 참조).

Scan 응답에는 해당하는 특정 Scan 요청에 따라 처리된 항목의 ScannedCountCount가 포함됩니다. 모든 Scan 요청의 총계를 가져오려면 ScannedCountCount의 누계를 계산할 수 있습니다.

스캔에서 사용된 용량 단위

테이블이나 보조 인덱스를 Scan할 수 있습니다. Scan 작업은 다음과 같이 읽기 용량 유닛을 사용합니다.

다음을 Scan하는 경우... DynamoDB는 다음에서 읽기 용량 단위를 사용합니다...
테이블 테이블의 할당된 읽기 용량.
Global secondary index 인덱스의 할당된 읽기 용량.
로컬 보조 인덱스 기본 테이블의 프로비저닝된 읽기 용량.

기본적으로, Scan 작업은 얼마나 많은 읽기 용량을 사용하는지에 대한 데이터를 반환하지 않습니다. 하지만 Scan 요청에서 ReturnConsumedCapacity 파라미터를 지정하여 이 정보를 얻을 수 있습니다. 다음은 ReturnConsumedCapacity에 대한 유효한 설정입니다.

  • NONE — 사용된 용량 데이터가 반환되지 않습니다. (이 값이 기본값입니다.)

  • TOTAL — 사용된 읽기 용량 유닛의 집계 수가 응답에 포함됩니다.

  • INDEXES — 액세스한 각 테이블 및 인덱스에 사용된 용량과 함께 사용된 읽기 용량 유닛의 집계 수가 응답에 표시됩니다.

DynamoDB는 애플리케이션에 반환되는 데이터 양이 아닌 항목 크기를 기준으로 사용된 읽기 용량 단위의 수를 계산합니다. 이러한 이유로, 모든 속성을 요청하든(기본 동작) 또는 일부 속성만 요청하든(프로젝션 표현식 사용) 상관없이 사용된 용량 단위의 수는 동일합니다. 이 수는 필터 표현식을 사용하는지 여부와도 상관없이 동일합니다.

스캔에 대한 읽기 일관성

기본적으로 Scan 작업은 최종적 일관된 읽기를 수행합니다. 따라서 최근 완료된 PutItem 또는 UpdateItem 작업으로 인해 Scan 결과에 변경 사항이 반영되지 않을 수 있습니다. 자세한 내용은 읽기 일관성 단원을 참조하십시오.

Scan이 시작되는 시점을 기준으로 강력한 일관된 읽기가 필요한 경우 Scan 요청에서 ConsistentRead 파라미터를 true로 설정합니다. 그러면 Scan 작업 시작 전에 마친 쓰기 작업까지 모두 Scan 응답에 포함됩니다.

DynamoDB 스트림가 함께 작동하는 테이블 백업이나 복제 시나리오에서는 ConsistentReadtrue로 설정하는 것이 유용할 수 있습니다. 처음에는 ConsistentRead을 true로 설정한 상태에서 Scan를 사용하여 테이블 데이터에 대한 일관된 복사본을 얻습니다. 그러면 DynamoDB 스트림가 Scan 작업 중에 테이블에서 추가로 발행하는 쓰기 연산을 기록합니다. Scan 작업을 마치면 스트림의 쓰기 연산을 테이블에 적용할 수 있습니다.

참고

ConsistentReadtrue로 설정한 상태에서 Scan 작업을 수행하면 ConsistentRead를 기본값(false)으로 그대로 두는 경우와 비교할 때 2배 더 많은 읽기 용량 단위를 사용합니다.

병렬 스캔

기본적으로 Scan 작업은 데이터를 순차적으로 처리합니다. Amazon DynamoDB는 애플리케이션에 1 MB씩 데이터를 반환하고 애플리케이션은 추가 Scan 작업을 수행하여 다음 1 MB의 데이터를 가져옵니다.

스캔할 테이블 또는 인덱스가 클수록 Scan을 완료하는 데 걸리는 시간이 늘어납니다. 또한 순차적 Scan은 프로비저닝된 읽기 처리량 용량을 항상 최대한 사용할 수 있는 것은 아닙니다. DynamoDB가 여러 물리적 파티션 간에 라지 테이블 데이터를 분산해도 Scan 작업은 한 번에 한 파티션만 읽을 수 있습니다. 이러한 이유로 Scan의 처리량은 단일 파티션의 최대 처리량에 따라 제약을 받습니다.

이 문제를 해결하기 위해 Scan 작업은 여러 애플리케이션 작업자가 세그먼트를 병렬로 처리하는 경우 테이블 또는 보조 인덱스를 여러 세그먼트로 논리적으로 나눌 수 있습니다. 각 작업자는 스레드(멀티스레딩을 지원하는 프로그래밍 언어에서) 또는 운영 체제 프로세스일 수 있습니다. 병렬 스캔을 수행하려면 각 작업자가 다음 파라미터를 사용하여 Scan 요청을 발행합니다.

  • Segment — 특정 작업자가 스캔할 세그먼트입니다. 각 작업자는 Segment에 서로 다른 값을 사용해야 합니다.

  • TotalSegments — 병렬 스캔에 사용되는 총 세그먼트 수입니다. 이 값은 애플리케이션에서 사용할 작업자 수와 같아야 합니다.

다음 다이어그램은 멀티스레드 애플리케이션이 3 병렬 처리 수준을 사용하여 병렬 Scan을 수행하는 방법에 대해 설명합니다.

이 다이어그램에서 애플리케이션은 세 개의 스레드를 생성하여 각 스레드에 번호를 지정합니다. (세그먼트는 0부터 시작하므로 첫 번째 번호는 항상 0입니다.) 각 스레드는 Scan 요청을 실행하며, Segment를 해당 지정 번호로 설정하고 TotalSegments를 3으로 설정합니다. 각 스레드는 해당 지정 세그먼트를 스캔하며 한 번에 1 MB의 데이터를 가져와서 애플리케이션의 기본 스레드에 데이터를 반환합니다.

SegmentTotalSegments 값을 개별 Scan 요청에 적용하여 언제든지 다른 값을 사용할 수 있습니다. 애플리케이션이 최적의 성능을 발휘하려면 이러한 값과 사용하는 작업자 수에 대한 여러 번의 시도가 필요할 수 있습니다.

참고

작업자 수가 많은 병렬 스캔 작업은 스캔할 테이블 또는 인덱스에 대한 모든 할당된 처리량을 족히 소비할 수 있습니다. 테이블 또는 인덱스가 다른 애플리케이션에서 과도한 읽기 또는 쓰기 작업을 발생시키는 경우 이러한 스캔을 수행하지 않아야 합니다.

요청당 반환되는 데이터 양을 제어하려면 Limit 파라미터를 사용하십시오. 이를 사용하면 다른 모든 작업자가 이용할 비용으로 한 작업자가 할당된 모든 처리량을 소비하게 되는 상황을 방지할 수 있습니다.