AWS/AWS Certified Developer Associate

[Udemy][day-53] Section22 : AWS 서버리스 : DynamoDB - 3

청룡동사는연우 2023. 2. 13. 00:22

#AWS Certified Developer Associate

 

 

 

328. DynamoDB CLI

--projection-expression (프로젝션 표현식) :

한 개 이상의 속성을 지정해서 가져올 수 있음

전체적인 열 및 속성을 받는 것이 아니라 일부 집합만 받아서 데이터를 줄이거나 원하는 데이터만 얻을 수 있음

 

--filter-expression (필터 표현식) : 

반환 되는 아이템을 필터링 하는 옵션

 

General AWS CLI Pagination option (페이지 매김) :

--page-size : 데이터 세트를 모두 가져오면서도 각 서브 API 가 aws 에 보내는 호출은 작아짐

ex ) 아이템 10,000개의 테이블에서 api 호출이 한번일 때 한번에 10,000개의 아이템을 검색하면 시간 초과가 발생함

하지만 --page-size 를 100으로 지정하면 크기가 100인 api 호출 100회가 실행되며 모든 api 호출을 성공시키도록 작동함

--max-items : CLI 호출에 대한 결과에서 제한된 숫자의 아이템을 보여줌

--starting-token : 다음 항목 세트 검색을 위해 마지막으로 설정할 NextToken 을 설정함

 

실습

이전에 만들었던 UserPosts 테이블과 같은 리전의 Cloudshell 을 열고

cli-examples.sh 파일을 사용할 예정

 

#!/bin/bash

# Demo Projection Expression
aws dynamodb scan --table-name UserPosts --projection-expression "user_id, content"

# Demo Filter Expression
aws dynamodb scan --table-name UserPosts --filter-expression "user_id = :u" --expression-attribute-values '{ ":u": {"S":"john123"}}'

# Page Size demo: will do 1 API call if you have 3 Items
aws dynamodb scan --table-name UserPosts 

# Will do 3 API calls if you have 3 Items
aws dynamodb scan --table-name UserPosts --page-size 1

# Max Item demo:
aws dynamodb scan --table-name UserPosts --max-items 1

# Fetch the next item
aws dynamodb scan --table-name UserPosts --max-items 1 --starting-token eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDF9

# Fetch the next item
aws dynamodb scan --table-name UserPosts --max-items 1 --starting-token eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDJ9

 

스캔 + 프로젝션 표현식 1

[cloudshell-user@ip-10-2-27-234 ~]$ aws dynamodb scan --table-name UserPosts --projection-expression "user_id, content"
{
    "Items": [
        {
            "content": {
                "S": "after enable dynamodb stream"
            },
            "user_id": {
                "S": "123"
            }
        },
        {
            "content": {
                "S": "Hello world, this is my first blog!"
            },
            "user_id": {
                "S": "yeonwoo123"
            }
        },
        {
            "content": {
                "S": "second post"
            },
            "user_id": {
                "S": "yeonwoo123"
            }
        },
        {
            "content": {
                "S": "Alice blog"
            },
            "user_id": {
                "S": "alice456"
            }
        }
    ],
    "Count": 4,
    "ScannedCount": 4,
    "ConsumedCapacity": null
}

테이블에는 user_id, game_ts, content 3개 속성이 있는데 이중 2개만 골라서 반환하도록 했다

 

스캔 + 필터 표현식 1

[cloudshell-user@ip-10-2-27-234 ~]$ aws dynamodb scan --table-name UserPosts --filter-expression "user_id = :u" --expression-attribute-values '{ ":u": {"S":"yeonwoo123"}}'                                       
{
    "Items": [
        {
            "content": {
                "S": "Hello world, this is my first blog!"
            },
            "user_id": {
                "S": "yeonwoo123"
            },
            "post_ts": {
                "S": "2023-02-08T12:34:09Z"
            }
        },
        {
            "content": {
                "S": "second post"
            },
            "user_id": {
                "S": "yeonwoo123"
            },
            "post_ts": {
                "S": "2023-02-09T12:34:09Z"
            }
        }
    ],
    "Count": 2,
    "ScannedCount": 4,
    "ConsumedCapacity": null
}

user_id 가 yeonwoo123 인 항목만 필터링해서 출력하는 명령어로

클라이언트 측에서 작동하게 된다

 

스캔 + page size

