[database] DynamoDB에서 많은 항목을 삭제하는 데 권장되는 방법은 무엇입니까?
DynamoDB에서 간단한 로깅 서비스를 작성하고 있습니다.
user_id 해시와 타임 스탬프 (Unix epoch int) 범위로 키가 지정된 로그 테이블이 있습니다.
서비스 사용자가 계정을 해지하면 범위 값에 관계없이 테이블의 모든 항목을 삭제해야합니다.
이러한 종류의 작업을 수행하는 데 권장되는 방법은 무엇입니까 (삭제할 항목이 수백만 개가 될 수 있음을 염두에 두십시오)?
내가 볼 수있는 한 내 옵션은 다음과 같습니다.
A : 항목이 남아 있지 않을 때까지 반환 된 각 항목에 대해 delete를 호출하는 Scan 작업을 수행합니다.
B : BatchGet 작업을 수행하고 아무것도 남지 않을 때까지 각 항목에 대해 다시 삭제를 호출합니다.
둘 다 오랜 시간이 걸리기 때문에 나에게 끔찍하게 보입니다.
내가 이상적으로하고 싶은 것은 LogTable.DeleteItem (user_id) 호출-범위를 제공하지 않고 모든 것을 삭제하도록하는 것입니다.
답변
내가 이상적으로하고 싶은 것은 LogTable.DeleteItem (user_id) 호출-범위를 제공하지 않고 모든 것을 삭제하도록하는 것입니다.
참으로 이해할 수있는 요청입니다. 이와 같은 고급 작업이 AWS 팀에 의해 시간이 지남에 따라 추가 될 수 있다고 상상할 수 있습니다 (제한된 기능 세트로 먼저 시작하고 고객 피드백을 기반으로 확장을 평가 한 기록이 있음). 적어도 전체 스캔 :
-
Scan 대신 Query를 사용 하여 모든 항목을 검색합니다. HashKeyValue 및 RangeKeyCondition 은이 API에서 별도의 매개 변수이고 전자 는 복합의 해시 구성 요소의 Attribute 값 만을 대상으로 하기 때문에 사용중인 결합 된 해시 / 범위 기본 키에 관계없이 작동 합니다. 기본 키. .
user_id
- 여기서 평소처럼 쿼리 API 페이징을 처리해야합니다. ExclusiveStartKey 매개 변수를 참조하십시오 .
이전 쿼리를 계속할 항목의 기본 키입니다. 이전 쿼리는 쿼리를 완료하기 전에 쿼리 작업이 중단 된 경우이 값을 LastEvaluatedKey로 제공 할 수 있습니다. 결과 세트 크기 또는 한계 매개 변수 때문입니다. LastEvaluatedKey는 새 쿼리 요청에서 다시 전달되어 해당 지점에서 작업을 계속할 수 있습니다.
- 여기서 평소처럼 쿼리 API 페이징을 처리해야합니다. ExclusiveStartKey 매개 변수를 참조하십시오 .
-
반환 된 모든 항목을 반복하고 평소와 같이 DeleteItem 을 용이하게 합니다.
- 업데이트 : 대부분의 경우 BatchWriteItem 은 이와 같은 사용 사례에 더 적합합니다 (자세한 내용은 아래 참조).
최신 정보
ivant 에서 강조한대로 BatchWriteItem 작업을 사용하면 단일 API 호출로 여러 테이블에 걸쳐 여러 항목 을 추가 하거나 삭제할 수 있습니다 [emphasis mine] .
하나의 항목을 업로드하려면 PutItem API를 사용하고 하나의 항목을 삭제하려면 DeleteItem API를 사용할 수 있습니다. 그러나 Amazon Elastic MapReduce (EMR)에서 대량의 데이터를 업로드하거나 다른 데이터베이스에서 Amazon DynamoDB로 데이터를 마이그레이션하는 등 대량의 데이터를 업로드 또는 삭제하려는 경우이 API는 효율적인 대안을 제공합니다.
여기에는 여전히 몇 가지 관련 제한 사항이 있습니다.
-
단일 요청의 최대 작업 — 총 25 개의 올리기 또는 삭제 작업을 지정할 수 있습니다. 그러나 총 요청 크기는 1MB (HTTP 페이로드)를 초과 할 수 없습니다.
-
원자 적 작업 아님 — BatchWriteItem에 지정된 개별 작업은 원자 적입니다. 그러나 BatchWriteItem은 전체적으로 원자 적 작업이 아니라 “최선의”작업입니다. 즉, BatchWriteItem 요청에서 일부 작업은 성공하고 다른 작업은 실패 할 수 있습니다. […]
그럼에도 불구하고 이것은 당면한 것과 같은 사용 사례에 잠재적으로 상당한 이득을 제공합니다.
답변
DynamoDB 설명서에 따르면 전체 테이블을 삭제할 수 있습니다.
아래를 참조하십시오.
“전체 테이블을 삭제하는 것은 항목을 하나씩 제거하는 것보다 훨씬 더 효율적입니다. 이는 기본적으로 넣기 작업만큼 많은 삭제 작업을 수행 할 때 쓰기 처리량을 두 배로 늘립니다.”
데이터의 하위 집합 만 삭제하려면 월, 연도 또는 이와 유사한 항목에 대해 별도의 테이블을 만들 수 있습니다. 이렇게하면 “지난 달”을 제거하고 나머지 데이터는 그대로 유지할 수 있습니다.
다음은 AWS SDK를 사용하여 Java에서 테이블을 삭제하는 방법입니다.
DeleteTableRequest deleteTableRequest = new DeleteTableRequest()
.withTableName(tableName);
DeleteTableResult result = client.deleteTable(deleteTableRequest);
답변
예를 들어 한 달이 지난 후 항목을 삭제하려면 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
답변
이 질문에 대한 답은 항목 수와 크기 및 예산에 따라 다릅니다. 이에 따라 다음과 같은 3 가지 경우가 있습니다.
1- 표의 항목 수와 항목 크기는 그리 많지 않습니다. 그런 다음 Steffen Opel이 말했듯이 Scan 대신 Query를 사용하여 user_id에 대한 모든 항목을 검색 한 다음 반환 된 모든 항목을 반복하고DeleteItem
하거나BatchWriteItem
. 그러나 여기에서 많은 처리량을 소모 할 수 있습니다. 예를 들어 DynamoDB 테이블에서 1000 개의 항목을 삭제해야하는 상황을 생각해보십시오. 각 항목의 크기가 1KB라고 가정하면 약 1MB의 데이터가 생성됩니다. 이 대량 삭제 작업에는 쿼리 및 삭제를 위해 총 2000 개의 쓰기 용량 단위가 필요합니다. 이 데이터로드를 10 초 이내에 수행하려면 (일부 애플리케이션에서는 그렇게 빠르지 않은 것으로 간주 됨) 테이블의 프로비저닝 된 쓰기 처리량을 200 쓰기 용량 단위로 설정해야합니다. 보시다시피 더 적은 수의 항목이나 작은 크기의 항목에 대해 이러한 방식으로 사용할 수 있습니다.
2- 우리는 테이블에 많은 항목 또는 매우 큰 항목이 있으며 시간에 따라 다른 테이블에 저장할 수 있습니다. 그런 다음 조나단이 말했듯이 테이블을 삭제할 수 있습니다. 이것은 훨씬 낫지 만 귀하의 경우와 일치하지 않는다고 생각합니다. 로그 생성 시간에 관계없이 모든 사용자 데이터를 삭제하고 싶으므로이 경우 특정 테이블을 삭제할 수 없습니다. 각 사용자에 대해 별도의 테이블을 갖고 싶다면 사용자 수가 많으면 너무 비싸고 귀하의 경우에는 실용적이지 않습니다.
3- 데이터가 많고 핫 데이터와 콜드 데이터를 서로 다른 테이블로 나눌 수없고 대규모 삭제를 자주 수행해야하는 경우 안타깝게도 DynamoDB는 좋은 옵션이 아닙니다. 더 비싸거나 매우 느려질 수 있습니다 (예산에 따라 다름). 이 경우 데이터에 대한 다른 데이터베이스를 찾는 것이 좋습니다.
답변
테이블에서 모든 행을 삭제하는 방법 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를 사용하여 테이블을 생성하는 경우 문제가 발생할 수 있습니다.
답변
다이나모 테이블을 자르는 옵션이 없습니다. 테이블을 삭제하고 다시 만들어야합니다. DynamoDB 요금은 ReadCapacityUnits 및 WriteCapacityUnits를 기준으로합니다. BatchWriteItem 함수를 사용하여 모든 항목을 삭제하면 WriteCapacityUnits를 사용하므로 특정 레코드를 삭제하거나 테이블을 삭제하고 다시 시작하는 것이 좋습니다.