블로그 이미지
평범하게 살고 싶은 월급쟁이 기술적인 토론 환영합니다.같이 이야기 하고 싶으시면 부담 말고 연락주세요:이메일-bwcho75골뱅이지메일 닷컴. 조대협


Archive»


MySQL 클러스터링을 위한 Galera Cluster

아키텍쳐 | 2015.11.18 23:52 | Posted by 조대협

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)를 이용하여, 데이타가 복제 되지 않은 델타 부분만 복제가 가능하지만, 시차가 오래되 버리면 풀 백업본을 가져다 엎어야 한다. (풀백업은 복구는 시간이 많이 걸림)