DynamoDB 발생한 트러블 이슈 모음

Viva의 놀이터·2021년 7월 27일
0

AWS DynamoDB

목록 보기
5/5
post-thumbnail

발생한 트러블 이슈 모음

insert 처리 속도 문제

delete 다중 삭제 불가 문제

아이템 삭제시 단일 삭제만 가능하여 하루치 데이터를 저장하고 해당 테이블을 S3로 저장한 뒤에 테이블 삭제하는 방법으로 해결

scan, query 조회 결과 크기 제한 문제

DynamoDB에서 Scan, query를 수행할 때 수행 결과가 최대 1MB를 넘지 못한다. 1MB가 넘는 데이터를 전체 조회하기 위해서는 조회 결과에 포함되어 있는 항목인 LastEvaluatedKey의 존재 유무를 판단하여 추가 검색이 필요한지 판단하여 처리

 @Test
    void dynamoDB_queryTest() {

        int want = 0;
        Map<String, AttributeValue> lastKeyEvaluated = null;
        do {
            ScanRequest scanRequest = new ScanRequest()
                    .withTableName("Test")
                    .withExclusiveStartKey(lastKeyEvaluated);

            ScanResult result = amazonDynamoDb.scan(scanRequest);
            want = want + result.getCount();
            lastKeyEvaluated = result.getLastEvaluatedKey();

            System.out.println(result.getItems());

            Map<String, AttributeValue> key = new HashMap<>();

            for (Map<String, AttributeValue> map : result.getItems()) {
                key.put("id", map.get("id"));

                DeleteItemRequest deleteItemRequest = (new DeleteItemRequest())
                        .withTableName("BeaconHistoryData")
                        .withKey(key);

                amazonDynamoDb.deleteItem(deleteItemRequest);
            }

        } while (lastKeyEvaluated != null);

        System.out.println(want);

    }

global index 조회 문제

DynamoDB table 조회시 table의 파티션 키가 아닌 글로벌 인덱스로 조회하고자 할 때 Java SDK 기준

  • 검색하고자 하는 table을 설정하고 해당 Table 클래스에 포함되어 있는 getIndex에 파라미터로 검색하고자 하는 글러벌 인덱스 값을 넣어서 Index 인스턴스 생성

  • 생성된 Index 인스턴스에 QuerySpec을 생성하여 query 매소드를 통해서 원하는 값을 검색합니다. 쿼리 생성 요소

 @Test
    void check_performance(){

        long start = System.currentTimeMillis();

        DynamoDB dynamoDB = new DynamoDB(amazonDynamoDb);
        Table table = dynamoDB.getTable("Test");
        int [] assetId_list = new int[] {1,2,3,4,5,6,7,8,9,10};
        Index index = table.getIndex("byAssetId");
        for(Integer nowAsset : assetId_list) {
            QuerySpec querySpec = new QuerySpec().withKeyConditionExpression("assetId = :v_id and createdAt between :v_start_at and :v_end_at")
                    .withValueMap(new ValueMap().withInt(":v_id", nowAsset).withString(":v_start_at", "원하는 값").withString(":v_end_at", "원하는 값"));

            ItemCollection<QueryOutcome> items = index.query(querySpec);

            Iterator<Item> iterator = items.iterator();
            Item item = null;
            Integer count = 0;

            List<TestDTO> test_perform = new ArrayList<>();
            Long base_placeId = 0L;
            Long base_timestamp = 0L;
            Long current_timestamp = 0L;
            Long durationTime = 0L;
            while (iterator.hasNext()) {
                item = iterator.next();
                count += 1;
                TestDTO test = TestDTO.builder()
                        // 원하는 값
                        .build();
             			// 원한는 동작
                }

            }

            System.out.println("총 개수는" + count);
            System.out.println("리스트의 길이는  " + test_perform.size());

            Iterator<TestDTO> test_list = test_perform.iterator();

            while (test_list.hasNext()) {
                TestDTO temp = test_list.next();
                System.out.println("머문시간은 " + temp.getStayTime().toString());
            }
        }
        long end = System.currentTimeMillis();
        System.out.println("수행시간: " + (end - start) + " ms");


    }

DynamoDB 생성 삭제 자동화 Lambda 파이프라인 오류 문제

문제 발생 시 Cloudwatch의 로그 그룹을 통해서 에러 log 확인 가능cloudWatch log group 바로가기

table 생성 문제

Java SDK 기준 테이블을 생성할 때 모든 항목을 만들 필요가 없다. 테이블의 (파티션 키, 정렬 키), 글로벌 인덱스에 선언된 (파티션 키, 정렬 키), 로컬 인덱스에서 선언된 (파티션 키, 정렬 키) 만 생성해주면 된다.

  table = dynamodb.create_table(
        AttributeDefinitions = [
            {'AttributeName': 'A', 'AttributeType': 'N'}
            , {'AttributeName': 'B', 'AttributeType': 'S'}
            , {'AttributeName': 'C', 'AttributeType': 'S'}
            , {'AttributeName': 'E', 'AttributeType': 'S'}
            , {'AttributeName': 'D', 'AttributeType': 'N'}],
        TableName = "KongPlace_"+str(index)+"_"+str(next_day)[:10], 
        KeySchema = [{'AttributeName': 'E', 'KeyType': 'HASH'}],
        GlobalSecondaryIndexes = [
            {'IndexName': 'byA', 'KeySchema': [{'AttributeName': 'A', 'KeyType': 'HASH'}, {'AttributeName': 'C', 'KeyType': 'RANGE'}], 'Projection': {'ProjectionType': 'ALL'}}
        , {'IndexName': 'byB', 'KeySchema': [{'AttributeName': 'B', 'KeyType': 'HASH'}], 'Projection': {'ProjectionType': 'ALL'}}
        , {'IndexName': 'byD', 'KeySchema': [{'AttributeName': 'D', 'KeyType': 'HASH'}], 'Projection': {'ProjectionType': 'ALL'}}],
        BillingMode = 'PAY_PER_REQUEST')

참고자료

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/Scan.html

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/developerguide/GSIJavaDocumentAPI.html

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/APIReference/API_CreateTable.html

https://docs.aws.amazon.com/ko_kr/amazondynamodb/latest/APIReference/API_Query.html#API_Query_RequestSyntax

profile
역사를 잊은 기술에겐 미래가 없다

0개의 댓글