[cloudshell-user@ip-10-2-27-234 ~]$ aws dynamodb scan --table-name UserPosts 
{
    "Items": [
        {
            "content": {
                "S": "after enable dynamodb stream"
            },
            "user_id": {
                "S": "123"
            },
            "post_ts": {
                "S": "456"
            }
        },
        {
            "content": {
                "S": "Hello world, this is my first blog!"
            },
            "user_id": {
                "S": "yeonwoo123"
            },
            "post_ts": {
                "S": "2023-02-08T12:34:09Z"
            }
        },
        {
            "content": {
                "S": "second post"
            },
            "user_id": {
                "S": "yeonwoo123"
            },
            "post_ts": {
                "S": "2023-02-09T12:34:09Z"
            }
        },
        {
            "content": {
                "S": "Alice blog"
            },
            "user_id": {
                "S": "alice456"
            },
            "post_ts": {
                "S": "2023-02-11T00:19:07Z"
            }
        }
    ],
    "Count": 4,
    "ScannedCount": 4,
    "ConsumedCapacity": null
}
(END)

테이블 전체를 스캔하는데 api 호출이 1번 으로 실행된다

만약 테이블 항목 숫자가 많다면 시간 초과가 발생할 것

 

스캔 + --page-size

[cloudshell-user@ip-10-2-27-234 ~]$ aws dynamodb scan --table-name UserPosts --page-size 1
{
    "Items": [
        {
            "content": {
                "S": "after enable dynamodb stream"
            },
            "user_id": {
                "S": "123"
            },
            "post_ts": {
                "S": "456"
            }
        },
        {
            "content": {
                "S": "Hello world, this is my first blog!"
            },
            "user_id": {
                "S": "yeonwoo123"
            },
            "post_ts": {
                "S": "2023-02-08T12:34:09Z"
            }
        },
        {
            "content": {
                "S": "second post"
            },
            "user_id": {
                "S": "yeonwoo123"
            },
            "post_ts": {
                "S": "2023-02-09T12:34:09Z"
            }
        },
        {
            "content": {
                "S": "Alice blog"
            },
            "user_id": {
                "S": "alice456"
            },
            "post_ts": {
                "S": "2023-02-11T00:19:07Z"
            }
        }
    ],
    "Count": 4,
    "ScannedCount": 4,
    "ConsumedCapacity": null
}
(END)

위처럼 --page-size 를 1로 지정하면 api 호출 한번에 1개의 항목을 검색하지만

한 번의 명령으로 인식해서 테이블에 있는 모든 행을 불러오게 된다

 

스캔 + --max-item

[cloudshell-user@ip-10-2-27-234 ~]$ aws dynamodb scan --table-name UserPosts --max-items 1
{
    "Items": [
        {
            "content": {
                "S": "after enable dynamodb stream"
            },
            "user_id": {
                "S": "123"
            },
            "post_ts": {
                "S": "456"
            }
        }
    ],
    "Count": 4,
    "ScannedCount": 4,
    "ConsumedCapacity": null,
    "NextToken": "eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDF9"
}
[cloudshell-user@ip-10-2-27-234 ~]$

한번에 검색할 아이템 갯수를 제한하려면 --max-items n 을 사용

위 경우 1개의 항목만 검색되었다

이제 NextToken 을 사용할 수 있는데

 

[cloudshell-user@ip-10-2-27-234 ~]$ aws dynamodb scan --table-name UserPosts --max-items 1 --starting-token eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDF9
{
    "Items": [
        {
            "content": {
                "S": "Hello world, this is my first blog!"
            },
            "user_id": {
                "S": "yeonwoo123"
            },
            "post_ts": {
                "S": "2023-02-08T12:34:09Z"
            }
        }
    ],
    "Count": 0,
    "ScannedCount": 0,
    "ConsumedCapacity": null,
    "NextToken": "eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDJ9"
}
[cloudshell-user@ip-10-2-27-234 ~]$

위 명령에서 --starting-token 값에 이 전에 확인했던 NextToken 값을 입력해주면 읽었던 항목의 다음 항목을 불러와 준다

위에있는 nexttoken 값으로 다시 불러와보면

 

[cloudshell-user@ip-10-2-27-234 ~]$ aws dynamodb scan --table-name UserPosts --max-items 1 --starting-token eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDJ9
{
    "Items": [
        {
            "content": {
                "S": "second post"
            },
            "user_id": {
                "S": "yeonwoo123"
            },
            "post_ts": {
                "S": "2023-02-09T12:34:09Z"
            }
        }
    ],
    "Count": 0,
    "ScannedCount": 0,
    "ConsumedCapacity": null,
    "NextToken": "eyJFeGNsdXNpdmVTdGFydEtleSI6IG51bGwsICJib3RvX3RydW5jYXRlX2Ftb3VudCI6IDN9"
}

