Replication이란
백업과 성능향상을 위해서 데이터베이스를 여러대의 서버에 복제하는 행위를 Replication이라고 한다. Replication에 대한 자세한 내용은 생활코딩 Mysql 고급편의 리플리케이션 수업을 참고한다.
Master와 Slave
원본 데이터가 위치하는 서버를 마스터라고 하고 그 원본을 복제한 서버를 슬레이브라고 한다.
마스터와 슬레이브를 구분할 때는 읽기와 쓰기를 이용한다. 데이터베이스의 작업은 읽기와 쓰기로 구분할 수 있다. SQL로 말하자면 읽기는 SELECT 구문이고, 쓰기는 INSERT, UPDATE, DELETE 이다. 그런데 쓰기 작업은 저장된 데이터가 변경되기 때문에 복제된 서버들 간에 동일한 형태를 유지하는 것이 어렵다. 그래서 보통 한대의 서버에만 쓰기 작업을 하고, 그 서버의 데이터를 복제해서 여러대의 슬레이브 서버를 만든 후에 슬레이브에서는 읽기 작업만을 수행한다.
read replica란 바로 이런 작업을 RDS에서 할 수 있도록 해주는 서비스다.
Read Replica
read replica를 하는 방법은 간단하다. db 인스턴스를 선택하고 read replica 명령을 실행하면 된다. 그럼 기존의 db 인스턴스를 마스터가 되고, 생성된 인스턴스는 슬레이브가 된다.
Read Replica의 사용
read replica를 사용하기 위해서는 에플리케이션의 로직을 수정해야 한다. 본문이나 글목록을 표시하는 부분에서는 슬레이브 서버의 자원을 사용하고, 글 작성 등에서는 마스터 서버를 사용하면 된다.
예제
이번 수업에서는 read replica를 생성하고, RDS와 웹서비스에서 진행한 예제에 글 작성 기능을 추가할 것이다. 작성된 글을 DB에 삽입 할 때는 마스터 서버를 사용하고, 글의 목록을 읽어올 때는 슬레이브를 읽어올 것이다. 아래는 예제의 전체코드다.
Master DB Instance
- End point : rds.master.ap-northeast-1.rds.amazonaws.com
- Master username : egoing
- Password : 22222222
Slave DB Instance
- End point : rds.slave.ap-northeast-1.rds.amazonaws.com
- Master username : egoing
- Password : 22222222
write.php
글을 작성하는 페이지로 사용자가 전송 버튼을 눌렀을 때 write_process.php로 사용자가 입력한 데이터를 전송해주는 역할을 한다.
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> </head> <body> <a href="write_process.php">리스트</a> <form action="write_process.php" method="get"> <p> <label>제목</label> <input type="text" name="title" /> </p> <p> <label>본문</label> <textarea name="description"> </textarea> </p> <p> <input type="submit" /> </p> </form> </body> </html>
write_process.php
write.php가 전송한 데이터를 받아서 Master 인스턴스에 추가한다.
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" > </head> <body> <a href="list.php">리스트</a> <a href="write.php">쓰기</a> <?php mysql_connect('rds.master.ap-northeast-1.rds.amazonaws.com','egoing','22222222'); mysql_select_db('opentutorials'); mysql_query("set session character_set_connection=utf8;"); mysql_query("set session character_set_results=utf8;"); mysql_query("set session character_set_client=utf8;"); $sql = " INSERT INTO topic (title, description, created) VALUES( '".mysql_real_escape_string($_GET['title'])."', '".mysql_real_escape_string($_GET['description'])."', NOW() )"; mysql_query($sql); ?> <div>등록했습니다</div> </body> </html>
list.php
글 목록을 보여주는 부분은 읽기작업이기 때문에 Slave DB 인스턴스를 사용한다.
<html> <head> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" > </head> <body> <a href="write.php">쓰기</a> <ul> <?php mysql_connect('rdsreplica1.cfiilfqyvjxr.ap-northeast-1.rds.amazonaws.com','egoing','22222222'); mysql_select_db('opentutorials'); mysql_query("set session character_set_connection=utf8;"); mysql_query("set session character_set_results=utf8;"); mysql_query("set session character_set_client=utf8;"); $sql = "SELECT * FROM topic"; $result = mysql_query($sql); while($row=mysql_fetch_assoc($result)){ echo "<li>".$row['title']."</li>"; } ?> </ul> </body> </html>