[AWS]DynamoDB (이게 AWS의 꽃이라구~)

차보경·2022년 11월 7일
3

AWS

목록 보기
8/13
post-thumbnail

DynamoDB

DynamoDB는 규모에 관계없이 10밀리초 미만의 성능을 제공하는 완전관리형 키–값 및 문서 데이터베이스입니다.

DynamoDB란?

  • NoSQL(Not Only SQL) 데이터베이스 (SQL뿐만아닌 다른 형태)
  • 매우 빠른 쿼리 속도
  • Auto-Scaling 기능 탑재 -> 데이터 크기가 늘어나면 사이즈가 자동으로 늘어남
  • Key-Value 데이터 모델 지원 (No SQL이기 때문에)
  • 테이블 생성시 스키마 생성 필요 없음 (테이블 생성시 스키마를 정의하지 않아도 됨)
  • 모바일, 웹, IoT데이터 사용시 추천됨 (실시간 데이터 처리에 좋음 알아서 스키마를 만들어주기도하고 오토스케일링이 되니까)
  • SSD 스토리지 사용

핵심 키워드

  • 테이블 (Table)
  • 아이템 (Items) - 행(row)과 개념이 비슷함
  • 특징 (Attributes) - 열(column)과 개념이 비슷함
  • Key-Value (Key : 데이터의 이름, Value : 데이터 자신)
  • 예시) JSON, XML (키-벨류 형태 뚜렷함. 그 중 JSON이 많이 쓰임)

Primary Keys (PK)

  • PK를 사용하여 데이터 쿼리

  • DynamoDB에는 두가지의 PK 유형이 있음

  • 파티션키 (Partition Key)

    • 고유 특징 (Unique Attribute)
    • 실제 데이터가 들어가는 위치를 결정해줌

      파티션키를 설정하고 데이터가 들어오면, 데이터가 어디로 저장될지 파티션키의 해시함수를 돌리고 그 해시값을 반환하면 그 위치에 저장함.
      - 파티션키 사용시 동일한 두개의 데이터가 같은 위치에 저장될 수 없음!
  • 복합키 (Composite Key)

    • 파티션키(Partition Key) + 정렬키(Sort Key)
    • 예시 : 똑같은 고객이 다른 날짜에 다른 물건을 구매
    • 파티션키 : 고객아이디, 정렬키 : 날짜(Timestamp)
    • 같은 파티션키의 데이터들은 같은 장소에 보관, 그 다음 정렬키에 의해 데이터가 정렬됨
    {
“Customer_id” : “28942”,  -- 파티션키
“Transaction_id” : “g9s4dd2”,
“Item_purchased” : “sofa”,
“Store_location” : “seoul”,
“Transaction_date” : “2020-10-16 14:20:00”,  -- 정렬키 로 설정하면 좋음
}

DynamoDB 데이터 접근 관리

  • AWS IAM으로 관리할 수 있음
    • 테이블 생성과 접근 권한을 부여할 수 있음
    • 특정 테이블만, 특정 데이터만 접근 가능케 해주는 특별한 IAM 역할 존재

Index (쿼리 기능 향상!)

  • 특정 컬럼만을 사용하여 쿼리를 테이블 전체가 아닌 기준점(pivot)을 사용해 쿼리가 이루어짐
  • 매우 큰 쿼리 성능 효과
  • 두가지의 Index 유형 존재
    • Local Secondary Index
    • Global Secondary Index

Local Secondary Index (LSI)

  • 테이블 생성시에만 정의해줄 수 있음
  • 따라서 테이블 생성 후 변경, 삭제가 불가능
  • 똑같은 파티션키 사용, 그러나 다른 정렬키 사용
    (같은 파티션키, 다른 정렬키로 다른 뷰를 보일 수 있음)
  • 여기서 X,Y는 동일한 파티션 키를 사용함, ESI는 정렬키 기반으로 쿼리 수행시 더 빠름. 정렬키가 없다면 테이블 전체를 뒤져야함.

Global Secondary Index (GSI)

  • 테이블 생성후에도 추가, 변경, 삭제 가능
  • 다른 파티션키, 정렬키 사용 (-> 다른 뷰를 보여 줄 수 있음)
    • 인덱스를 정의하면 전혀다른 파티션키와 정렬키를 가진 뷰가 복제됨. 테이블에서 데이터가 변화하면 뷰는 바로 적용됨)

      뷰를 상대로 쿼리를 하면 더 빠른 쿼리가 가능해짐

Query VS Scan

Query

  • Primary Key를 사용하여 데이터 검색
  • Query사용시 모든 데이터(컬럼) 반환 (이후 정렬키로 정리할 수 있음)
  • ProjectionExpression 파라미터 (보고싶은 컬럼만 보게 수정할 수 있음 -> 필터링 역할)

Scan

  • 모든 데이터를 불러옴 (primary key 사용 X) -> 필터사용
    (쿼리는 불러올 때 이미 파티션이 적용되는 반면, 스캔은 아님)
  • ProjectionExpression 파라미터

Query VS Scan

  • Query가 Scan보다 훨씬 효율적임
  • 따라서 Query 사용 추천
    Scan은 전체 데이터를 확인하고 필터링하는건데 테이블의 크기가 커질수록 속도가 느려질 것. 보완하는 테크닉이 있긴함. (병행스캔_테이블은n으로 쪼개서 동시 다발적으로 스캔하는 것)
  • 테이블의 크기가 크지 않고 테이블의 lookup정도의 테이블(참고용 데이터딕셔너리 정의)이면 scan도 괜츈

실습


