MariaDB의 Storage 엔진 중 하나인 myrocks 는 페이스북에서 개발한 엔진 이다.


개념 정리 및 테스트를 하고 싶어서 작년에 잠깐 진행하다가 중단된 이후 지난주부터 다시 진행 중이다.


여러 테스트 이전에 개념 정리가 중요한데,

아직 정리를 진행중이며, 공유를 하기에도 민망할 정도로 정리가 안되어 일단은 간단 sysbench 테스트 정도 진행한거 공유하려고 한다.


공유에 앞서 myrocks의 경우 기존 innodb의 B Tree 방식이 아닌 LSM-tree 기반 INDEX를 사용한다.


추후 mongo DB도 진행 예정이지만 이때도 페이스북에서 개발한 rocks engine?을 설치해서 테스트 예정이다.


mryocks는 아무래도 INSERT 와 SELECT 에 초점을 맞춘? storage engine 이기에 간단하게 INSERT 테스트를 먼저 진행해 보았다.


참고로 myrocks 는 아래와 같이 확인 할 수 있다.

(Engine : ROCKSDB / Index : LSMTREE)



당연 동일 DB에 sysbench를 이용하여 INSERT를 진행 하였다.


--innodb

sysbench --test=/usr/share/sysbench/tests/include/oltp_legacy/insert.lua --threads=8 --mysql-host=192.168.56.101 --mysql-user=root --mysql-port='8001' --mysql-table-engine=innodb --db-driver=mysql --oltp-table-size=10000000 --oltp-test-mode=complex --events=10000 --oltp-read-only=off  --db-ps-mode=disable  run;


--rocksdb

sysbench --test=/usr/share/sysbench/tests/include/oltp_legacy/insert.lua --threads=8 --mysql-host=192.168.56.101 --mysql-user=root   --mysql-port='8001' --mysql-table-engine=rocksdb --db-driver=mysql  --mysql-db=sbtest_rocksdb --oltp-table-size=10000000  --oltp-test-mode=complex --events=10000  --oltp-read-only=off  --db-ps-mode=disable  run;



결과는 아래와 같다


1. innodb



2. myrocks



Conclusion


- time 은 innodb가 myrocks 보다 적게 소요

- transaction 처리량 또한 innodb(2420건) myrocks (935건)으로 더 높은 처리량



* 추가 20초 동안 INSERT 진행

1. innodb

# sysbench --test=/usr/share/sysbench/tests/include/oltp_legacy/insert.lua --threads=8 --mysql-host=192.168.56.101 --mysql-user=root --mysql-port='8001' --mysql-table-engine=innodb --db-driver=mysql --max-requests=0 --max-time=20 --oltp-test-mode=complex --oltp-read-only=off  --db-ps-mode=disable  run;


2. myrocks

# sysbench --test=/usr/share/sysbench/tests/include/oltp_legacy/insert.lua --threads=8 --mysql-host=192.168.56.101 --mysql-user=root   --mysql-port='8001' --mysql-table-engine=rocksdb --db-driver=mysql  --mysql-db=sbtest_rocksdb --max-requests=0 --max-time=20 --oltp-test-mode=complex --oltp-read-only=off  --db-ps-mode=disable  run;



1. innodb 결과

\


2. myrocks 결과


- 하아..myrocks에 대해 기대한 만큼 뭔가가 아쉽다. 물론 내가 잘못 테스트 할 수 있기 때문에 그냥 참고 자료로 활용하려고 한다...ㅠ

반응형

mysqldump로 백업을 진행하다 보니 테스트 기회가 생겨 테스트를 진행해 보았다.


sql파일을 바로 Import 진행하니 중간에 세션이 끊기거나 한다면 ㅊㅓ음부터 다시 진행해야하는 불상사가 발생해서.

검색 도중 innodb를 myisam으로 변경 후 진행하는 방식을 추천해 주어 진행해 보았다.


기본 테스트 테이블의 정보는 아래와 같다.


