여기서 다루는 내용
· 서비스 간단 소개
· 설치 및 실행
· 일관성 테스트
· 마무리
이번 시간에는 Galera cluster(Mysql 5.6)를 구성하여 도쿄, 버지나아 리전에 위치한 2개의 노드에서 멀티 마스터를 구성하는 작업을 하고, 인증 복제 방식으로 일관성이 유지되는 부분을 간단하게 확인해 보겠습니다.
서비스 간단 소개
- Galera cluster
- 오픈소스
- 동기 방식의 복제 구조 (인증 기반 복제 시스템)
- MariaDB, Mysql 지원
- 세부 정보 : Link
클러스터 설치 및 구성
:: 설치 환경
Region : tokyo, virginia
Instance info : r4.xlarge (vCPU 4, Memory 30.5 GB, EBS gp2 100GB, Up to 10 Gigabit, Amazon Linux AMI)
Network : vpc peering [ tokyo (10.0.2.0/24) <-> virginia[172.31.0.0/16) ]
:: VPC peering 구성
도쿄와 버지니아간 VPC peering 구성을 진행합니다.
tokyo (10.0.2.0/24) <-> virginia (172.31.0.0/16)
※ 참고
VPC peering 구성 관련 자세한 내용은 여기 참고 하면 됩니다.
:: Security group 생성
아래 이미지와 같이 TCP 3306, 4444, 4568, 4567 port를 오픈합니다.
:: 클러스터 설치
- 인스턴스 생성
- 도쿄
- 버지니아
- 도쿄
- yum repository 설정
- sudo vim /etc/yum.repos.d/galera.repo <- galera.repo 파일 생성
[galera]
name = Galera
baseurl = http://releases.galeracluster.com/galera-3/centos/6/x86_64
gpgkey = http://releases.galeracluster.com/GPG-KEY-galeracluster.com
gpgcheck = 1
[mysql-wsrep]
name = MySQL-wsrep
baseurl = http://releases.galeracluster.com/mysql-wsrep-5.6/centos/6/x86_64/
gpgkey = http://releases.galeracluster.com/GPG-KEY-galeracluster.com
gpgcheck = 1
- sudo vim /etc/yum.repos.d/galera.repo <- galera.repo 파일 생성
- 각 인스턴스 별 galera cluster for mysql 설치 (AMI 생성을 통한 복제 구성 권장)
- sudo yum install galera-3 mysql-wsrep-5.6 <- galera for mysql binary 설치
- sudo vim /etc/my.cnf <- mysql 설정 파일 생성 (설정 관련 시스템 설정 , 복제 설정 참고)
[mysqld]
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
user=mysql
binlog_format=ROW
bind-address=0.0.0.0
default_storage_engine=innodb
innodb_autoinc_lock_mode=2
innodb_flush_log_at_trx_commit=0
innodb_buffer_pool_size=122M
wsrep_provider=/usr/lib64/galera-3/libgalera_smm.so
wsrep_on = ON
wsrep_cluster_name=DBCLUSTER <- 클러스터 명
wsrep_cluster_address="gcomm://10.0.2.5,172.31.17.86" <- 클러스터 구성 노드들 IP 주소
wsrep_sst_method=rsync
wsrep_node_address=172.31.17.86 <- 현재 노드 IP 주소
wsrep_node_name=MyNode1 <- 노드 명
wsrep_debug=ON <- 디버깅 로그 설정
wsrep_log_conflicts=ON <- 충돌 로그 설정
- sudo mysql_install_db <- MySQL 데이터 디렉토리 초기화
- sudo yum install perl-Data-Dumper.x86_64 <- mysql_install_db 실행시 Perl data dumper 를 필요로 하는 경우 설치
:: 클러스터 구성
- Virginia server 실행
- sudo service mysql start --wsrep-debug --wsrep_cluster_address=gcomm://
- Tokyo server 실행
- sudo service mysql start --wsrep-debug --wsrep_cluster_address=gcomm://172.31.17.86 <- 도쿄 노드의 IP와 연결
- 클러스터 구성 확인
- Tokyo server 확인
- [ec2-user@ip-10-0-2-5 ~]$ mysql -u root
mysql> show status like 'wsrep_%';
+------------------------------+--------------------------------------+
| Variable_name | Value |
+------------------------------+--------------------------------------+
...
| wsrep_local_state_comment | Synced |
...
| wsrep_incoming_addresses | 172.31.17.86:3306,10.0.2.5:3306 |
...
| wsrep_cluster_conf_id | 3 |
| wsrep_cluster_size | 2 |
| wsrep_cluster_state_uuid | f78c7f7f-3d29-11e8-8fb9-26c97c7b26c2 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
...
| wsrep_provider_name | Galera |
...
| wsrep_ready | ON |
+------------------------------+--------------------------------------+
57 rows in set (0.00 sec)
mysql>
- Virginia server 확인
- [ec2-user@ip-172-31-17-86 ~]$ mysql -u root
mysql> show status like 'wsrep_%';
+------------------------------+--------------------------------------+
| Variable_name | Value |
+------------------------------+--------------------------------------+
...
| wsrep_local_state_comment | Synced |
...
| wsrep_incoming_addresses | 172.31.17.86:3306,10.0.2.5:3306 |
...
| wsrep_cluster_conf_id | 3 |
| wsrep_cluster_size | 2 |
| wsrep_cluster_state_uuid | f78c7f7f-3d29-11e8-8fb9-26c97c7b26c2 |
| wsrep_cluster_status | Primary |
| wsrep_connected | ON |
...
| wsrep_provider_name | Galera |
...
| wsrep_ready | ON |
+------------------------------+--------------------------------------+
57 rows in set (0.00 sec)
mysql>
- Tokyo server 확인
일관성 테스트
Galera cluster는 아래 이미지와 같이 인증 프로세스를 실행하여 글로벌 일관성을 유지시켜 줍니다.
즉, 인증 테스트가 성공하면 트랜잭션이 commit되고 쓰기 세트가 나머지 클러스터에 적용되고, 인증 테스트가 실패하면 노드는 쓰기 세트를 삭제하고 클러스터는 원래 트랜잭션을 rollback 합니다.
임의의 테이블에 데이터가 있는 상태에서 각 노드에서 동일 테이블에 트랜잭션을 생성하여 select, delete 하고 commit을 수행하여 한쪽에서는 commit성공을 하고, 다른 한쪽에서는 rollback되어 deadlock이 발생되는 부분을 확인해 보겠습니다.
① Virginia server
mysql> START TRANSACTION; <- 트랜잭션 시작
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM sbtest1 WHERE id = 11;
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k | c | pad |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| 11 | 500585 | 37216201353-39109531021-11197415756-87798784755-02463049870-83329763120-57551308766-61100580113-80090253566-30971527105 | 05161542529-00085727016-35134775864-52531204064-98744439797 |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> DELETE FROM sbtest1 WHERE id = 11;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM sbtest1 WHERE id = 11;
Empty set (0.00 sec)
mysql> SELECT * FROM sbtest1 WHERE id = 13;
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k | c | pad |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| 13 | 501371 | 33071042495-29920376648-91343430102-79082003121-73317691963-02846712788-88069761578-14885283975-44409837760-90760298045 | 91798303270-64988107984-08161247972-12116454627-22996445111 |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> DELETE FROM sbtest1 WHERE id = 13; <-id 13 데이터 삭제
Query OK, 1 row affected (0.00 sec)
② Tokyo server
mysql> START TRANSACTION; <- 트랜잭션 시작
Query OK, 0 rows affected (0.00 sec)
mysql> SELECT * FROM sbtest1 WHERE id = 11;
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k | c | pad |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| 11 | 500585 | 37216201353-39109531021-11197415756-87798784755-02463049870-83329763120-57551308766-61100580113-80090253566-30971527105 | 05161542529-00085727016-35134775864-52531204064-98744439797 |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> DELETE FROM sbtest1 WHERE id = 11;
Query OK, 1 row affected (0.00 sec)
mysql> SELECT * FROM sbtest1 WHERE id = 11;
Empty set (0.00 sec)
mysql> COMMIT;
Query OK, 0 rows affected (0.17 sec) <- commit 성공
mysql>
③ Virginia server
mysql> COMMIT;
ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction <- 도쿄 노드에서 먼저 commit 하였기 때문에 commit 실패
mysql> SELECT * FROM sbtest1 WHERE id = 13; <- rollback 되었기 때문에 id 13 데이터 확인 가능
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| id | k | c | pad |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
| 13 | 501371 | 33071042495-29920376648-91343430102-79082003121-73317691963-02846712788-88069761578-14885283975-44409837760-90760298045 | 91798303270-64988107984-08161247972-12116454627-22996445111 |
+----+--------+-------------------------------------------------------------------------------------------------------------------------+-------------------------------------------------------------+
1 row in set (0.00 sec)
mysql>
:: Deadlock 로그 확인
클러스터 노드 실행시 --wsrep-debug 옵션으로 실행하면 err 로그 파일에 트랜잭션 실패 로그도 같이 저장됩니다.
위에서 발생한 deadlock 에러를 로그 파일에서 확인해보면 아래와 같은 로그를 확인 가능합니다.
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
2018-04-23 08:40:28 15542 [Note] WSREP: cleanup transaction for LOCAL_STATE: START TRANSACTION
*** Priority TRANSACTION:
TRANSACTION 575931, ACTIVE 0 sec starting index read
mysql tables in use 1, locked 1
MySQL thread id 2, OS thread handle 0x7ff0156ed700, query id 4501 System lock
*** Victim TRANSACTION:
TRANSACTION 575930, ACTIVE 28 sec
, undo log entries 1
MySQL thread id 4, OS thread handle 0x7ff0141f3700, query id 4499 localhost root
*** WAITING FOR THIS LOCK TO BE GRANTED:
RECORD LOCKS space id 133 page no 4 n bits 144 index `PRIMARY` of table `sysbench`.`sbtest1` trx id 575930 lock_mode X locks rec but not gap
Record lock, heap no 6 PHYSICAL RECORD: n_fields 6; compact format; info bits 32
0: len 4; hex 80000009; asc ;;
1: len 6; hex 00000008c9ba; asc ;;
2: len 7; hex 670000057019e4; asc g p ;;
3: len 4; hex 8007a065; asc e;;
4: len 30; hex 34343235373437303830362d31373936373030373135322d333238303936; asc 44257470806-17967007152-328096; (total 120 bytes);
5: len 30; hex 33343535313735303439322d36373939303339393335302d383131373932; asc 34551750492-67990399350-811792; (total 60 bytes);
2018-04-23 08:40:59 15542 [Note] WSREP: cluster conflict due to high priority abort for threads:
2018-04-23 08:40:59 15542 [Note] WSREP: Winning thread:
THD: 2, mode: applier, state: executing, conflict: no conflict, seqno: 259056
SQL: (null)
2018-04-23 08:40:59 15542 [Note] WSREP: Victim thread:
THD: 4, mode: local, state: idle, conflict: no conflict, seqno: -1
SQL: (null)
2018-04-23 08:40:59 15542 [Note] WSREP: BF kill (1, seqno: 259056), victim: (4) trx: 575930
2018-04-23 08:40:59 15542 [Note] WSREP: Aborting query: void conf 0 trx: 575930
2018-04-23 08:40:59 15542 [Note] WSREP: kill IDLE for 575930
2018-04-23 08:40:59 15542 [Note] WSREP: enqueuing trx abort for (4)
2018-04-23 08:40:59 15542 [Note] WSREP: signaling aborter
2018-04-23 08:40:59 15542 [Note] WSREP: WSREP rollback thread wakes for signal
2018-04-23 08:40:59 15542 [Note] WSREP: client rollback due to BF abort for (4 4499), query: (null)
2018-04-23 08:40:59 15542 [Note] WSREP: WSREP rollbacker aborted thd: (4 140669128730368)
2018-04-23 08:41:01 15542 [Note] WSREP: Deadlock error for: (null)
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------
마무리
Galera cluster를 구성하여 동기 방식의 Multi master가 가능하지만 노드의 수가 증가하면 트랜잭션 응답 시간 증가와 충돌 및 교착 상태 발생 확률이 높아질 것으로 예상되기 때문에 감안해야 될 것 같습니다.
이상 Galera cluster mysql 5.6버전을 설치 및 클러스터 구성을 하고 간단하게 일관성을 확인해보는 시간을 마무리합니다.