[찍먹 Cloud Computing] 4. DynamoDB & Amazon RDS
두 개의 대표적인 AWS DB를 공부 해 보자 2021-07-27

AWS의 Database

안녕하세요? Justkode 입니다. 이번 시간에는 AWS의 Database에 대해서 공부 해 보는 시간을 가져 보도록 하겠습니다. AWS에서 사용하는 Database는 두 가지가 있습니다.

DynamoDB

첫 번째는 DynamoDB 입니다. 이는 AWS의 대표격으로 사용 되는 데이터베이스이며, NoSQL Database 중 하나 입니다. 여기서 NoSQL은 무엇이냐 하면, 말 그대로 표준 SQL 인터페이스를 차용하지 않은 데이터베이스를 뜻하며, 정형화 된 데이터가 아니기 때문에 많은 데이터를 읽고 쓰는데에 능한 데이터베이스 입니다.

DynamoDB는 데이터 접근을 위해 Key-Value 방식을 이용 하고, 데이터 타입으로는 JSON을 이용 합니다. 특정 Key를 통해, 그 내부에 있는 데이터에 접근하는 방식이죠. 이를 통해, Key 값만 알면 특정 데이터에 빠르게 접근 할 수 있습니다. 하지만, 데이터가 스키마로 정형화 되지는 않았기 때문복잡한 쿼리문에는 적합 하지 않습니다.

일단 DynamoDB 대시보드로 접속 합니다. 그러면 다음과 같이 테이블 만들기가 보이는 것을 볼 수가 있습니다. 한 번 클릭 해 볼까요?

테이블 만들기 클릭

그러면 다음과 같이 DynamoDB 테이블 만들기 창이 뜨게 됩니다. 테이블 이름에는 원하는 테이블 이름을 작성 하면 되고, 기본 키 - 파티션 키에는 고유 키로 삼고 싶은 속성을 입력 하면 됩니다. 만약 정렬 키 추가를 통해 정렬 키를 입력 하시게 되면, 나중에 데이터를 참조할 때, 정렬 기준으로써 사용 할 수 있습니다.

테이블 이름, 기본 키 입력

위에 있는 테이블 설정 - 기본 설정 사용을 체크 해제 하게 되면, 설정 창이 확장 되게 됩니다. 여기서 검색 속도를 향상 시킬 수 있는 보조 인덱스와, 읽기/쓰기 용량 모드와 프로비저닝 된 용량, Auto Scaling을 설정 할 수 있습니다.

Auto Scaling

유휴 시 암호화는 저장 된 데이터를 보호하기 위한 정책을 선택 해 줄 수 있습니다. 이는 키 값을 기반으로 진행합니다. 다 완료 되었다면 생성 버튼을 눌러 주세요.

유휴 시 암호화

자, 생성이 완료 되었다면, 항목 탭으로 들어가 볼까요? 그러면 다음과 같이 데이터 현황을 볼 수가 있습니다. 현재는 아무런 데이터가 없기 때문에, 조회 할 수 있는 데이터가 없습니다. 한 번 데이터를 추가 해 볼까요? 항목 만들기를 클릭 해 주세요.

항목 만들기 클릭

그러면 다음과 같이 항목을 입력 할 수 있는 창이 뜹니다. 저는 테이블 명에서도 알 수 있다 싶이, 주문 내역이 담긴 테이블을 만들고 싶기 때문에, order_id, customer 그 이상의 데이터를 추가 해 주어야 합니다. 왼쪽 상단의 Tree를 클릭 하여, Text로 바꿔 주세요.

Tree - Text로 변경

클릭 하게 되면, 다음과 같이, JSON을 입력 할 수 있는 창이 뜹니다. 저는 다음과 같이, items 어트리뷰트를 추가 하여, 해당 어트리뷰트는 주문 목록이 담겨있는 배열을 만들도록 하였습니다. 입력이 완료 되셨다면, 저장을 클릭 해 주세요.

입력 후, 저장.

저장 후 테이블을 확인하면 데이터가 추가 된 것을 볼 수가 있습니다.

데이터가 추가 된 것을 확인 할 수 있음.

저는 이에 이어 두 번째 데이터를 위와 같은 방법으로 추가 하도록 하겠습니다.

데이터 하나 더 추가

자! 이제 두 개의 데이터가 있는 테이블이 완성 되었습니다. 그 다음, 우리가 특정 조건을 통해 조회를 하고 싶을 때는 어떻게 해야 할 까요?

데이터가 두 개가 된 모습.

항목탭의 상단에 있는 검색창에서 스캔쿼리로 바꿔 주고, 파티션 키에 조회 하고 싶은 정보의 파티션 키를 입력 합니다. 여기서는 order_id가 되겠네요, 조건을 더 추가하고 싶으면, 필터 추가를 클릭 합니다. 정보를 다 입력 하셨다면 검색 시작을 통해 조회를 할 수 있습니다. 그러면 아래 사진과 같이 정보가 조회된 모습을 볼 수 있습니다.

검색 화면

