# Chapter7. AWS에 데이터베이스 환경을 만들어보자 - AWS RDS
웹 서비스의 백엔드를 다룬다고 했을 때 **애플리케이션 코드를 작성하는 것 만큼 중요한 것이 데이터베이스를 다루는 일**입니다. 따라서 어느 정도의 데이터베이스 구축, 쿼리 튜닝에 대해서 기본적인 지식이 필요합니다. 이번 장에서는 데이터베이스를 구축하고 앞 장에서 만든 `EC2` 서버와 연동을 해보겠습니다. 다만, **직접 데이터베이스를 설치하지 않습니다.** 직접 데이터베이스를 설치해서 다루게 되면 모니터링, 알람, 백업, `HA` 구성 등을 모두 직접 해야만 합니다. 처음 구축할 때 며칠이 걸릴 수 있는 일입니다.

`AWS`에서는 앞에서 언급한 작업을 모두 지원하는 **관리형 서비스**인 `RDS(Relational Database Service)`를 제공합니다. `RDS`는 `AWS`에서 지원하는 클라우드 기반 관계형 데이터베이스입니다. 하드웨어 프로비저닝, 데이터베이스 설정, 패치 및 백업과 같이 잦은 운영 작업을 자동화하여 개발자가 개발에 집중할 수 있게 지원해주는 서비스입니다. 추가로 **조정 가능한 용량**을 지원하여 예상치 못한 양의 데이터가 쌓여도 비용만 추가로 내면 정상적으로 서비스가 가능한 장점도 있습니다.

---

## 7.1 RDS 인스턴스 생성하기
먼저 `RDS` 인스턴스를 생성하겠습니다. 검색창에 `rds`를 입력해서 선택하고, `RDS` 대시보드에서 `[데이터베이스 생성]` 버튼을 클릭합니다.

`RDS` 생성 과정이 진행됩니다. `DB` 엔진 선택 화면에서 `MariaDB`를 선택하도록 하겠습니다. `RDS`에는 오라클, `MSSQL`, `PostgreSQL` 등이 있으며 당연히 **본인이 가장 잘 사용하는 데이터베이스**를 고르면 되지만, 꼭 다른 데이터베이스를 선택해야 할 이유가 있는 것이 아니라면 `MySQL`, `MariaDB`, `PostgreSQL` 중에 고르길 추천합니다. 필자는 그중에서도 `MariaDB`를 추천하며 이유는 다음과 같습니다.

- 가격
- `Amazon Aurora(오로라)` 교체 용이성

`RDS`의 가격은 라이센스 비용 영향을 받습니다. 상용 데이터베이스인 오라클, `MSSQL`이 오픈소스인 `MySQL`, `MariaDB`, `PostgreSQL` 보다는 **동일한 사양 대비 가격이 더 높습니다.**

두 번째로 **Amazon Aurora 교체 용이성**입니다. `Amazon Aurora`는 `AWS`에서 **MySQL과 PostgreSQL을 클라우드 기반에 맞게 재구성한 데이터베이스** 입니다. 공식 자료에 의하면 `RDS MySQL` 대비 5배, `RDS PostgreSQL` 보다 3배의 성능을 제공합니다. 더군다나 **AWS에서 직접 엔지니어링**하고 있기 때문에 계속해서 발전하고 있습니다. 현재도 다른 데이터베이스와 비교해 다양한 기능을 제공하고 있습니다.

클라우드 서비스에 가장 적합한 데이터베이스이기 때문에 많은 회사가 `Amazon Aurora`를 선택합니다. 그러다 보니 호환 대상이 아닌 오라클, `MSSQL`을 굳이 선택할 필요가 없습니다. 이렇게 보면 `Aurora`를 선택하면 가장 좋을 것 같지만 시작하는 단계에서 `Aurora`를 선택하기 어렵습니다. **프리티어 대상이 아니며**, 최저 비용이 **월 10만원 이상**이기 때문에 부담스럽습니다. 그래서 일단은 `MariaDB`로 시작합니다.

**MySQL을 기반**으로 만들어졌기 때문에 쿼리를 비롯한 전반적인 사용법은 `MySQL`과 유사하니 사용 방법에 대해서는 크게 걱정하지 않아도 됩니다. 비슷한 사용법 외에도 `MariaDB`는 `MySQL` 대비 다음의 장점이 있습니다.

- 동일 하드웨어 사양으로 `MySQL`보다 향상된 성능
- 좀 더 활성화된 커뮤니티
- 다양한 기능
- 다양한 스토리지 엔진