또 다음 항목을 확인할 수 있다

 

 

 

 

 

 

329. DynamoDB 트랜잭션(Transactions)

트랜잭션을 사용하면 하나 이상 테이블의 여러 아이템에 양단간 작업을 할 수 있음

DynamoDB 에 ACID 기능 (Atomicity, Consistency, Isolation, Durability) (원자성, 일관성, 격리, 영속성) 제공

트랜잭션 읽기 모드

- 최종 일관성 (Eventual Consistency) - 전체적으로 일관된 읽기 기능

- 강력한 일관성 (Strong Consistency) - 모든 테이블에서 동시에 읽기 기능

- 트랜잭션 일관성 (Transactional) - 트랜잭션 상에서 일관된 읽기 기능

트랜잭션 쓰기 모드

- 표준 (Standard) - 전체 테이블에 걸쳐서 쓰기를 많이 하는 기능 , 일부는 실패할 수 있음

- 트랜잭션 (Transactional) - 전체 테이블에 걸쳐 모든 쓰기가 작동하거나 혹은 모두 작동하지 않음

 

WCU 와 RCU 를 2배로 소비함

- 각 아이템에 두개 작업을 하려면 백그라운드에서 트랜잭션을 준비하고 또 커밋해야 하기 때문

 

트랜잭션의 두가지 작업

TransactGetItems - 트랜잭션에서 하나 이상의 GetItem 작업을 하는 API 코드

TransactWriteItens - 하나 이상의 PutItem 및 UpdateItem 과 DeleteItem 을 작업함

 

트랜잭션을 폭 넓게 활용됨 - ACID 기능 전체에 걸쳐 사용됨

- 금융거래, 주문관리, 멀티플레잉 게임 등 일관성이 필요한 경우

 

Transactions

 

Capacity Computations (용량 계산)

예시 1) 초당 세번의 트랜잭션 쓰기, 아이템 크기는 5KB 이다. 이때 WCU 값은?

- 30 WCUs

예시 2) 초당 다섯번의 트랜잭션 읽기, 아이템 크기는 5KB 이다. 이때 RCU 값은?

- 20 RCUs

- 아이템 하나를 처리하는데 2RCU 가 필요하고 5번 횟수 , 트랜잭션이니까 *2 

 

 

 

 

 

330. DynamoDB 세션 상태

DynamoDB as Session State Cahe

dynamodb 를 스토리지 형식으로 쓸 수도 있지만 세션 상태를 캐시로 저장할 때 쓸 수도 있음

 

vs ElastiCache :

앨라스틱캐시는 전부 메모리에 위치함 vs dynamoDB 는 서버리스

둘 다 key/value stores

 

vs EFS (세션 상태를 저장하는 또 다른 방법 - 디스크 , 여러 EC2 인스턴스에서 디스크를 공유) :

EFS 는 네트워크 드라이브로 EC2 인스턴스에 연결되어야 함 - 예를들면 람다에서는 사용할 수 없음

 

vs EBS & Instance Store :

로컬 캐싱에만 사용할 수 있음 - 공유 캐싱은 불가능

 

vs S3 :

s3 도 세션 상태에 사용이 가능하지만 지연 시간이 높다

큰 파일에는 적절하지만 작은 객체에는 비효율적임

 

 

 

 

 

331. DynamoDB 파티셔닝 전략

DynamoDB Write Sharding

파티션 키를 잘 분배하라는 내용임

hot key issue 를 방지하기 위함인데

모두 통합해서 관리하는건 위험하다는 뜻인듯 하다

 

 

 

332. DynamoDB 조건부 쓰기, 동시 쓰기, 및 원자적 쓰기

dynamoDB 에서 할 수 있는 모든 쓰기에 대한 이론

 

Concurrent Writes (동시 쓰기)

동시 쓰기

만약 2명의 유저가 db 의 아이템을 업데이트 한다고 할 때

동시 쓰기는 이 2개의 요청을 모두 성공시킨다

하지만 결과적으로 한개의 요청만 성공한 모습일 것

 

Condisional Writes (조건부 쓰기)

조건부 쓰기

조건부 쓰기란, 사용자가 업데이트 할 때 조건을 설정해서 이 조건에 부합해야만 요청을 허용하는 방식

동시성 문제를 해결하기에 좋은 쓰기 방식이며 낙관적 잠금이라고도 부름

 

Atomic Writes (원자적 쓰기)

원자적 쓰기

사용자 1은 값을 1씩 증가시키려고 하고 사용자 2는 값을 2씩 증가시키려고 할 때

