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)
{
“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로 사용가능 (실습해보자)
-
람다에가서 신규 함수 생성
이 람다는 DynamoDB에 넣을 수 있는 권한이 있어야하니, IAM으로 가서 설정해줌
-
IAM 역할 설정
-
권한 들어간 역할 만들기
-
만든 역할에 람다의 기본요소 사용가능하게 해주는 권한을 넣어줘야함
이렇게하면 lambda, dynamodb관련 권한을 가진 role이 만들어짐!
-
람다에서 실행 역할을 설정해주면 완성!
-
람다 함수로 데이터를 입력하는 함수를 넣고 테스트를 돌려주면 함수 오류 확인도 되고(는 내얘기), 데이터가 들어간 것을 확인할 수 있다.
import boto3
def lambda_handler(event, context):
client = boto3.resource('dynamodb')
table = client.Table('Chabbo_dynamodb_table')
table.put_item(
Item={
'customer_id': '12MCX',
'transation_data': '2020-08-02',
'item_category': 'Book',
'price': 18000
}
)
한번에 여러 값을 넣어보자
-
DynamoDB엔 배치 쓰기라는 것이 있음.
이렇게 여러 값을 넣어주고 람다함수를 재정의 해주자. 하고 테스트를 돌리면 이렇게 권한이 없다는 멘트가 뜬다.
[ERROR] ClientError: An error occurred (AccessDeniedException) when calling the BatchWriteItem operation
-
IAM 정책 수정!
기존에 만들었던 dynamodb putitem policy 정책에 BatchWriteItem을 추가해준다.
그리고 다시 테스트를 하면 성공이라는 말과 함께 아이템들이 들어간 것을 확인할 수 있다!
이렇게하면 나중에 코드로 연결된 부분만 다른 곳에서 불러올 수 있도록 처리하면 바로바로 Lambda를 통해 DynamoDB에 저장 가능하겠군
쿼리, 스캔 실습
-
스캔으로 100,000원 이상 구매한 사람 sorting
-
쿼리로 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로 보냄. 그럼 구매자는 결제창을 보게 됨 -> 결제하면 구매 완료!
어떤 이벤트가 발생했을 때 대응하는 효율적인 아키텍쳐 만들게해줌.
어떻게 스트림을 만들고 람다와 연결되는지 보면