2번째 테이블이 대상이고 빈 테이블에 myisam으로 변경 후



68,769,549 건을 진행했다.



시간을 보면 알 수 있듯이

대략 7시간 정도 소요 되었다.

(메모리는 32G 기준 )


참고로, 동일 테이블에 동일 방식으로 innodb를 진행하였을 경우 10시간 이상 진행해도 끝나지 않았다.


이렇게 되면 MyISAM 으로 변경 후 진행해야 되는 걸까??

이 부분에 대해서 추가 작업이 있음을 인지하고 있어야 한다.


해당 테이블을 MyISAM 에서 InnoDB로 Storage 엔진을 또 변경해야 된다는 것이다.

데이터가 없을 때에는 바로 변경이 된다.


하지만 데이터가 있을 경우 temp 테이블에 추가하였다가 진행해야 되기에 시간이 만만치 않게 소요 된다.



아쉽게도 정확한 측정을 못했지만 대략 4시간 정도 소요 되었다.


약 7억건의 데이터를 옮기는데 이정도 소요된다.


다시 한번 21건에 대해서 진행 중인데, 정확한 수치를 알고 있어야 될 듯 싶으며,

이번 기회를 통해 백업 방식을 xtrabackup으로 테스트 및 변경을 고려 해 봐야 할 듯 싶다.


반응형

MariaDB로 누가 접속 했는지 어떠한 행동을 했는지 확인을 위해서 Audit를 테스트 진행해 보았다.


진행 방식은 다음과 같다.


1. 지속적으로 로그인 성공 및 시간 조회 / 로그인 암호 실패 

2. 지속적으로 Sysbench를 이용하여 10000000 건의 테이블에 대해 select 진행 

3. 이 부분에 대해 cpu / Disk IO / QPS 등을 체크


처음에는 이와 같은 방식으로 지속적으로 체크를 한다.


이후 Audit을 on으로 한 이후에 (로그를 남김) 해당 부하들의 변화률을 체크 하기로 하자.




참고로 Audit 은 아래 블로그를 참고해서 플러그인을 설치하자. 

직접 올려도 되지만 더 자세하게 잘 알려준 블로그가 오히려 좋을 듯 싶다.



1. 지속적으로 로그인 아웃을 하는 스크립트는 파이썬을 이용했다. Thread를 이용하면 좋겠지만...간단하게 개발하기 위해서..내 실력이 안되기에..ㅠ


#-*- coding:utf-8 -*-

import pymysql
import time

def LoginSucess(tp=''):
db = pymysql.connect(host='192.168.0.1', port=int(3306), user='root', passwd='root', db='mysql',
autocommit=True, use_unicode=True, charset="utf8")
if tp.lower() == 'dict':
cursor = db.cursor(pymysql.cursors.DictCursor)
else:
cursor = db.cursor()
query = """
SELECT now();
"""
cursor.execute(query)
row = cursor.fetchone()
print(row)

def LoginFail(tp =''):
try:
db = pymysql.connect(host='192.168.0.1', port=int(3306), user='root', passwd='1234', db='mysql',
autocommit=True, use_unicode=True, charset="utf8")
if tp.lower() == 'dict':
cursor = db.cursor(pymysql.cursors.DictCursor)
else:
cursor = db.cursor()

except Exception as e:
print(str(e))


if __name__ == "__main__" :
while True :
LoginSucess()
LoginFail()
time.sleep(1)


- 여기서는 지속적으로 돌면서 로그인 아웃을 시도한다....mysql close하는 부분이 없네.......OTL


2. Sysbench를 이용해서 다른 서버에서 해당 서버로 스트레스 테스트를 진행하는 것이다.


- 데이터 추가를 먼저 진행하자
sysbench --test=/usr/local/Cellar/sysbench/1.0.6/share/sysbench/tests/include/oltp_legacy/oltp_simple.lua --num-threads=8 \
--mysql-host=db1 --mysql-user=root --mysql-password='root' \
--mysql-table-engine=innodb --db-driver=mysql \
--mysql-engine-trx=yes \
--oltp-table-size=10000000 \
--oltp-test-mode=complex --max-requests=10000 \
--oltp-read-only=off \
prepare

