Skip to main content 집밥서선생

RDS로 Postgresql 인스턴스 설정 과정

Published: 2023-02-28

RDS란?


RDS는 MySQL, PostgreSQL, Oracle, Microsoft SQL Server, Amazon Aurora와 같은 다양한 데이터베이스 엔진을 클라우드 환경에서 쉽게 구축, 운영, 확장할 수 있도록 지원하는 Amazon Web Services의 관리형 관계형 데이터베이스 서비스이다.

데이터베이스 인스턴스를 생성하고 구성하는 프로세스를 자동화함으로써 개발자와 시스템 관리자가 데이터베이스를 관리하는 데 필요한 대부분의 작업을 간소화한다. 또한 백업, 복원, 패치, 모니터링 및 확장과 같은 관리 작업을 수행하는 데 필요한 다양한 기능을 제공한다.

이 뿐만 아니라 RDS는 보안, 가용성, 확장성 등에 대한 기본적인 지원을 제공하기 때문에 사용자가 애플리케이션에 필요한 데이터베이스 서비스를 쉽게 사용할 수 있다. 이러한 요소들로 인해 RDS는 클라우드 환경에서 안전하고 신뢰할 수 있는 데이터베이스가 된다.



VPC 설정


  • VPC
  • 서로 다른 AZ의 Subnet 세 개
  • Internet Gateway
  • 인바운드 포트로 22, 80, 25432 세 개 뚫어놓은 Security Group

rds cluster를 만들 때 서로 다른 AZ에 속하는 subnet이 최소 세 개 필요
5432가 postgresql 기본 포트이고, 25432는 추후 연결시 변경한 포트

여기를 참조하여 VPC는 위와 같이 세팅해놓았다.


 만들어진 vpc에 Actions > Edit VPC settings 해서 DNS setting을 모두 체크해주었다. 아마 Public Access할 때 필요한 옵션이다.

EC2 Instance 생성


  EC2 특이사항은 없고 생성할 때 VPC, SG에 등록해준다.

RDS 생성


주요 설정은 아래 사진과 같다.


데이터베이스 버전

 PostgreSQL로 인스턴스를 생성할 것이며, 기본 버전인 PostgreSQL 13.7-R1로 생성하였다.

Template 및 Availability

 프로덕션용/개발용 여부인지에 따라서 Production이랑 Dev/Test 중 골라서 선택해주면 될 듯 하다.

그 아래 Deployment options은 Multi-AZ cluster, Multi-AZ instance, single instance 세 개의 option이 있다.

single instance는 당연히 하나의 인스턴스만 띄우는 것인데 반해, Multi-AZ가 붙은 옵션은 AZ에 문제가 생기는 경우를 상정하여 다른 AZ에 스탠바이 인스턴스를 띄운다.

multi-AZ cluster에서는 writer 인스턴스와 reader 인스턴스가 분리되어 있으며, 쓰기 작업은 writer 인스턴스, 읽기 작업은 reader 인스턴스에서 진행된다. 반면 Multi-AZ instance나 Single Instance에서는 하나의 인스턴스에서 읽기/쓰기가 모두 진행된다.

항목 Multi-AZ cluster Multi-AZ instance
인스턴스 타입 read/write 인스턴스 분리 read/write 인스턴스 통합
인스턴스 수 reader 2개 + writer 1개 active 1개 + standby 1개
비용 비쌈
($0.804 per hour)
덜 비쌈
($0.441 per hour)
autoscaling 불가능 가능
언제 쓸까? 서비스가 더 커질 것을 전망 돈 아끼고 싶을 때

Authentification Settings

 master username, master password를 설정해준다.

Instance Type

 인스턴스 타입이나 스토리지 타입을 적절히 설정해준다. 마찬가지로 아래 표로 정리하였다.
