안녕하세요? Justkode 입니다. 이번 시간에는 AWS의 Database에 대해서 공부 해 보는 시간을 가져 보도록 하겠습니다. AWS에서 사용하는 Database는 두 가지가 있습니다.
첫 번째는 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에서 제공하는 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
의 설치가 선행 되어야 합니다.)
mysql -u (마스터 ID) --host (엔드포인트) -P (포트 (기본 값: 3306)) -p
데이터베이스 생성 창
일단 RDS 같은 경우는 각 언어에서 각 RDBMS에 맞는 써드 파티 라이브러리를 이용하여 쉽게 접근이 가능합니다. 하지만 DynamoDB는 AWS 자체 제작 데이터베이스이기 때문에, 저번 시간에 썼던 boto3
를 이용 하여야 합니다.
만약 외부 코드 혹은 AWS Lambda를 통해 이를 사용하고자 하면 저번에 이용했던 AWS IAM을 사용하여야 합니다.
외부 코드에서 사용 할 경우에 대해 먼저 설명 드리겠습니다. 기존에 사용하던 IAM이 있다면, AWS IAM의 정책을 수정 해 주어야 합니다. IAM - 사용자 - 사용자 선택 - 권한 추가를 클릭 하여, AmazonDynamoDBFullAccess을 추가 해 주세요.
IAM - 사용자 - 사용자 선택 후 '요약' 탭으로 들어가 권한 추가 클릭
기존 정책 직접 연결 - AmazonDynamoDBFullAccess 추가
만약 AWS Lambda에서 실행 하고자 한다면, 다음과 같이 각 함수 - 구성 - 권한 - 실행 역할을 클릭하고, 역할 이름을 클릭 해 주세요.
역할 이름 클릭
그럼 다음과 같은 창이 뜨게 됩니다. 여기서 정책 연결을 클릭 해 주세요.
정책 연결 클릭
여기서 AmazonDynamoDBFullAccess을 추가 해 주면, Lambda 상에서 DynamoDB에 접근이 가능 합니다.
AmazonDynamoDBFullAccess 추가
그럼 함수를 한 번 만져 볼까요? 일단, GET
, POST
방식 각각에 대해 처리를 하고자 하기 때문에, 파일을 분리해 주는 것이 코드가 더 깔끔 해 질 것 같습니다. 다음과 같이 get_item.py
, post_item.py
를 추가 해 줍니다.
get_item.py, post_item.py 추가
그 다음에는 각 파일들을 다음과 같이 수정 후 deploy 해 주세요, 코드 설명은 주석에 있습니다.
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으로
}
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']
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
}
저는 다음과 같은 데이터로 테스트를 했습니다.
{
"body": null,
"resource": "/{proxy+}",
"path": "/path/to/resource",
"httpMethod": "GET",
"isBase64Encoded": false,
"queryStringParameters": {
"order_id": 1,
"customer": "justkode"
},
"multiValueQueryStringParameters": {
"order_id": [
1
],
"customer": [
"justkode"
]
},
...
}
{
"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"
}
...
}
성공적으로 연동이 된 모습 입니다.
GET 성공
POST 성공
이렇게 AWS RDS, AWS DynamoDB에 대해서 기본 적인 세팅 및 생성 방법에 대해 배워 보는 시간을 가져 보았습니다. 다음 시간에는 Docker 기초에 대해서 공부 해 보도록 하겠습니다.