- 데이터 실행 (while문으로 계속 실행)

while true; do
sysbench --test=/usr/local/Cellar/sysbench/1.0.6/share/sysbench/tests/include/oltp_legacy/oltp_simple.lua --num-threads=8 \
--mysql-host=db1 --mysql-user=root --mysql-password='root' \
--mysql-table-engine=innodb --db-driver=mysql \
--mysql-engine-trx=yes \
--oltp-table-size=10000000 \
--oltp-test-mode=complex --max-requests=10000 \
--max-time=4 \
--oltp-read-only=off \
--db-ps-mode=disable \
run
sleep 1

done


주석을 달아 놨듯이.. 처음에는 10,000,000 건을 Insert 이후에 해당 건을 while문이 돌면서 지속적으로 스트레스를 주는 것이다.


왜 while로 했냐면 해당 가상 머신 사양이 좋지 않아 CPU를 100%로 만들지 않으면서도 지속적인 스트레스를 주기 위함이다..

CPU를 100%하면 이후에 어떠한 반응도 체크를 하기 힘들기에 나는 적정선이 70%내를 유지하기 위함이다.


이렇게 한 후 이제 CPU와 QPS등을 체크를 해보자.

체크하는 것은 또한 Python을 이용하였다.



보는 바와 같이 QPS / CPU 등이 일정한 것을 확인할 수 있다...아쉬운 건 Disk I/O를 발생시키지 못한 점이다...


이제는 Audit을 ON으로 한 후 다시 진행 해 보자.


Audit을 제대로 설치 하였다면 아래와 같이 진행할 수 있다.


MariaDB [(none)]> show global status like 'server_audit%';

MariaDB [(none)]> set global server_audit_logging = on;


정상적으로 로그가 남기고 있는지 확인해 보자


따로 경로를 설정하지 않았다면, Data폴더에 가면 확인할 수 있다.

Data폴더에서는 일정 크기의 로그가 쌓이면 자동 백업을 진행하게 된다.

아래 일부를 캡쳐했는데, 유저 / 어디서 들어오는지..쿼리는 어떤것을 남기는지 확인할 수 있다.


여기까지 진행하고 DB / OS 상황을 보자.


별다른 특이 사항은 없어 보인다.


이제는 위와 같은 방법으로 로그인 성공 / 실패 를 하는 스크립트를 실행하고, 추가로 스트레스 테스트도 진행하자.

이렇게 어느정도의 스트레스가 완료 되었다면 둘을 비교해 보자.


비교는 ipython Jupyter를 이용하였다. 추가로 matplotlib을 이용하여 둘의 결과를 그래프로 표현해 보았다.


파란색 선이 Audit 을 Off로 한 후에 진행한 그래프이며, 녹색 선이 Audit 을 On 으로 한 후 진행 하였다.

결과를 보면 큰 차이가 없는 것을 확인할 수 있다.





간단한 결과만 보고 Audit을 On으로 한다고 부하가 발생ㅎㅏ지 않는다고 단정할 수 없다.

8 쓰레드로 진행하였으며(sysbench에서 8쓰레드로 명시했지만 제대로 됬는지는 확인을 못했다..), session도 30 내외로 진행하였기 때문에 더더욱 실제 운영에는 적용할 수 없다.


하지만 간단하게 테스트한 부분이기에 이 부분을 조금 더 보완하여 진행 한다면 분명 좋은 결과를 도출해 낼 수 있을 것이다.

반응형

Galera Cluster에서 auto increment  컬럼에 따로 값을 지정하지 않으면 해당 노드들끼리 중복이 생겨 정합성이 깨지는 경우가 생길 수 있다.

그래서 옵션에서 중복허용되지 않게 하기 위해 증가되는 값을 설정함으로써 중복을 방지한다.


