DynamoDB에서 많은 항목을 삭제하는 데 권장되는 방법은 무엇입니까?


111

DynamoDB에서 간단한 로깅 서비스를 작성하고 있습니다.

user_id 해시와 타임 스탬프 (Unix epoch int) 범위로 키가 지정된 로그 테이블이 있습니다.

서비스 사용자가 계정을 해지하면 범위 값에 관계없이 테이블의 모든 항목을 삭제해야합니다.

이러한 종류의 작업을 수행하는 데 권장되는 방법은 무엇입니까 (삭제할 항목이 수백만 개가 될 수 있음을 염두에 두십시오)?

내가 볼 수있는 한 내 옵션은 다음과 같습니다.

A : 항목이 남아 있지 않을 때까지 반환 된 각 항목에 대해 delete를 호출하는 Scan 작업을 수행합니다.

B : BatchGet 작업을 수행하고 아무것도 남지 않을 때까지 각 항목에 대해 다시 삭제를 호출합니다.

둘 다 오랜 시간이 걸리기 때문에 나에게 끔찍하게 보입니다.

내가 이상적으로하고 싶은 것은 LogTable.DeleteItem (user_id) 호출-범위를 제공하지 않고 모든 것을 삭제하도록하는 것입니다.

답변:


52

내가 이상적으로하고 싶은 것은 LogTable.DeleteItem (user_id) 호출-범위를 제공하지 않고 모든 것을 삭제하도록하는 것입니다.

참으로 이해할 수있는 요청입니다. 이와 같은 고급 작업이 AWS 팀에 의해 시간이 지남에 따라 추가 될 수 있다고 상상할 수 있습니다 (제한된 기능 세트로 먼저 시작하고 고객 피드백을 기반으로 확장을 평가 한 기록이 있음). 적어도 전체 스캔 :

  1. Scan 대신 Query를 사용 하여 모든 항목을 검색합니다. HashKeyValueRangeKeyCondition 은이 API에서 별도의 매개 변수이고 전자 는 복합의 해시 구성 요소의 Attribute 값 만을 대상으로 하기 때문에 사용중인 결합 된 해시 / 범위 기본 키에 관계없이 작동 합니다. 기본 키. .user_id

    • 여기서 평소처럼 쿼리 API 페이징을 처리해야합니다. ExclusiveStartKey 매개 변수를 참조하십시오 .

      이전 쿼리를 계속할 항목의 기본 키입니다. 이전 쿼리는 쿼리를 완료하기 전에 쿼리 작업이 중단 된 경우이 값을 LastEvaluatedKey로 제공 할 수 있습니다. 결과 세트 크기 또는 한계 매개 변수 때문입니다. LastEvaluatedKey는 새 쿼리 요청에서 다시 전달되어 해당 지점에서 작업을 계속할 수 있습니다.

  2. 반환 된 모든 항목을 반복하고 평소와 같이 DeleteItem 을 용이하게 합니다.

    • 업데이트 : 대부분의 경우 BatchWriteItem 은 이와 같은 사용 사례에 더 적합합니다 (자세한 내용은 아래 참조).

최신 정보

ivant 에서 강조한대로 BatchWriteItem 작업을 사용하면 단일 API 호출로 여러 테이블에 걸쳐 여러 항목 을 추가 하거나 삭제할 수 있습니다 [emphasis mine] .

하나의 항목을 업로드하려면 PutItem API를 사용하고 하나의 항목을 삭제하려면 DeleteItem API를 사용할 수 있습니다. 그러나 Amazon Elastic MapReduce (EMR)에서 대량의 데이터를 업로드하거나 다른 데이터베이스에서 Amazon DynamoDB로 데이터를 마이그레이션하는 등 대량의 데이터를 업로드 또는 삭제하려는 경우이 API는 효율적인 대안을 제공합니다.

여기에는 여전히 몇 가지 관련 제한 사항이 있습니다.

  • 단일 요청의 최대 작업 — 총 25 개의 올리기 또는 삭제 작업을 지정할 수 있습니다. 그러나 총 요청 크기는 1MB (HTTP 페이로드)를 초과 할 수 없습니다.

  • 원자 적 작업 아님 — BatchWriteItem에 지정된 개별 작업은 원자 적입니다. 그러나 BatchWriteItem은 전체적으로 원자 적 작업이 아니라 "최선의"작업입니다. 즉, BatchWriteItem 요청에서 일부 작업은 성공하고 다른 작업은 실패 할 수 있습니다. [...]

그럼에도 불구하고 이것은 당면한 것과 같은 사용 사례에 잠재적으로 상당한 이득을 제공합니다.


4
두 번째 단계에 일괄 삭제를 사용하는 것이 합리적이라고 생각합니다 ( 일괄 쓰기 작업 으로 "마스킹"됨 )
ivant