참고 자료 : ["MySQL에서 MariaDB로 마이그레이션 해야 할 10가지 이유"](https://xdhyix.wordpress.com/2016/03/24/mysql-%EC%97%90%EC%84%9C-mariadb-%EB%A1%9C-%EB%A7%88%EC%9D%B4%EA%B7%B8%EB%A0%88%EC%9D%B4%EC%85%98-%ED%95%B4%EC%95%BC%ED%95%A0-10%EA%B0%80%EC%A7%80-%EC%9D%B4%EC%9C%A0/)

다음으로 넘어가면 사용 사례 항목이 나옵니다. `[프리티어]`를 선택합니다.

상세 설정에서는 다음과 같이 설정합니다.

>DM 인스턴스 클래스 : db.t2.micro - 1 vCPU, 1GiB RAM / 할당된 스토리지 : 20
스토리지 자동 조정 체크해제
DB 인스턴스 식별자 : 원하는 이름
마스터 사용자 이름 : 원하는 이름
마스터 암호 : 원하는 암호

본인만의 `DB` 인스턴스 이름과 사용자 정보를 등록합니다. 여기서 사용된 사용자 정보로 실제 데이터베이스에 접근하게 됩니다. 네트워크에선 퍼블릭 엑세스를 `[예]`로 변경합니다. 이후 보안 그룹에서 지정된 IP만 접근하도록 막을 예정입니다.

데이터베이스 옵션에서는 **이름을 제외한 나머지를** 일단 기본값으로 둡니다.

모든 설정이 끝나서 `[완료]` 버튼을 클릭하면 생성 과정이 진행되고, 데이터베이스가 다 생성되었다면 이제 본격적으로 설정을 해보겠습니다.

---

## 7.2 RDS 운영환경에 맞는 파라미터 설정하기
`RDS`를 처음 생성하면 몇 가지 설정을 필수로 해야합니다. 우선 다음 3개의 설정을 차례로 진행합니다.

- 타임존
- Character Set
- Max Connection

왼쪽 카테고리에서 `[파라미터 그룹]` 탭을 클릭해서 이동합니다.

화면 오른쪽 위의 `[파라미터 그룹 생성]` 버튼을 클릭합니다.

세부 정보 위쪽에 `DB` 엔진을 선택하는 항목이 있습니다. 여기서 **방금 생성한 MariaDB와 같은 버전**을 맞춰야 합니다. 앞에서 생성된 버전과 같은 버전대를 선택해야 합니다. (ex. 10.2.xx 버전으로 생성되었다면 10.2 버전 선택)

생성이 완료되면 파라미터 그룹 목록 창에 새로 생성된 그룹을 볼 수 있는데, 해당 파라미터 그룹을 클릭한 뒤, `[파라미터 편집]` 버튼을 통해 **편집모드로 전환**합니다.

편집 모드로 되었다면 하나씩 설정값들을 변경합니다. 먼저 `time_zone`을 검색하여 `[Asia/Seoul]`을 선택합니다.

다음으로 `Character Set`을 변경합니다. `Character Set`은 항목이 많습니다. 아래 8개 항목 중 `character` 항목들은 모두 `utf8mb4`로, `collation` 항목들은 `utf8mb4_general_ci`로 변경합니다.

- character_set_client
- character_set_connection
- character_set_database
- character_set_filesystem
- character_set_results
- character_set_server
- collation_connection
- collation_server

`utf8`은 이모지를 저장할 수 없지만, `utf8mb4`는 이모지를 저장할 수 있으므로 보편적으로 `utf8mb4`를 많이 사용합니다.

마지막으로 `Max Connection`을 수정합니다. `RDS`의 `Max Connection`은 **인스턴스 사양에 따라 자동으로** 정해집니다. 현재 프리티어 사양으로는 약 60개의 커넥션만 가능해서 좀 더 넉넉한 값(150)으로 지정합니다.

이후에 `RDS` 사양을 높이게 된다면 기본값으로 다시 돌려놓으면 됩니다. 설정이 다 되었다면 위의 `[변경 사항 저장]` 버튼을 클릭해 최종 저장합니다.

이렇게 생성된 파라미터 그룹을 다음과 같은 순서로 데이터베이스에 연결합니다.

>1. 좌측의 데이터베이스 버튼 클릭
>2. 데이터베이스 선택
>3. 수정 버튼 클릭
>
>4. 이후 추가 구성의 데이터베이스 옵션 항목에서 `DB` 파라미터 그룹은 `default`로 되어있습니다. `DB` 파라미터 그룹을 방금 생성한 신규 파라미터 그룹으로 변경합니다.

계속을 누르면 수정 사항 요약을 볼 수 있습니다. 여기서 반영 시점을 `[즉시 적용]`으로 합니다. 예약된 다음 유지 시간으로 하면 지금 하지 않고, 새벽 시간대에 진행하게 됩니다. 이 수정사항이 반영되는 동안 데이터베이스가 작동하지 않을 수 있으므로 예약 시간을 걸어두라는 의미지만, 지금은 서비스가 오픈되지 않았기 때문에 즉시 적용합니다. 그럼 `수정 중` 상태가 나옵니다.

간혹 파라미터 그룹이 제대로 반영되지 않을 때가 있습니다. 정상 적용을 위해 한 번 더 재부팅을 진행합니다.(`작업 - 재부팅 버튼`)

재부팅까지 성공했다면 이제 로컬 PC에서 RDS에 한 번 접속해 보겠습니다.

---

## 7.3 내 PC에서 RDS에 접속해 보기
로컬 PC에서 `RDS`로 접근하기 위해서 **RDS의 보안 그룹에 본인 PC의 IP를 추가**합니다. `RDS`의 세부정보 페이지중 `연결 & 보안`탭에서 `VPC 보안 그룹`중 활성 항목을 클릭합니다.

`RDS`의 보안 그룹 정보를 그대로 두고, 브라우저를 새로 열어 봅니다. 새로 연 브라우저 창에서는 보안 그룹 규칙 탭에서 **EC2에 사용된 보안 그룹의 그룹 ID**를 복사합니다.

복사된 보안 그룹 ID와 본인의 IP를 아래 쪽의 인바운드 규칙 탭의 `인바운드 규칙 편집` 버튼을 통해 **RDS 보안 그룹의 인바운드**로 추가합니다.

인바운드 규칙 유형에서는 `MYSQL/Aurora`를 선택면 자동으로 3306 포트가 선택됩니다.

- 보안 그룹 첫 번째 줄 : 현재 내 PC의 IP를 등록합니다.
- 보안 그룹 두 번째 줄 : `EC2`의 보안 그룹을 추가합니다.
  - 이렇게 하면 **EC2와 RDS 간에 접근이 가능**합니다.
  - `EC2`의 경우 이후에 2대 3대가 될 수도 있는데, 매번 IP를 등록할 수는 없으니 보편적으로 이렇게 보안 그룹 간에 연동을 진행합니다.

  `RDS`와 개인 PC, `EC2` 간의 연동 설정은 모두 되었습니다. 로컬에서 한번 테스트해 보겠습니다.

### Database 플러그인 설치
로컬에서 원격 데이터베이스로 붙을 때 GUI 클라이언트를 많이 사용합니다. `MySQL`의 대표적인 클라이언트로 `Workbench`, `SQLyog`(유료), `Sequel Pro`(맥 전용), `DataGrip`(유료) 등이 있습니다.

각각의 도구마다 큰 차이가 없으니 **본인이 가장 좋아하는 툴을** 사용하면 됩니다. 이 책에서는 **인텔리제이에 Database 플러그인**을 설치해서 진행하겠습니다.

`RDS` 정보 페이지의 `연결 & 보안` 탭에서 **엔드 포인트**를 확인합니다. 이 엔드 포인트가 접근 가능한 URL이므로 메모장 같은 곳에 복사해 둡니다.

이 책에서는 `Database Navigator` 플러그인을 사용하고 있으나 인텔리제이의 공식 플러그인이 아닙니다.

~~자세한 내용은 책을 참조할 것. 인텔리제이 얼티메이트 버전에는 해당되지 않는 것 같습니다.~~

#### IntelliJ Ultimate 기준

![Chapter7_database_RDS_1](https://user-images.githubusercontent.com/68052095/100730191-15ce6880-340d-11eb-80c4-289adb8bc0ec.PNG)

`Database` -> `Data Source` -> `MySQL` 선택(**MariaDB는 MySQL 기반이므로**) 후 본인이 생성한 `RDS`의 정보를 차례로 등록합니다.

![Chapter7_database_RDS_2](https://user-images.githubusercontent.com/68052095/100730194-16ff9580-340d-11eb-8356-3a9ca9aa08cb.PNG)

- Host : 방금 전 복사한 RDS의 엔드 포인트를 등록합니다.
- User : 데이터베이스를 만들때 입력한 마스터 사용자 이름을 입력합니다.
- Password : 마스터 암호를 입력합니다.

마스터 계정명과 비밀번호를 등록한 뒤, 화면 아래의 `[Test Connection]`을 클릭해 연결 테스트를 해봅니다.

`Connection Successful` 메시지를 보았다면 `[Apply -> OK]` 버튼을 차례로 눌러 최종 저장을 합니다.

![Chapter7_database_RDS_3](https://user-images.githubusercontent.com/68052095/100730198-16ff9580-340d-11eb-89dd-bae3c4a88bb9.PNG)

그럼 인텔리제이에 `RDS`의 스키마가 노출됩니다. 위쪽에 있는 `[Open SQL Console]` 버튼을 클릭하고 `[New SQL Console..]` 항목을 선택해서 SQL을 실행할 콘솔창을 열어보겠습니다.

![Chapter7_database_RDS_4](https://user-images.githubusercontent.com/68052095/100730200-17982c00-340d-11eb-93f7-52b03df8c66c.PNG)

사진에 보이는 `console`의 이름을 적당히 바꿔준 뒤, 생성된 콘솔창에서 SQL을 실행해 보겠습니다. 

쿼리가 수행될 `database`를 선택하는 쿼리입니다.

>use AWS `RDS 웹 콘솔에서 지정한 데이터베이스명`;

만약 본인이 `RDS` 생성 시 지정한 `database` 명을 잊었다면 인텔리제이의 `Database`탭에 생성된 `DB`의 `Schema` 항목을 보면 **MySQL에서 기본으로 생성하는 스키마 외에 다른 스키마**가 1개 추가되어 있으니 이를 확인하면 됩니다.

데이터베이스가 선택된 상태에서 **현재의 character_set, collation** 설정을 확인합니다.

> show variables like 'c%';

쿼리 결과를 보면 다른 필드들은 모두 `utf8mb4`가 잘 적용되었는데 `character_set_database`, `collation_connection` 2가지 항목이 `latin1`로 되어있습니다.

이 2개의 항목이 `MariaDB`에서만 `RDS` 파라미터 그룹으로는 변경이 안됩니다. 그래서 직접 변경하기 위해 다음 쿼리를 실행합니다.

>ALTER DATABASE 데이터베이스명
>CHARACTER SET = 'utf8mb4'
>COLLATE = 'utf8mb4_general_ci';

쿼리를 수행하였다면 다시 한번 `character set`을 확인해 봅니다.

성공적으로 모든 항목이 `utf8mb4`로 변경된 것을 확인했다면 **타임존**까지 아래 쿼리로 확인해 봅니다.

>select @@time_zone, now();

`RDS` 파라미터 그룹이 잘 적용되어 한국 시간으로 된 것을 확인할 수 있습니다.

마지막으로 한글명이 잘 들어가는지 간단한 테이블 생성과 `insert` 쿼리를 실행해 봅니다.

>테이블 생성은 인코딩 설정 변경 전에 생성되면 안 됩니다. 만들어질 당시의 설정값을 그대로 유지하고 있어, 자동 변경이 되지 않고 강제로 변경해야만 합니다. 웬만하면 테이블은 모든 설정이 끝난 후 생성하시는 것이 좋습니다.

다음 쿼리를 차례로 실행해 봅니다.

>CREATE TABLE test (
  id bigint(20) NOT NULL AUTO_INCREMENT,
  content varchar(255) DEFAULT NULL,
  PRIMARY KEY (id)
) ENGINE=InnoDB;
>
>insert into test(content) values ('테스트');
>
>select * from test;

한글 데이터도 잘 등록되는 것을 확인할 수 있습니다.

`RDS`에 대한 모든 설정이 끝났습니다. 이제 이렇게 설정된 `RDS`가 `EC2`와 잘 연동되는지 확인해 보겠습니다.

---

## 7.4 EC2에서 RDS에서 접근 확인
`EC2`에 `ssh` 접속을 진행합니다.

- 맥에선 `ssh` 서비스명
- 윈도우에선 `putty`

접속되었다면 `MySQL` 접근 테스트를 위해 `MySQL CLI`를 설치하겠습니다.

> sudo yum install mysql

설치가 다 되었으면 로컬에서 접근하듯이 계정, 비밀번호, 호스트 주소를 사용해 `RDS`에 접속합니다.

> mysql -u 계정 -p -h Host주소
>
>ex) mysql -u banjjoknim -p -h springboot2-webservice.cdlzwe9h6r65.ap-northeast-2.rds.amazonaws.com

참고 링크 : [AWS : RDS 인스턴스 연결 오류](https://bravesuccess.tistory.com/196)

패스워드를 입력하라는 메시지가 나오면 패스워드까지 입력합니다. `EC2`에서 `RDS`로 접속되는 것을 확인할 수 있습니다.

`RDS`에 접속되었으면 실제로 생성한 `RDS`가 맞는지 간단한 쿼리를 한번 실행해 봅니다.

> show databases;

우리가 생성했던 데이터베이스(`springboot2-webservice`)가 있음을 확인할 수 있습니다.

---