데이터베이스
- DB, 여러 사람에 의해 공유되어 사용될 목적으로 통합하여 관리 되는 데이터의 집합이다.
RDBMS(Relational Databaase Management System)
- 관계형 데이터베이스, 가장 많이 사용되는 데이터베이스의 한 종류로 데이터 간 사전에 정의된 관계(Relational)가 있고, 연관 관계가 있는 데이터 항목들의 모음을 말한다.
- 대표적인 관계형 데이터베이스 관리시스템(RDBMS)으로 Oracle과 MySQL, Microsoft SQL Server, PostgreSQL, MariaDB 등이 있다.
- Amazon Web Services는 RDS(Relational Database Services)라는 서비스를 통해 RDBMS 서비스를 제공한다.
RDS(Relational Database Services)
- Amazon RDS는 클라우드에서 관계형 데이터베이스를 더욱 간편하게 설정, 운영 및 확장할 수 있는 서비스이다.
- 하드웨어 프로비저닝, 데이터베이스 설정, 패치 및 백업과 같은 시간 소모적인 관리 작업을 자동화하면서 비용 효율적이고 크기 조정 가능한 데이터베이스 서비스를 제공한다.
구분 | 내용 |
---|
서비스명 | Amazon RDS(Relational Database Services) |
설명 | 주로 사용되는 6개의 데이터베이스 엔진 중에서 선택할 수 있는 아마존 관계형 데이터베이스 서비스 |
주요 특징 | 관리 용이성, 뛰어난 확장성, 가용성 및 내구성, 빠른 속도, 보안 |
Amazon 클라우드 데이터베이스 서비스의 선택 사항
- 직접 EC2에 데이터베이스를 설치하여 이용하는 것
본인이 원하는 Database를 EC2 인스턴스에 직접 설치하여 운영하는 방법으로 기존 On-Premise에서 사용하던 데이터베이스를 그대로 사용할 수 있고 가장 이질감 없이 사용할 수 있다. 다만 데이터베이스 제공 벤더사에 따라서는 클라우드용 라이선스를 운영하는 경우가 있으므로 EC2에 설치 운영 전에 미리 파트너사를 통해 기존 라이선스를 사용할 수 있는지 여부를 확인해야 한다.
- AWS에서 직접 제공해주는 데이터베이스 서비스를 이용하는 것
AWS는 관계형 데이터베이스 서비스인 Amazon RDS, NoSQL 기반의 중단 없는 확장성을 제공하는 Amazon DynamoDB, 대용량 병렬 페타바이트급 데이터웨어(Data Ware) 서비스를 제공할 수 있는 Amazon Redshift와 같은 다양한 데이터베이스 서비스를 제공한다.
특징으로 설치 및 운영/관리를 Amazon에서 제공하므로 별도의 운영/관리가 필요 없으며, 서비스의 용도 및 사용량에 따라 원하는 형태의 리소스를 선택할 수 있다.
Amzon RDS 주요 특징
- 유연한 인스턴스 및 스토리지 확장
RDS는 다양한 CPU/메모리 옵션을 제공한다. Cloudwatch와 연계를 통해 트래픽에 따른 증설 및 사양의 축소도 가능하다. DB의 데이터 저장 공간인 스토리지는 필요에 따라 유연하게 확장이 가능하다.
- 손쉽게 사용 가능한 백업 및 복원 기능
RDS는 자동 백업 설정을 통해 손쉽게 백업이 가능하며, 특정 시점으로 손쉽게 복구할 수 있는 기능을 제공한다. 최대 35일까지 데이터를 보존하며, 스냅샷(Snapshot)을 통해 Database를 생성할 수도 있다.
- 멀티 AZ(Availability Zone)를 통한 고가용성 확보
RDS는 멀티 AZ 기능을 활용하여 Region 내 AZ 간 데아터베이스 동기화(Synchronization) 구성이 가능하며, 주요 장애 상황 발생 시 자동으로 데이터베이스 Failover를 수행할 수 있도록 고가용성을 지원한다. 리플리케이션을 통한 가용성도 지원한다.
MySQL은 읽기 트래픽을 자동 관리하는 Read Replica로 분산 서비스를 제공할 수 있다.
- RDS 암호화 옵션을 통해 보안성 강화
모든 RDS는 옵션을 통한 One-Click을 통해 데이터에 대한 암호화 기능을 제공하며, 데이터 백업, 스냅샷(Snapshot), Read Replica에도 적용된다.
KMS를 통해 사용자가 생성하고 관리하는 키(Key) 사용이 가능하다. 다만 RDS DB 생성 시 암호화 Enable 이후 암호화 Disable은 불가능하며, 암호화 DB에서만 암호화 Read Replica를 생성 가능하다.
- Database Migration 서비스
RDS는 AWS Database Migration Services를 통해 동종 혹은 다른 DB 엔진으로부터 RDS로 데이터에 대한 Migration을 지원한다. 또한 EC2 또는 RDS간의 데이터 리플리케이션을 통해 원하는 시점에 비용 효율적인 데이터베이스 대한 데이터 이전을 지원한다.
MySQL용 DB 인스턴스 생성, 클라이언트를 통한 DB 연결 및 삭제
인스턴스 생성
- AWS에 로그인하여 [서비스] -> [데이터베이스]에서 [RDS]로 이동한다.
- 좌측 메뉴에서 [데이터베이스]로 이동하여 [데이터베이스 생성]을 누른다.
- 데이터베이스 생성 방식 선택은 [표준 생성]으로 엔진 옵션은 [MySQL]로 한다.
- 템플릿을 [프리티어]로 하고 설정에서 DB 인스턴스 식별자, 마스터 사용자 이름, 마스터 암호을 입력한다.
- DB 인스턴스 크기는 [버스터블 클래스]에 [db.t2.micro], 스토리지는 [범용(SSD)], 20Gib, [스토리지 자동 조정 활성화] 체크에 임계값은 1000
- 연결에서 VPC는 Default VPC를 사용하고 서브넷 그룹은 기본값, 퍼블릭 액세스 기능은 예, 보안 그룹 새로 생성, 이름은 New-RDS-SG, 가용 영역 기본설정 없음, 포트는 3306으로 한다.
- 데이터베이스 인증에서 암호 인증, 추가 구성은 확인 후 [데이터베이스 생성]을 한다.
- 생성 됐다.
SQL 클라이언트 다운로드 및 DB 연결
- https://dev.mysql.com/downloads/workbench/ 에서 MySQL Workbench를 본인 PC의 플랫폼에 맞는 것으로 설치한다. 로그인은 하지 않아도 된다.
- 설치가 끝나면 실행한다. 그 후에 MySQL Connections옆에 +를 누른다.
- RDS 연결을 위해 IP가 필요하므로 만들어둔 DB를 클릭해서 엔드포인트를 복사한다.
- 복사해 온 엔드포인트를 Hostname에 넣고 Username과 Password는 아까 생성 시 사용한 마스터 이름과 암호를 입력하고 Test Connection을 한다.
- 연결 테스트를 끝내고 OK 눌러서 빠져나오면 생성된 것을 확인할 수 있다.
- 데이터베이스에 접속이 되었고 이제 테이블 생성, 데이터 삽입, 쿼리 입력을 수행할 수 있다.
- 삭제는 엔드포인트 복사해 온 페이지에서 할 수 있다.
- "인스턴스 삭제 시 시스템 스냅샷 및 특정 시점으로 복구를 포함한 자동화된 백업을 더이상 사용할 수 없다는 점을 인정합니다." 의 내용만 체크하고 "delete me"를 입력하고 삭제한다.
- 삭제가 진행 중이다.
웹서버에서 실행되는 PHP 애플리케이션에 MySQL 데이터베이스 연결하기
이전에 만든 인스턴스와 VPC를 이용해도 되고 새로 생성해도 된다.
18. RDS DB 인스턴스가 VPC에서 사용되기 위해서 서브넷 그룹을 생성하기 위해서 [VPC]페이지로 이동해서 [서브넷]에서 프라이빗 서브넷을 추가하기 위해 생성한다.
19. 사진과 같이 입력한다. VPC는 새로 생성한거나 이전에 사용한걸 써도된다. 입력을 다하고 생성한다.
20. EC2에서 보안그룹으로 가서 [보안 그룹 생성]을 진행한다.
21. 이런 식으로 내용들을 입력한다.
22. 바로 하나 더 생성한다. VPC는 같은 것, 인바운드 규칙에서 MYSQL유형으로 소스는 방금 만든 그룹ID를 입력해서 생성하면 된다.
23. RDS페이지로와서 서브넷 그룹 생성을 위해서 DB서브넷 그룹 생성을 한다.
24. 이름과 설명, vpc를 지정한다.
25. 서브넷 추가에서 가용 영역과 서브넷은 선택 가능한건 다하고 생성한다.
26. RDS에서 DB 인스턴스를 생성하는데 "표준 생성", "MySQL", 버전은 5.7.30, "프리티어"로 한다.
27. 설정에서는 사진처럼 입력해도되고 원하는 이름으로 입력해도 된다.
28. 연결에서는 vpc는 기존 vpc로 vpc 보안 그룹을 "기존 항목 선택"으로해서 보안 그룹은 만들어둔 db꺼만 추가한다.
29. 아래쪽에 추가 구성에서 이름만 지정해서 DB 인스턴스 생성을 마친다. 생성을 마치면 엔드포인트를 확인한다.
PHP가 포함된 Apache 웹 서버 설치
- Amazon Linux 2 AMI를 선택한다.
- 유형 "t2.micro"로 선택하고 다음:인스턴스 세부 정보 구성으로 넘어간다.
- vpc는 기존에 생성한 것을 서브넷은 퍼블릭 서브넷, 퍼블릭 IP 자동 할당으로하고 검토 및 시작으로 넘어가서 확인 후 시작한다.
- 생성하고 나서 생성한 인스턴스를 우클릭해서 네트워킹에 보안 그룹 변경을 누른다.
- 기존 보안 그룹을 냅두고 RDS-securitygroup 보안그룹을 추가하고 "보안 그룹 할당"을 눌러 나온다
- Putty로 접속을 한다.
- Yum을 업데이트 해준다.
sudo yum update -y
- sudo yum install -y httpd php php-mysqlnd 명령어로 PHP 소프트웨어 패키지가 포함된 Apache 웹 서버를 설치한다. 설치하고 나서 sudo service httpd start로 웹서버를 실행시킨다.
- 인스턴스에서 퍼블릭 DNS로 접속 시도했을 때 이 화면이 나오면 성공이다.
- putty로 접속한 인스턴스에서 sudo chkconfig httpd on 명령어를 입력해 재접시에도 httpd가 실행하게 만든다.
- 로그인 중인 ec2-uiser로 웹 서버의 기본 루트 페이지 파일을 수정 변경 가능하도록 설정하기 위해 /var/www/ 디렉터리의 소유권 및 권한을 변경해야한다. 다음의 명령을 사용해서 www라는 그룹을 추가하고 /var/www/에 대한 소유권과 권한을 부여한다.
sudo groupadd www
sudo usermod -a -G www ec2-user
이후 다시 접속해서 groups로 확인한다.
- sudo chown -R root:www /var/www 명령어로 /var/www/ 디렉터리 및 해당 콘텐츠의 그룹 소유권을 www그룹으로 변경한다.
- /var/www/ 및 그 하위 디렉터리의 권하을 변경해서 그룹 쓰기 권한을 추가하고, 나중에 생성될 하위 디렉터리에서 그룹 ID를 설정한다
sudo chmod 2775 /var/www
find /var/www -type d -exec sudo chmod 2775 {} +
- /var/www 및 하위 디렉터리의 파일 권한을 계속 변경해서 그룹 쓰기 권한을 추가한다.
find /var/www -type f -exec sudo chmod 0664 {}
RDS DB 인스턴스에 Apache 웹 서버 연결
- EC2 인스턴스에 계속 연결되어 있을 때 디렉터리를 /var/www 로 변경하고 inc라는 새로운 하위 디렉터리를 생성한다.
cd /var/www
mkdir inc
cd inc
- dbinfo.inc라는 inc 디렉터리에서 새 파일을 생성 후 편집기로 호출하여 파일을 편집한다.
sudo touch dbinfo.inc
sudo vim dbinfo.inc
- dbinfo.inc 파일에 추가한다. endpoint는 RDS MySQL DB 인스턴스의 엔드포인트, master password는 RDS MySQL DB 인스턴스의 마스터 암호이다.
<?php
define('DB_SEVER', 'db-instance.cisro564xznz.ap-northeast-2.rds.amazonaws.com');
define('DB_USEERNAME', 'user');
define('DB_PASSWORD', 'Master비밀번호');
defind('DB_DATABASE', 'sample');
?>
- 디렉터리를 /var/www/html로 이동한다.
cd /var/www/html
- SapmlePage.php라는 html 디렉터리에서 새 파일을 생성하고 편집기로 파일을 편집한다.
sudo touch SamplePage.php
sudo vim SamplePage.php
- 다음 내용을 추가한다.
<html>
<body>
<h1>Sample page</h1>
<?php
/* Connect to MySQL and select the database. */
$connection = mysqli_connect(DB_SERVER, DB_USERNAME, DB_PASSWORD);
if(mysqli_connect_errno()) echo "Failed to connect to MySQL: ".mysqli_connect_error();
$database = mysqli=select_db($connection, DB_DATABASE);
/* Ensure that the Employees table exists. */
VerifyEmployeesTable($connection, DB_DATABASE);
/* if input fields are populated, add a row to the Employees table.*/
$employee_name = htmlentities($_POST['Name']);
$employee_address = htmlentities($_POST['Address']);
if(strlen($employee_name) || strlen($employee_address)) {
AddEmployee($connection, $employee_name, $employee_address);
}
?>
<form action="<?PHP echo $_SERVER['SCRIPT_NAME'] ?>" method="POST">
<table border="0">
<tr>
<td>Name</td>
</tr>
<tr>
<td>
<input type="text" name="Name" maxlength="45" size="30" />
</td>
<td>
<input type="submit" value="Add Data" />
</td>
</tr>
</table>
</form>
<table border="1" cellpadding="2" cellspacing="2">
<tr>
<td>ID</td>
<td>Name</td>
<td>Address</td>
</tr>
<?php
$result = mysqli_query($connection, "SELECT * FROM Employees");
while($query_data = mysqli_fetch_row($result)) {
echo "<tr>";
echo "<td>",$query_data[0], "</td>",
"<td>",$query_data[1], "</td>",
"<td>",$query_data[2], "</td>";
echo "</tr>"
}
?>
</table>
<?php
mysqli_free_result($result);
mysqli_close($connection);
?>
</body>
</html>
<?php
/* Add an employee to the table. */
function AddEmployee($connection, $name, $address) {
$n = mysqli_real_escape_string($connection, $name);
$a = mysqli_real_escape_string($connection, $address);
$query = "INSERT INTO `Employees`(`Name`, `Address`) VALUES('$n', '$a');";
if(!mysqli_query($connection, $query)) echo("<p>Error adding employee data.</p>");
}
/* Check whether the table exists and, if not, create it. */
function VerifyEmployeesTable($connection, $dbName) {
if(!TableExists("Employees", $connectio, $dbName))
{
$query = "CREATE TABLE `Employees`(`ID` int(11) NOT NULL AUTO_INCREMENT, `Name` varchar(45) DEFAULT NULL, `Address` varchar(90) DEFAULT NULL, PRIMARY KEY(`ID`), UNIQUE KEY `ID_UNIQUE`(`ID`)) ENGINE=InnoDB AUTO_INCREMENT=1 DEFAULT CHARSET=latin1";
if(!mysqli_query($connection, $query)) echo("<p>Error creating table.</p>");
}
}
/* Check for the existence of a table. */
function TableExists($tableName, $connection, $dbName) {
$t = mysqli_real_escape_string($connection, $tableName);
$d = mysqli_real_escape_string($connection, $dbName);
$checktable = mysqli_query($connection, "SELECT TABLE_NAME FROM information_schema.TABLES WHERE TABLE_NAME = '$t' AND TABLE_SCHEMA = '$d'");
if(mysqli_num_rows($checktable) > 0) return true;
return false;
}
?>```