DynamoDB의 각 테이블에 대한 트래픽 정보는 측정치 탭을 클릭 하면 조회 할 수 있습니다.

항목 만들기 클릭

AWS RDS

AWS RDS는 AWS에서 제공하는 RDBMS Instance 입니다. AWS EC2를 기반으로 작동하며, 테이블 백업, 모니터링, 로그 등에 대한 기능들을 모두 제공 합니다. 그 대신 일반 AWS RDS에서 구동하는 가격 보다 비쌉니다. 하지만, 위의 기능들을 모두 제공 해 주는 것은 상당한 메리트 입니다.

일단 AWS RDS DashBoard에 접속 해 볼까요? 그러면 다음과 같은 화면을 볼 수 있습니다. 데이터베이스 생성을 클릭 하여, 데이터베이스를 생성해 보죠.

데이터베이스 생성 클릭

그러면 이렇게 데이터베이스 생성 창이 저희를 반겨 주는 것을 볼 수 있습니다. 일단 데이터베이스 생성 방식표준 생성으로 하고, 엔진 옵션 - 엔진 유형MySQL로 하겠습니다.

데이터베이스 생성 창

탬플릿에서는 앞으로 할 DB 설정의 기본 값을 지정 할 수 있습니다. 일단, 프리 티어를 클릭 해 줍니다. 그렇지 않으면 통장이 거덜 날 수도 있습니다.

데이터베이스 생성 창

그 다음, 설정에서는 데이터베이스의 전반적인 인스턴스 식별자(인스턴스 이름), 마스터 사용자 이름(계정명), 암호(계정 암호)를 입력 할 수 있습니다.

계정 관련 세팅 가능

DB 인스턴스 클래스에서는 인스턴스 클래스를 선택할 수 있으며, 여기서 나오는 클래스들은 AWS EC2의 것들과 동일 합니다.

인스턴스 클래스 선택

그 다음, 스토리지에 대한 세팅을 할 수 있습니다.

스토리지 세팅

연결에서는 사용할 VPC의 종류를 선택 하여, VPC 내부 인스턴스에 대해서만 내부에 할당 된 아이피를 통해 접근 가능 하게 할 수 있고, 서브넷 그룹은 AWS EC2에서 설정 한 것 처럼, 보안 그룹을 선택 할 수 있습니다. 퍼블릭 액세스는 VPC가 아닌 외부에서의 접근 허용 여부를 물어 봅니다. VPC 보안 그룹은 데이터베이스에 대한 액세스를 허용할 VPC 보안 그룹을 선택 할 수 있습니다.

연결 관련 세팅

밑에 있는 추가 구성 탭에서는 데이터베이스의 포트를 설정 할 수 있습니다.

포트 설정 창

백업 창에서는 백업에 관련 된 사항들을 설정 할 수 있으며, 자동 백업 활성화의 여부, 백업 보존 기간의 기간에 대해서 설정 합니다.

백업 설정 창

로그 내보내기Amazon CloudWatch Logs로 게시할 로그 유형을 선택 할 수 있습니다.

로그 설정 창

마지막으로, 월별 추정 요금에서는 추정 요금을 확인 할 수 있습니다.

추정요금 확인

이렇게 데이터베이스를 생성하면 데이터베이스 항목에서 우리가 방금 만든 데이터베이스가 생성 되는 모습을 볼 수 있습니다. 생성 하기 까지 5~10분이 걸립니다. 생성이 완료 되었다면, 해당 데이터베이스를 클릭 해 주세요

데이터베이스 생성 완료

그러면 우리가 만든 DB의 엔드포인트를 확인할 수 있습니다. 엔드포인트 내용을 복사 해 주세요.

엔드포인트 복사

그 다음, 터미널로 가서, MySQL CLI를 이용하여 접속 하면 완료 입니다. 기본 계정은 저희가 세팅때 만들었던 계정을 입력 합니다. 그럼 다음과 같이, MySQL 데이터베이스에 접속에 성공 한 것을 볼 수 있습니다.

(주의: 먼저 MySQL CLI의 설치가 선행 되어야 합니다.)

  • Input
mysql -u (마스터 ID) --host (엔드포인트) -P (포트 (기본 값: 3306)) -p

데이터베이스 생성 창

DynamoDB에 AWS Lambda 연결 하기

일단 RDS 같은 경우는 각 언어에서 각 RDBMS에 맞는 써드 파티 라이브러리를 이용하여 쉽게 접근이 가능합니다. 하지만 DynamoDBAWS 자체 제작 데이터베이스이기 때문에, 저번 시간에 썼던 boto3를 이용 하여야 합니다.

만약 외부 코드 혹은 AWS Lambda를 통해 이를 사용하고자 하면 저번에 이용했던 AWS IAM을 사용하여야 합니다.

외부 코드에서 사용 할 경우에 대해 먼저 설명 드리겠습니다. 기존에 사용하던 IAM이 있다면, AWS IAM의 정책을 수정 해 주어야 합니다. IAM - 사용자 - 사용자 선택 - 권한 추가를 클릭 하여, AmazonDynamoDBFullAccess을 추가 해 주세요.