1
@ivant-힌트를 보내 주셔서 감사합니다. BatchWriteItem의 "마스킹 된"삭제 기능은 당시 저를 실제로 탈출했습니다. 그에 따라 답변을 업데이트했습니다.
Steffen Opel 2012

로 삭제하는 BatchWriteItem항목을 통해 지정해야TableWriteItems


3
나는 이것이 오래 되었다는 것을 알고 있고 OP는 특정 언어 SDK를 언급하지 않았지만 Python에는 "자동으로 버퍼링을 처리하고 일괄 적으로 항목을 전송 batch_writer()하는 boto3.resource.TableAPI의 일부로 높은 수준이 있습니다. 또한 배치 작성자는 또한 처리되지 않은 항목을 자동으로 처리하고 필요에 따라 다시 보냅니다. "즉, 성가신 부분을 관리하는 BatchWriteItem을 둘러싼 래퍼입니다. boto3.amazonaws.com/v1/documentation/api/latest/reference/…
Davos

46

DynamoDB 설명서에 따르면 전체 테이블을 삭제할 수 있습니다.

아래를 참조하십시오.

"전체 테이블을 삭제하는 것은 항목을 하나씩 제거하는 것보다 훨씬 더 효율적입니다. 이는 기본적으로 넣기 작업만큼 많은 삭제 작업을 수행 할 때 쓰기 처리량을 두 배로 늘립니다."

데이터의 하위 집합 만 삭제하려면 월, 연도 또는 이와 유사한 항목에 대해 별도의 테이블을 만들 수 있습니다. 이렇게하면 "지난 달"을 제거하고 나머지 데이터는 그대로 유지할 수 있습니다.

다음은 AWS SDK를 사용하여 Java에서 테이블을 삭제하는 방법입니다.

DeleteTableRequest deleteTableRequest = new DeleteTableRequest()
  .withTableName(tableName);
DeleteTableResult result = client.deleteTable(deleteTableRequest);

8
이 답변도 마음에 들지만주의해야합니다. 시스템에 많은 테이블이 생성 될 수 있으며 테이블 프로비저닝 당 비용을 지불합니다. 따라서이 테이블이 삭제되지 않는 동안 월말 (테이블이 월 단위 인 경우) 이후에 프로비저닝을 줄여야합니다.
Sergio MC Figueiredo

2
이 답변에 동의하면 테이블에서 모든 레코드를 삭제해야하는 경우 적용되지만 여기서 질문자는 전체 테이블이 아닌 사용자 기반 항목을 삭제하려고합니다.
Ihtsham Minhas 2015

1
DynamoDB 요금을 고려할 때 각 사용자에 대해 별도의 테이블 테이블을 갖는 것은 비용이 많이 듭니다. 한 달에 하나의 테이블은 실제로 상황을 악화시킵니다. 이것은 분명히 다른 매우 구체적인 문제에 대한 답입니다.
André Werlang

11
CloudFormation과 같은 자동 프로비저닝을 사용하여 테이블을 스택의 일부로 관리하는 경우 테이블 삭제는 매력적인 옵션이 아닐 수도 있습니다. CloudFormation에서 손으로 삭제 한 테이블을 다시 만드는 간단한 방법을 모르겠습니다.
brabster

2
이 접근 방식은 테이블을 삭제하고 다시 만드는 데 (필요한 경우) 상당한 시간이 걸리므로 전체 시간 동안 사용할 수 없게됩니다. 이 질문은 사용자 데이터 제거를 명확하게 설명합니다. 이는 사용자 별 테이블로 분리되는 비실용적입니다.
André Werlang 2017 년

13

예를 들어 한 달이 지난 후 항목을 삭제하려면 TTL 옵션을 사용하십시오. 그것은 것입니다 하지쓰기 단위 계산 .

귀하의 경우에는 로그가 만료되면 ttl을 추가하고 사용자가 삭제 된 후에는 그대로 둡니다. TTL은 로그가 결국 제거되도록합니다.

테이블에서 TTL이 활성화되면 백그라운드 작업이 항목의 TTL 속성을 확인하여 만료되었는지 확인합니다.

DynamoDB는 일반적으로 만료 48 시간 이내에 만료 된 항목을 삭제합니다. 만료 후 항목이 실제로 삭제되는 정확한 기간은 작업 부하의 특성과 테이블 크기에 따라 다릅니다. 만료되고 삭제되지 않은 항목은 읽기, 쿼리 및 스캔에 계속 표시됩니다. 이러한 항목은 계속 업데이트 할 수 있으며 만료 속성을 변경하거나 제거하기위한 성공적인 업데이트가 적용됩니다.

https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/TTL.html https://docs.aws.amazon.com/amazondynamodb/latest/developerguide/howitworks-ttl.html