예를들어 2개의 노드라고 한다면 1번 노드에서는 1,3,5,7,9로 증가하고 2번 노드에서는 2,4,6,8,10 이런식으로 증가한다.


해당 부분을 테스트하여 공유 및 이에 대한 자세한 내용도 첨부해 본다.


* 해당 서버는 노드수가 5개라 현재 5로 되어 있는 것을 확인할 수 있다


- 1번 노드에서  Insert 진행



- 3번 노드에서 insert 진행


노란색을 보면 28까지는 5씩 증가 했지만 a3 에서 넣는 순간 부터는 29에서 진행 후 다시 5씩 증가하는 것을 확인 가능하다.

 


좀더 자세한 내용은 아래 확인하면 될 듯 싶다.





[출처] http://h391106.tistory.com/323


1.    
MariaDB Galera Cluster Variables

wsrep_auto_increment_control

wsrep_causal_reads

wsrep_certify_nonPK

wsrep_cluster_address

wsrep_cluster_name

wsrep_convert_LOCK_to_trx

 

이 문서는 위 Variables 에 대해 다루고 있다.


테스트에 사용한 MariaDB  5.5.39 이며, wsrep_provider_version 은 내장되어 있던 25.3.5(r178) 를 사용하였다.

문서에서 언급 한 각 Variables  default, Introduced, deprecated 의 정보는 8.A 를 확인한 내용이며이는 wsrep API patch v0.8 를 기준으로 한다.

 

2.    wsrep_auto_increment_control

 

Default = on

Introduced = 1

 

Cluster membership 에 변화가 있을 때

auto_increment_increment  auto_increment_offset system variables 을 자동으로 조정한다.

 

Cluster Membership 의 변화란 클러스터를 구성하는 노드에 변화가 있어 클러스터 사이즈가 커지거나 작아지는 경우를 말한다.

 

계획 된 작업으로 신규 노드를 추가하는 일도장애가 발생해 노드가 클러스터 구성에서 빠지는 일도 Cluster Membership 의 변화이다.

 

wsrep_auto_increment_control = on 사용으로 INSERT 구문으로 인한 충돌을 줄여준다고 한다.

 

여기서 말하는 충돌은 MariaDB  Duplicate entry 에러를 의미하며, pk  auto_increment 를 사용하는 경우를 말한다.

 

auto_increment_increment

 

Default = (wsrep_cluster_size)

 

auto_increment_offset

 

Default = (Cluster 를 구성하는 노드 1, 2, 3, … 순차적으로 값을 가져간다.)

 

위의 두 파라미터는 Galera cluster 이전에도 존재하던 Variables 이다.

특히 매뉴얼을 보면 MASTER  TO MASTER Replication (DUAL MASTER) 셋팅에서 사용한다고 한다.

 

3 node Galera Cluster 를 구성하면 다음과 같이 System Variable 값을 가져간다. ( wsrep_auto_increment_control = on )

 

전 노드 공통으로 auto_increment_increment = 3

각 노드는 auto_increment_offset = [1|2|3]

 

auto_increment_offset 의 값이 auto_increment_increment 의 값보다 큰 경우 auto_increment_offset 의 값은 무시되며,

이외의 경우 auto_increment 의 기대되는 값은 다음의 공식을 따른다.

 

(현재의 auto_increment 보다 큰 가장 작은 값 ) = auto_increment_offset + N * auto_increment_increment

 

wsrep_auto_increment_control = on 을 사용하는 3 NODE CLUSTER 에서 A 라는 테이블이 AUTO_INCREMENT 를 사용하는 B 라는 컬럼을 가진다고 가정하자.

테이블의 B 컬럼의 AUTO_INCREMENT 로 할당 된 가장 큰 값이 20 이라고 할 때 기대되는 다음 AUTO_INCREMENT 는 다음과 같다.

 

auto_increment_increment = 3

auto_increment_offset = 1

ð  22

 

auto_increment_increment = 3

auto_increment_offset = 2

ð  23

 

