2. DBMS이야기/02. MySQL

MySQL 5.6 Parallel Replication (slave_parallel_workers)

OSSW(Open Source System SoftWare 2014. 11. 28. 11:00

MySQL 5.6 Parallel Replication (slave_parallel_workers)



MySQL Replication 구조는 Master에서 아무리 많은 쿼리를 처리하더라도 Slave가 Master의 처리량을 따라갈 수 없는 근본적인 문제를 가지고 있다.

이는 Master에서는 다량의 세션에서 동시에 쿼리를 수행하지만 Slave는 항상 Single Thread로 복제를 처리하기 때문인데, MySQL 5.6 버전에서는 이런 부분들을 조금 완화할 수 있는 parallel slave 기능이 도입되었다.

 

MySQL 5.6의 parallel slave는 database 단위로 별도의 worker thread가 생성되고, 기존 복제 처리를 하던 SQL Thread가 작업 관리 역할을 하면서 각 worker thread에게 작업을 할당해 주는 방식으로 처리된다.







mysql> set global slave_parallel_workers=4;


mysql> stop slave ; start slave;

...

mysql> show processlist;

+----+-------------+------+------+---------+------+-----------------------------------------------------------------------------+------------------+

| Id | User        | Host | db   | Command | Time | State                                                                       | Info             |

+----+-------------+------+------+---------+------+-----------------------------------------------------------------------------+------------------+

| 31 | system user |      | NULL | Connect | 6500 | Waiting for master to send event                                            | NULL             |

| 32 | system user |      | NULL | Connect | 5548 | Slave has read all relay log; waiting for the slave I/O thread to update it | NULL             |

| 33 | system user |      | NULL | Connect | 5592 | Waiting for an event from Coordinator                                       | NULL             |

| 34 | system user |      | NULL | Connect | 5592 | Waiting for an event from Coordinator                                       | NULL             |

| 35 | system user |      | NULL | Connect | 5594 | Waiting for an event from Coordinator                                       | NULL             |

| 36 | system user |      | NULL | Connect | 5587 | Waiting for an event from Coordinator                                       | NULL             |

+----+-------------+------+------+---------+------+-----------------------------------------------------------------------------+------------------+

 

mysql> show processlist;

+----+-------------+------+---------+---------+------+--------------------------------------------------+------------------------------------------------------------------------------------------------------+

| Id | User        | Host | db      | Command | Time | State                                            | Info                                                                                                 |

+----+-------------+------+---------+---------+------+--------------------------------------------------+------------------------------------------------------------------------------------------------------+

| 31 | system user |      | NULL    | Connect |  831 | Waiting for master to send event                 | NULL                                                                                                 |

| 32 | system user |      | NULL    | Connect |    0 | Waiting for Slave Workers to free pending events | NULL                                                                                                 |

| 33 | system user |      | sbtest1 | Connect |   31 | update                                           | INSERT INTO sbtest10(k, c, pad) VALUES (0,' ','qqqqqqqqqqwwwwwwwwwweeeeeeeeeerrrrrrrrrrtttttttttt'), |

| 34 | system user |      | sbtest4 | Connect |   30 | update                                           | INSERT INTO sbtest4(k, c, pad) VALUES (0,' ','qqqqqqqqqqwwwwwwwwwweeeeeeeeeerrrrrrrrrrtttttttttt'),( |

| 35 | system user |      | sbtest3 | Connect |   32 | update                                           | INSERT INTO sbtest4(k, c, pad) VALUES (0,' ','qqqqqqqqqqwwwwwwwwwweeeeeeeeeerrrrrrrrrrtttttttttt'),( |

| 36 | system user |      | sbtest2 | Connect |   32 | update                                           | INSERT INTO sbtest4(k, c, pad) VALUES (0,' ','qqqqqqqqqqwwwwwwwwwweeeeeeeeeerrrrrrrrrrtttttttttt'),( |

+----+-------------+------+---------+---------+------+--------------------------------------------------+------------------------------------------------------------------------------------------------------+ 





실제 어느 정도의 효과가 있는지 아래와 같은 시나리오로 테스트를 해보았다.

▶ sysbench로 테스트 database를 8개 생성 (sbtest1~8)

 sysbench oltp 테스트 부하를 sbtest1~8에 동시에 인입 =>  Master db 기준으로 초당 40,000~45,000 정도의 쿼리가 처리됨

▶ Slave db에서 slave_parallel_workers 파라미터를  0(기존방식), 2, 4, 8로 증가하면서 복제 처리량 측정 

 

테스트 결과 병렬 처리를 하지 않았을 때에 비해서 database 개수만큼 병렬 처리를 했을 때 거의 6배 정도의 복제 처리량이 증가하는 것을 확인할 수 있었다.

물론 부하모델에 따라서 수치는 차이가 나겠고, Master에 비해서는 여전히 느리게 복제가 반영되겠지만, 충분히 메리트 있는 기능으로 보인다.









다만 5.6 버전 기준으로 이 기능을 사용하기 위해서는 몇가지 유의해야 될 부분들이 있다.

(1) 당연한 얘기겠지만 database 단위로 worker thread가 생성되기 때문에, database가 1개인 경우에는 이득이 없다.

(2) worker thread는 트랜잭션을 고려하지 않고 반영을 하기 때문에 각 database가 독립적인 구조가 아니라 트랜잭션으로 묶여서 사용되는 환경에서는 Master-Slave 간 데이터 정합성을 보장할 수 없다.

(3) database 단위로 복제를 처리하지만, 한쪽 database에서 지연이 발생하면 전체 database에도 복제 지연이 발생하게 된다.  

     즉, 병렬 처리의 효과를 극대화하기 위해서는 각 database에 인입되는 부하가 균일해야 하며, 짧은 쿼리들 위주이어야 한다.

     (SQL Thread가 특정 worker thread에게 작업 할당을 해야 되는데, 해당 thread가 이전 작업을 완료하지 못했으면 SQL Thread는 대기)

(4) 5.6.16 버전까지는 특정 상황에서 parallel slave 기능을 사용했을 때 memory leak이 발생할 수 있다. (5.6.17에서 패치됨)

     http://bugs.mysql.com/bug.php?id=71197





※ 특정 database에 lock을 걸어서 의도적으로 복제 적용하지 못하도록 처리했을 때의 나머지 worker thread가 대기하는 상태


mysql> lock table sbtest1.sbtest write;


Query OK, 0 rows affected (0.00 sec)

 

mysql> show processlist;

+----+-------------+-----------------+---------+---------+------+--------------------------------------------------+------------------------------------------------------------------------------------------------------+

| Id | User        | Host            | db      | Command | Time | State                                            | Info                                                                                                 |

+----+-------------+-----------------+---------+---------+------+--------------------------------------------------+------------------------------------------------------------------------------------------------------+

| 31 | system user |                 | NULL    | Connect |  853 | Waiting for master to send event                 | NULL                                                                                                 |

| 32 | system user |                 | NULL    | Connect |    0 | Waiting for Slave Workers to free pending events | NULL                                                                                                 |

| 33 | system user |                 | sbtest1 | Connect |   37 | Waiting for table metadata lock                  | INSERT INTO sbtest(k, c, pad) VALUES (0,' ','qqqqqqqqqqwwwwwwwwwweeeeeeeeeerrrrrrrrrrtttttttttt'),(0 |

| 34 | system user |                 | NULL    | Connect |   32 | Waiting for an event from Coordinator            | NULL                                                                                                 |

| 35 | system user |                 | NULL    | Connect |   32 | Waiting for an event from Coordinator            | NULL                                                                                                 |

| 36 | system user |                 | NULL    | Connect |   32 | Waiting for an event from Coordinator            | NULL                                                                                                 |

+----+-------------+-----------------+---------+---------+------+--------------------------------------------------+------------------------------------

 




Posted By 김득은






자료 출처  :  http://seuis398.blog.me/70039224614