용도 상황
db.m~ 범용 일반적인 경우
db.r~ 메모리 최적화 저장하는 데이터가 많은 경우
db.t~ CPU 버스트 읽기/쓰기 빈도가 높은 경우
용도 상황
General Purpose SSD (gp2) 범용 일반적인 경우
General Purpose SSD (gp3) 범용 + 확장성 일반적인 경우 + 확장 가능성
Provisioned IOPS (io) I/O 최적화 읽기/쓰기 빈도가 높은 경우
Magnetic Deprecated 쓰지마세용

Connectivity

  EC2에 직접 연결을 하면 public access가 블록된다. public access를 허용하려면 EC2에 연결하지 않고 public access를 허용해주면 되며, VPC 및 SG를 설정해주면 EC2에서도 연결이 가능하다. 추가로 사진엔 반영되지 않았는데 포트까지 25432로 변경해보았다.

additional configuration에 cloudwatch 설정같은 것도 있는 듯 하니, 필요하다면 설정해도 될 듯 하다.

이후 인스턴스를 생성하면 얼마 후 연결이 가능할 것이다.



RDS 접속

이제 접속이 잘 되는지 확인해보자.


(EC2에서) RDS 연결

만약 public access를 활성화했다면 로컬에서도 연결이 가능하다. 비활성화 했다면 EC2에서만 접근이 가능하다.

우선 EC2 인스턴스에 postgresql client를 설치해주자. postgresql client가 설치되어 있다면 이 과정은 생략해도 좋다.

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install postgresql-client

rds 인스턴스의 접속 엔드포인트를 확인한 후, 다음과 같은 명령어로 rds 인스턴스에 접속한다. 만약 인스턴스를 생성할 때 Multi-AZ cluster로 생성하였다면 writer의 엔드포인트로 접속해야 한다.

psql 
--host=<엔드포인트> 
--port=<포트번호> 
--username=<사용자명> 
--password 
--dbname=postgres

dbname의 postgres는 PostgreSQL의 마스터 유저로, 초기 접속시에는 postgres로 접속해야 한다.


접속했다면, 데이터베이스를 생성하고 다시 접속하여 테스트 데이터를 만들어보자.

create database mydb;
q;
psql 
--host=<엔드포인트> 
--port=<포트번호> 
--username=<사용자명> 
--password 
--dbname=mydb
create table mytable (
    id int not null primary key,
    name varchar(20) not null
);
insert into mytable values (1, 'ㅎㅇ');

Multi-AZ cluster라면 \q로 나간 후 reader로 재접속하여 endpoint로 rds에 접속해서 확인해보자.

psql 
--host=<엔드포인트> 
--port=<포트번호> 
--username=<사용자명> 
--password 
--dbname=mydb
select * from mytable;

gui tools

어느 블로그 포스트를 보니 모니터링 툴 중 TablePlus란 게 그렇게 좋다고 한다. 써보니 우분투는 아직 알파 릴리즈라 오류가 좀 나는 듯.

보이는 필드들을 모두 채워주면 된다.


접속하고 나서 이것저것 시도해보니 이렇게 데이터를 보여줍니다.



ORM 연결

ORM으로 Python의 SQL Alchemy를 써서 연결해보았다.

from sqlalchemy import create_engine
from dotenv import load_dotenv
from sqlalchemy.orm import sessionmaker
import os

load_dotenv()

HOST = os.environ.get("DB_HOST")
PORT = os.environ.get("DB_PORT")
ID = os.environ.get("DB_ID")
PW = os.environ.get("DB_PW")
DB = os.environ.get("DB_DB")

URL = "postgresql://{}:{}@{}:{}/{}".format(ID, PW, HOST, PORT, DB)

db = create_engine(URL)
Session = sessionmaker(db)
session = Session()

rows = session.execute("SELECT * FROM mytable")
for row in rows:
    print(row)

session.close()

모델 코드 짜기 귀찮아서 로우쿼리 날렸는데 잘 받아와진다.

© 2024 JHSeo. All right reserved.