auto_increment_increment = 3

auto_increment_offset = 3

ð  24

 

결과적으로 auto_increment_offset = on 의 사용으로 AUTO_INCREMENT  PKEY 로 사용하는 경우에 대해

INSERT  DUPLICATE ENTRY 에러를 줄일 수 있다.

 

3.    wsrep_causal_reads

 

Default = off

Introduced = 1

Deprecated = 3.6

 

이 기능은 3.6 에서 deprecated 되었으며, wsrep_sync_wait 로 대체되었다.

 

wsrep_sync_wait

 

Introduced = 3.6

 

아래 값을 지정하면 해당하는 오퍼레이션을 수행하기 전에 동기화 된 읽기 view 를 보장한다.

 

 SELECT, SHOW, BEGIN / START TRANSACTION 을 포함한 READ Statement 를 검사

 UPDATE, DELETE statements 를 검사

 1, 2 를 포함한다.

 INSERT, REPLACE statement 를 검사

 

4.    wsrep_certify_nonPK

 

Default = on

Introduced = 1

 

wsrep_certify_nonPK = on 인 경우 PK 없는 테이블에 대해 DML 을 허용한다.

 

(내부적으로 pk 를 생성하는 듯 함 – 확인할 것…)

 

wsrep_certify_nonPK = off 인 경우 PK 없는 테이블에 DML 을 사용하는 경우 다음과 같은 에러가 발생한다.

 

ERROR 1213 (40001): Deadlock found when trying to get lock; try restarting transaction

 

5.    wsrep_cluster_address

 

Cluster Membership 을 구성하는데 사용되는 System Variable 이다.

 

클러스터의 최초 노드를 구성하는 경우 gcomm:// 셋팅으로 startup 한다.

이 의미는 다른 클러스터 노드에 접속하지 않는다란 뜻이다.

 

이후 해당 vriable 을 클러스터를 구성하는 전 노드로 업데이트 한다.

 

A, B, C 라는 3개의 Address 가 있다고 하면 gcomm:// 셋팅으로 인스턴스를 시작한 이후,

gcomm://A,B,C 로 변경한다.

 

사실 위 과정 없이도 Joiner 노드의 올바른 wsrep_cluster_name 구성과 wsrep_cluster_address 구성이 있다면

startup 하는데 문제가 없다.

 

6.    wsrep_cluster_name

 

Default = my_wsrep_cluster

Introduced = 1

 

Logical  Cluster name 을 지정한다.

Cluster name 이 다르면 Cluster Membership 참가가 실패한다.

 

이를 테면 Donor node 에서는 다음과 같은 에러가 발생하다 Joiner node 프로세스가 죽는다.

 

[Note] WSREP: handshake failed, my group: 'mariatest', peer group: 'my_wsrep_cluster'

 

 Variable 셋팅으로 하나의 장비에 여러 서비스 목적의 Cluster 를 구성하는 경우나,

wsrep_cluster_address 를 실수로 잘못 지정한 경우에 데이터를 보호할 수 있다.

 

7.    wsrep_convert_LOCK_to_trx

 

Default = off

Introduced = 1

 

LOCK / UNLOCK TABLES  BEGIN / COMMIT statements 로 바꿔준다.

암묵적으로 locking sessions  transactions 을 사용하도록 변환한다.

 

이 옵션이 off 인 상태에서는

 

NODE #1 – lock table test [ read | write ]

NODE #1  Insert : Waiting

NODE #2  No Waiting

NODE #3  No Waiting

 

on 인 경우에는 같은 테스트에서 NODE #1 에서의 Insert : Waiting 이 없다.

 

8.    REFERENCE

A.     wsrep 파라미터
http://galeracluster.com/documentation-webpages/mysqlwsrepoptions.html

B.     mariadb 파라미터
https://mariadb.com/kb/en/mariadb/documentation/optimization-and-tuning/system-variables/server-system-variables/          