TTL 추가는 "업데이트"(쓰기 작업)입니다. "삭제"대신 "업데이트"를 수행하면 어떤 이득이 있는지 잘 모르겠습니다.
Tomer 19

해당 데이터를 원래 쓰기로 삽입하고 다른 업데이트 작업으로 업데이트 할 수 있습니다. 물론 데이터가 많고 삭제하려는 경우에는 선택할 수 없습니다. 그러나 이것은 삽입하거나 업데이트하는 데이터에 대해 ttl을 가질 수있는 경우에 유효한 옵션입니다.
Lukas Liesis

1
이미 TTL이 구성되어 있고 정리가 최대 48 시간을 기다릴 수 있다면 이것이 확실히 최적의 옵션입니다. 확실하지 않다면 사과드립니다.
Tomer 2019

4

이 질문에 대한 답은 항목 수와 크기 및 예산에 따라 다릅니다. 이에 따라 다음과 같은 3 가지 경우가 있습니다.

1- 표의 항목 수와 항목 크기는 그리 많지 않습니다. 그런 다음 Steffen Opel이 말했듯이 Scan 대신 Query를 사용하여 user_id에 대한 모든 항목을 검색 한 다음 반환 된 모든 항목을 반복하고DeleteItem 하거나BatchWriteItem. 그러나 여기에서 많은 처리량을 소모 할 수 있습니다. 예를 들어 DynamoDB 테이블에서 1000 개의 항목을 삭제해야하는 상황을 생각해보십시오. 각 항목의 크기가 1KB라고 가정하면 약 1MB의 데이터가 생성됩니다. 이 대량 삭제 작업에는 쿼리 및 삭제를 위해 총 2000 개의 쓰기 용량 단위가 필요합니다. 이 데이터로드를 10 초 이내에 수행하려면 (일부 애플리케이션에서는 그렇게 빠르지 않은 것으로 간주 됨) 테이블의 프로비저닝 된 쓰기 처리량을 200 쓰기 용량 단위로 설정해야합니다. 보시다시피 더 적은 수의 항목이나 작은 크기의 항목에 대해 이러한 방식으로 사용할 수 있습니다.

2- 우리는 테이블에 많은 항목 또는 매우 큰 항목이 있으며 시간에 따라 다른 테이블에 저장할 수 있습니다. 그런 다음 조나단이 말했듯이 테이블을 삭제할 수 있습니다. 이것은 훨씬 낫지 만 귀하의 경우와 일치하지 않는다고 생각합니다. 로그 생성 시간에 관계없이 모든 사용자 데이터를 삭제하고 싶으므로이 경우 특정 테이블을 삭제할 수 없습니다. 각 사용자에 대해 별도의 테이블을 갖고 싶다면 사용자 수가 많으면 너무 비싸고 귀하의 경우에는 실용적이지 않습니다.

3- 데이터가 많고 핫 데이터와 콜드 데이터를 서로 다른 테이블로 나눌 수없고 대규모 삭제를 자주 수행해야하는 경우 안타깝게도 DynamoDB는 좋은 옵션이 아닙니다. 더 비싸거나 매우 느려질 수 있습니다 (예산에 따라 다름). 이 경우 데이터에 대한 다른 데이터베이스를 찾는 것이 좋습니다.


0

테이블에서 모든 행을 삭제하는 방법 i DynamoDb는 DynamoDbs ScanAsync를 사용하여 테이블에서 모든 행을 가져온 다음 결과 목록을 DynamoDbs AddDeleteItems에 공급하는 것입니다. 아래 코드는 C #에서 잘 작동합니다.

        public async Task DeleteAllReadModelEntitiesInTable()
    {
        List<ReadModelEntity> readModels;

        var conditions = new List<ScanCondition>();
        readModels = await _context.ScanAsync<ReadModelEntity>(conditions).GetRemainingAsync();

        var batchWork = _context.CreateBatchWrite<ReadModelEntity>();
        batchWork.AddDeleteItems(readModels);
        await batchWork.ExecuteAsync();
    }

참고 : 테이블을 삭제 한 다음 웹 콘솔에서 다시 생성하면 YAML / CloudFront를 사용하여 테이블을 생성하는 경우 문제가 발생할 수 있습니다.


0

다이나모 테이블을 자르는 옵션이 없습니다. 테이블을 삭제하고 다시 만들어야합니다. DynamoDB 요금은 ReadCapacityUnits 및 WriteCapacityUnits를 기준으로합니다. BatchWriteItem 함수를 사용하여 모든 항목을 삭제하면 WriteCapacityUnits를 사용하므로 특정 레코드를 삭제하거나 테이블을 삭제하고 다시 시작하는 것이 좋습니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.