IAM - 사용자 - 사용자 선택 후 '요약' 탭으로 들어가 권한 추가 클릭

기존 정책 직접 연결 - AmazonDynamoDBFullAccess 추가

만약 AWS Lambda에서 실행 하고자 한다면, 다음과 같이 각 함수 - 구성 - 권한 - 실행 역할을 클릭하고, 역할 이름을 클릭 해 주세요.

역할 이름 클릭

그럼 다음과 같은 창이 뜨게 됩니다. 여기서 정책 연결을 클릭 해 주세요.

정책 연결 클릭

여기서 AmazonDynamoDBFullAccess을 추가 해 주면, Lambda 상에서 DynamoDB에 접근이 가능 합니다.

AmazonDynamoDBFullAccess 추가

Code Implement

그럼 함수를 한 번 만져 볼까요? 일단, GET, POST 방식 각각에 대해 처리를 하고자 하기 때문에, 파일을 분리해 주는 것이 코드가 더 깔끔 해 질 것 같습니다. 다음과 같이 get_item.py, post_item.py를 추가 해 줍니다.

get_item.py, post_item.py 추가

그 다음에는 각 파일들을 다음과 같이 수정 후 deploy 해 주세요, 코드 설명은 주석에 있습니다.

  • lambda_function.py
import json
import decimal
from get_item import get_item
from post_item import post_item

def lambda_handler(event, context):
    if event["httpMethod"] == "GET":
        status, response = get_item(event["queryStringParameters"])  # GET 방식 처리, 
    else:
        status, response = post_item(event["body"])  # POST 방식 처리, body 값을 받음.
    
    class DecimalEncoder(json.JSONEncoder):  # Decimal 타입의 데이터를 int 형으로 변환 하기 위함.
        def default(self, o):
            if isinstance(o, decimal.Decimal):
                return int(str(o))
            return super(DecimalEncoder, self).default(o)
        
    return {
        "statusCode": status,
        "body": json.dumps(response, cls=DecimalEncoder)  # json으로 
    }
  • get_item.py
import boto3
from botocore.exceptions import ClientError

def get_item(query):
    if 'order_id' not in query and 'customer' not in query:  # 쿼리 체크
        return 400, {"message": "key error"}
    else:  # query 뽑기
        order_id = int(query["order_id"])
        customer = query["customer"]
    
    dynamodb = boto3.resource('dynamodb')  # dynamodb
    table = dynamodb.Table('order_list')  # Table명 입력
    
    try:
        response = table.get_item(Key={'order_id': order_id, "customer": customer})  # key로 데이터 가져옴, 우리가 입력했던 키 값 입력.
    except ClientError as e:
        return 500, e.response['Error']['Message']  # 에러시 예외 처리
    else:
        if "Item" not in response:  # data 없을 시 404
            return 404, {"message": "data doen't exist"}
        else:
            return 200, response['Item']
  • post_item.py
import boto3
from datetime import datetime

def post_item(body):
    if any([e not in body for e in ('items', 'customer')]):  # 키 값 체크
        return 400, {'message': 'key error'}
    
    dynamodb = boto3.resource('dynamodb')  # dynamodb
    table = dynamodb.Table('order_list')  # Table명 입력
    
    items = body['items']
    customer = body['customer']
    
    # datetime 이용
    order_id = int(datetime.now().strftime("%Y%m%d%H%M%S"))  # 현재 시간을 int로
    response = table.put_item(  # Item을 dict 형태로 추가
       Item={
            'order_id': order_id,
            'customer': customer,
            'items': items
        }
    )
    return 200, {
            'order_id': order_id,
            'customer': customer,
            'items': items
        }

저는 다음과 같은 데이터로 테스트를 했습니다.

  • getitem
{
  "body": null,
  "resource": "/{proxy+}",
  "path": "/path/to/resource",
  "httpMethod": "GET",
  "isBase64Encoded": false,
  "queryStringParameters": {
    "order_id": 1,
    "customer": "justkode"
  },
  "multiValueQueryStringParameters": {
    "order_id": [
      1
    ],
    "customer": [
      "justkode"
    ]
  },
  ...
}
  • postitem
{
  "body": {
    "customer": "justkode",
    "items": [
      {
        "E/A": 3,
        "id": 3,
        "name": "fried chicken",
        "price": 3000
      }
    ]
  },
  "resource": "/{proxy+}",
  "path": "/path/to/resource",
  "httpMethod": "POST",
  "isBase64Encoded": false,
  "queryStringParameters": {},
  "multiValueQueryStringParameters": {},
  "pathParameters": {
    "proxy": "/path/to/resource"
  }
  ...
}

Test 이후

성공적으로 연동이 된 모습 입니다.

GET 성공

POST 성공

마치며

이렇게 AWS RDS, AWS DynamoDB에 대해서 기본 적인 세팅 및 생성 방법에 대해 배워 보는 시간을 가져 보았습니다. 다음 시간에는 Docker 기초에 대해서 공부 해 보도록 하겠습니다.