C.     wsrep_auto_increment_control
http://www.percona.com/blog/2011/01/12/conflict-avoidance-with-auto_increment_incremen-and-auto_increment_offset/

D.     16.1.2.2 Replication Master Options and Variables
http://dev.mysql.com/doc/refman/5.0/en/replication-options-master.html

E.     Bootstrapping the cluster
http://www.percona.com/doc/percona-xtradb-cluster/5.5/manual/bootstrap.html

반응형

마리아 DB에서 Galera Cluster를 설치하면서 개념이 필요해서 검색해서 공유해 본다.

추가적으로 정리가 되면 MariaDB에서 Galera Cluster 설치 하는 부분을 공유할 예정이다.


[원본] http://bcho.tistory.com/1062


MySQL Galera Replication


조대협 (http://bcho.tistory.com)


RDBMS 오픈소스 중에서 단연 가장 많이 사용되는 것은 MySQL인데, 근래에 웹 스케일이 커지면서, 단일 인스턴스로만 서비스가 불가능한 용량까지 가게 되서, 이 MySQL에 대한 클러스터링 스케일링에 대한 이슈가 많아졌다. 이에 Tungsten, MySQL Replication, NDB, Galera 등 다양한 클러스터링 방법이 있는데, 그중에서 갈레라 클러스터링 (Galera Clustering)에 대해서 간단하게 정리하고자 한다.


MySQL Replication


갈레라 클러스터링을 이해하기에 앞서서 먼저 가장 널리(그리고 쉽게) 사용되는 MySQL Replication 방식에 대해서 알아보자. MySQL Replication 방식은 Master/Slave 방식의 구성이 일반적이며, 이 구성의 경우 특정 노드는 쓰기를 담당하고 나머지 노드는 읽기를 담당하는 형태로 구성이 된다.

통상적으로 데이타 베이스 트랜젝션의 60~80%가 읽기 트렌젝션이기 때문에, 이러한 구조를 사용하더라도 충분히 성능의 향상을 기대할 수 있다.


다음 그림은 MySQL Replication 의 간단한 구조도 이다.

 




먼저 좌측의 Master Node에 쓰기 트렌젝션이 수행되면 Master node는 데이타를 저장하고, 트렌젝션에 대한 로그를 내부적으로 BIN LOG라는 파일에 저장한다. (시간 순서대로 수행한 업데이트 트렌젝션이 기록되어 있다.)


Slave Node에서는 이 BIN LOG를 복사해온다. 이 복사 작업을 IO Thread라는 스레드가 수행하는데, 이렇게 읽어온 내용은 Replay Log라는 파일에 기록이 된다. 이렇게 기록된 내용은 SQL Thread라는 스레드가 읽어서, 하나씩 수행을 해서  MySQL 데이타 파일에 기록을 한다.


쉽게 설명하면, insert 쿼리를 master node에서 실행했으면 그 쿼리가 master node의 bin log에 기록이 되고, 이 내용은 slave node에 복사가 된후에, slave node에서 같은 쿼리가 수행이 되서 복제가 반영되는 방식이다.


방식이 단순해서 신뢰도가 높은 반면, 단점으로는

  • 읽기와 쓰기 노드를 분리해야 하며,
  • 데이타 복제가 동기 방식이 아닌 비동기 방식으로 적용된다. 바꿔서 말하면, master node에 적용한 데이타 변경사항이 slave에 반영될때까지 일정 시간이 걸린다는 것으로, master와 slave node간의 순간적인 데이타 불일치성이 발생할 수 있다는 것이다.


Galera cluster


Galera cluster는 http://galeracluster.com/ 에서 제공되는 오픈소스로, 동기방식의 복제 구조를 사용하고 있다.

간단하게 구조를 살펴보자 아래 그림을 보면 




각각의 노드가 있을때, 아무 노드에나 쓰기나 업데이트가 발생하면, 모든 노드에 데이타를 복사를 완료하고 나서, 업데이트 내용이 파일에 저장된다. 아키텍쳐상의 구조를 보면, 위의 그림과 같이 각 MySQL 노드에는 WSREP 라는 모듈이 있다. 이 모듈은 데이타베이스에 복제를 위한 범용 모듈로 여기에 마치 드라이버처럼 Galera replication module을 연결해주면 데이타 변경이 있을때 마다, 이 Garela replication module이 다른 mysql node로 데이타를 복제한다.


약간 더 구체적인 구조를 살펴보면 노드간의 데이타 복제는 다음과 같은 흐름을 따르게 된다. 





노드에 트랜젝션이 발생하고 COMMIT이 실행이되면, 디스크에 내용을 쓰기 전에 다른 노드로 복제를 요청하고 다른 노드에 복제 요청이 접수되었을때, 해당 노드의 디스크에 실제로 데이타를 쓰게 된다.


이러한 특성으로, 전체 노드에 데이타가 항상 일관성있게 저장되고, 모든 노드가 마스터 노드로 작동을 하며, 특정 노드가 장애가 나더라도 서비스에 크게 문제가 없다. 

(MySQL Replication의 경우 마스터 노드가 장애가 나면 슬레이브 노드중 하나를 마스터로 승격을 해야하는 등 다소 운영 프로세스가 갈레라에 비해서는 복잡하다.)


상당히 좋아 보이는 구조이기는 한데, 반대로 가지는 단점도 만만하지 않다.


성능

먼저 성능적인 부분에서, 데이타를 디스크에 저장하기 전에, 다른 모든 노드에 데이타 복제 요청을 해야 하기 때문에, 비동기 방식의 MySQL Replication에 비해서, 쓰기 성능이 떨어지는 것으로 보인다.


장애 전파

이렇게 다른 노드에 복제 요청을 하는 클러스터 구조의 경우, 장애를 다른 노드로 전파 시킬 가능성이 높은데, 예전에 대표적인 웹 애플리케이션 서버인 웹로직의 경우 유사한 세션 클러스터링 구조를 사용했다. 

이 경우 복제를 요청했을때 복제 요청을 받은 노드가 장애 상황 특히 느려지거나 일시적으로 멈췄으때, 복제를 요청한 노드가 응답을 받지 못하고 대기하게 되고, 이 대기한 노드에 다른 노드가 복제를 또 요청하면, 같은 이유로 복제가 지연 되면서 클러스터를 타고 장애가 전파되는 현상을 야기하게 된다.

그래서 갈레라 클러스터의 경우 LOCK문제가 생기거나 슬로우 쿼리들이 많이 발생할때 장애를 전파시킬 수 있는 잠재적인 문제를 가지고 있다.


스케일링의 한계

갈레라가 모든 노드에 데이타를 복제하고 트렌젝션을 끝내는 만큼, 전체적인 노드수가 많아지게 되면, 복제를 하는데 그만큼 시간이 많이 걸림에 따라, 하나의 클러스터에서 유지할 수 있는 노드의 수가 한계가 있어져서, 횡적 스케일링의 한계가 올 수 있다. 


이런 단점에도 불구하고, 모든 노드에 읽기 쓰기가 가능한 멀티 마스터 구조와 모든 노드의 데이타를 일관적으로 유지 시켜준다는 장점과 쉬운 설정 방법으로 인하여 MySQL 클러스터를 구성한다면 한번쯤 검토해봐야 하는 솔루션이 아닌가 한다.


(아쉽게도 국내 사례는 그다지 많지 않은듯...)


몇가지 참고 사항

  • 갈레라 클러스터는 서로 다른 MySQL 버전간에도 클러스터로 묶을 수 있다.
  • 갈레라 클러스터에서 노드가 떨어졌다가 붙으면 일정 부분은 GTID (Global Transaction ID)를 이용하여, 데이타가 복제 되지 않은 델타 부분만 복제가 가능하지만, 시차가 오래되 버리면 풀 백업본을 가져다 엎어야 한다. (풀백업은 복구는 시간이 많이 걸림)


반응형

+ Recent posts