이런 테이블을 만들어 보자

  • 정렬키로 transation_data를 사용하면 최신구매한 것들을 기준으로 sorting할 수 있음

  • 항목추가 : 한번에 하나밖에 안됨

  • 불편!!! 이후엔 IoT에서 바로 DynamoDB로 넣거나, S3버켓에 파일 업로드 -> 람다함수 발동 -> DynamoDB로 사용가능

S3버켓에 파일 업로드 -> 람다함수 발동 -> DynamoDB로 사용가능 (실습해보자)

  1. 람다에가서 신규 함수 생성

    이 람다는 DynamoDB에 넣을 수 있는 권한이 있어야하니, IAM으로 가서 설정해줌

  2. IAM 역할 설정

  3. 권한 들어간 역할 만들기

  4. 만든 역할에 람다의 기본요소 사용가능하게 해주는 권한을 넣어줘야함


    이렇게하면 lambda, dynamodb관련 권한을 가진 role이 만들어짐!

  5. 람다에서 실행 역할을 설정해주면 완성!

  6. 람다 함수로 데이터를 입력하는 함수를 넣고 테스트를 돌려주면 함수 오류 확인도 되고(는 내얘기), 데이터가 들어간 것을 확인할 수 있다.

import boto3

def lambda_handler(event, context):
    client = boto3.resource('dynamodb') # AWS 리소스 선택
    table = client.Table('Chabbo_dynamodb_table')

    table.put_item(
        Item={
            'customer_id': '12MCX',
            'transation_data': '2020-08-02',
            'item_category': 'Book',
            'price': 18000
        }
    )

한번에 여러 값을 넣어보자

  1. DynamoDB엔 배치 쓰기라는 것이 있음.

    이렇게 여러 값을 넣어주고 람다함수를 재정의 해주자. 하고 테스트를 돌리면 이렇게 권한이 없다는 멘트가 뜬다.
    [ERROR] ClientError: An error occurred (AccessDeniedException) when calling the BatchWriteItem operation

  2. IAM 정책 수정!
    기존에 만들었던 dynamodb putitem policy 정책에 BatchWriteItem을 추가해준다.

    그리고 다시 테스트를 하면 성공이라는 말과 함께 아이템들이 들어간 것을 확인할 수 있다!

이렇게하면 나중에 코드로 연결된 부분만 다른 곳에서 불러올 수 있도록 처리하면 바로바로 Lambda를 통해 DynamoDB에 저장 가능하겠군

쿼리, 스캔 실습

  1. 스캔으로 100,000원 이상 구매한 사람 sorting

  2. 쿼리로 92cha 검색!

  • 파티션키는 중복을 허용함. (관계형의 Primary key와는 다름)
    관계형에선 Primary key중복 허용 X. NoSQL에서는 파티션키 중복 허용! -> 빠른 검색 활용 가능

  • 추가 NoSQL은 map, list도 값을 저장할 수 있다!(JSON 형태라서 가능한 듯)


DAX (DynamoDB Accelerator)

  • 클러스터 In-memory 캐시 (데이터를 캐시에 저장해서 빠르게 서칭가능)
  • 10배 이상의 속도 향상
  • 읽기 요청만 해당사항 (X 쓰기요청) (수많은 데이터를 읽을 때 사용 가능)
  • Ex) Black Friday날 쇼핑 웹사이트 운영 (수많은 읽기 요청 예상)

DAX 원리

  • DAX 캐싱 시스템
    ➔ DynamoDB 테이블에 데이터 삽입 & 업데이트시 DAX에도 반영 (1타 2피)
  • 읽기 요청에 맞는 데이터가 DAX에 들어있을시 DAX에서 데이터 즉시 반환 (Cache Hit데이터가 있을때) <-> (Cache Miss없을때, 없으면 테이블 뒤져야함)

DAX의 단점

  • 쓰기 요청이 많은 어플리케이션에서는 부적절함
  • 읽기 요청이 많지 않은 어플리케이션에서 부적절함 (Cache Miss가 많으면 부적절. 비용나가니까 테이블만 뒤지면 되는데 캐시까지 뒤지니까 시간도 소용됨)
  • 아직 모든 지역에서 제공하지 않음 (지금도 한국은 없음)

    지역을 오하이오로 바꾸니까 DAX가 뜬다

Streams

  • DynamoDB 테이블에서 일어나는 일들(삽입, 수정, 삭제 등)이 일어날 시 시간적 순서에 맞게 Streams에 기록
  • Log는 즉각 암호화가 일어나며 24시간동안 보관됨
  • 주로 이벤트를 기록하고 이벤트 발생을 외부로 알리는 용도 (예시 : Lambda Function)
  • 이벤트 전&후에 대한 상황 보관
  • DynamoDB API : 직접 DynamoDB와 소통하는 것(테이블에 입력, 삭제) -> 하나의 API는 하나의 Endpoint와 연결됨.
  • DynamoDB Stream API는 완전 다른 DynamoDB Stream Endpoint와 연결됨
  • 온라인 쇼핑몰에서 아이템을 구매하려면 invoice를 만들건데, 이건 DynamoDB 테이블에 만들고, 이런 데이터 삽입 이벤트를 DynamoDB Stream이 인식하고 람다 함수가 실행됨.
  • 구매가 될 때마다 람다가 발생되고 SNS로 메세지 전송. 이 SNS은 SQS로 보냄. 그럼 구매자는 결제창을 보게 됨 -> 결제하면 구매 완료!

어떤 이벤트가 발생했을 때 대응하는 효율적인 아키텍쳐 만들게해줌.
어떻게 스트림을 만들고 람다와 연결되는지 보면

profile
차보의 Data Engineer 도전기♥ (근데 기록을 곁들인)

0개의 댓글