dynamoDB 는 두 요청을 모두 성공시키고 결과적으로 3이 증가되게 됨

 

Batch Writes (배치 쓰기)

배치 쓰기

많은 아이템에 쓰기와 업데이트를 동시에 하는 것

 

 

 

 

 

333. S3 를 사용한 DynamoDB 패턴

s3 에서 dynamoDB 를 사용하는 두가지 방법

 

큰 객체를 DynamoDB 에 저장하는 방법

- dynamoDB 의 테이블에는 400KB 데이터까지만 저장 가능함

- 이미지나 영상 데이터같은 경우 적합하지 않음

 

(개인적으로 진행하고 있는 blackpink fan page project 에서 이와 같은 아키텍처 사용중, 괜히 뿌듯함)

 

dynamoDB 를 인덱스 S3 객체 메타데이터 방식으로 사용하는 방법

 

(위랑 아래랑 뭔차이임?, 걍 객체 end-point 를 사용하냐 안하냐 차이인가 트래픽이 덜드나?)

 

 

 

 

334. DynamoDB 작업

  • 테이블 정리(table cleanup)

Scan + DeleteItem

- 많이 느림, 스캔 작업에 RCU , 삭제 작업에 WCU 가 많이 소비됨 - 비쌈

Drop Table + Recreate table

- 빠르고 효율적, 저렴함

- 기존 테이블과 같은 설정으로 재생성하는게 중요함

 

  • 테이블 복제 (copying table)

계정, 리전, 장소에 걸쳐 복제 시

 

AWS Data Pipline

- 백앤드 단계에서 두 테이블을 동기화하고 조정함

 

Backup and restore

- dynamoDB 테이블을 백업하고 새로운 테이블에 복구 하는 방법

- 시간은 걸리지만 훨씬 효율적임

- 다른 외부 서비스를 요구하지 않음

 

Scan + PutItem or BatchWriteItem

- 스스로 스캔 후 PutItem 이나 BatchWriteItem 을 해서 복제

- 개인 코드를 사용해야 함

- 테이블에 동시에 변경을 줄 수 있음

- 권장하는 방법은 아니지만 고려할 만한 옵션이라고 함

 

 

 

 

335. DynamoDB 보안 및 기타

  • Security

VPC Endpoint

- dynamoDB 에 인터넷 없이도 액세스가 가능하도록 해줌, 모든 트래픽은 VPC 내에 보관됨

- IAM 에 의해 모든 액세스 제어

- 미사용 데이터는 AWS KMS 로, 전송 중인 데이터는 SSL/TLS 로 암호화

 

  • Backup and Restore feature avaliable

특정 시간 복구 (Point-in-time Recovery / PITR)

- RDS 와 동일, 성능에 영향을 미치지 않음

일반 백업 후 복구

 

  • Global Tables

다수 리전에 다중 활성화 가능하고 복제 가능한 고성능의 테이블

이를 위해 dynamoDB 스트림 부터 활성화 해야함

 

  •  DynamoDB Local

로컬에서 실행할 수 있는 dynamoDB 시뮬레이션

애플리케이션을 개발하고 테스트 하는 데에 사용 가능

 

  • AWS Database Migration Service

데이터를 마이그레이션 할 때 사용 가능

MongoDB, Oracle, MySQL, S3 등과 함께 사용 가능

 

 

DynamoDB - Users Interact with DynamoDB Directly

만약 클라이언트가 웹이나 모바일에서 테이블을 수정하려고 할 때

일시적 자격 증명을 통해 iam 역할을 할당받게 되고 자신의 데이터만 수정할 수 있게 권한 작업으로 이를 제한하는 것

 

파인 그레인 액세스 (Fine-Grained Access Control)

연합 로그인을 통해서 일시적 자격 증명이 주어지고 IAM 역할이 생성됨

이 IAM 역할에는 조건이 붙게 됨 - 이 조건을 통해 사용자가 할 수 있는 작업이 정의됨

IAM 역할 - Condition

LeadingKey 는 기본 키 값을 기반으로 해서 사용자들에게 row 수준의 액세스 만을 제한하는 것

속성에 대한 조건도 지정 가능 - 이를 통해 사용자가 DynamoDB 테이블에서 볼 수 있는 특정 속성을 제한할 수 있음 

 

요약

- 연결 로그인을 이용해서 파인 그레인 액세스 제어가 가능

- LeadingKey 로 조건을 지정함으로써 row 레벨에서의 제한이 가능

- 컬럼 레벨에서 제한을 하려면 속성 조건도 지정 가능