MariaDB, MySQL, Percona Server Threadpool 정리

https://mariadb.com/kb/en/mariadb/thread-pool-in-mariadb/
1. 언제 쓰레드풀을 사용하면 효과적인가:
– 짧은 쿼리 위주, CPU바운드의 OLTP 워크로드에 유용

2. 쓰레드풀이 비효율적으로 동작하는 드문 경우들:
– 매우 몰리는 워크로드 (긴 유휴 액티비티와 짧은시간 동안 많이 동작하는 유저 액티비티 혼재)
– 쓰레드 생성 쓰로틀링부터 나오는 딜레이를 감당할 수 없을 때:
이런 경우라도, 쓰레드들을 retire 시키는 방식을 조정해서 성능은 향상될 수 있음
(e.g. MariaDB 의 thread_pool_idle_timeout, MySQL 의 thread_pool_max_unused_threads)
– 동시에 많고 길고, 양보하지 않는 쿼리들이 있을 때:
DW성 작업과 같이 풀을 독점하는 수행시간이 긴 쿼리가 발생할 때 다른 쿼리의 수행을 방해할 수 있음, 딜레이는 오직 지연stall 감지 매커니즘으로 조정할 수 있음
(e.g. thread_pool_stall_limit)
– 데이테베이스가 부하에 무관하게 언제나 빨리 끝나는 심플한 쿼리가 필요할 때:
데이터베이스 로드와 상관없이 심플한 쿼리가 언제나 빨리 수행될 수 있는 건 아님, 쓰레드풀이 다 차있을 때 SELECT 1 과 같은 쿼리도 큐로 들어가거나 나중에 수행되어 쓰레드풀 미사용보다 느려질 수 있음

3. MariaDB 로우레벨 구현 상세 문서에 있는 오라클 쓰레드풀의 단점 (2011년):
http://worklog.askmonty.org/worklog/Server-BackLog/?tid=246
– 리눅스에서만 효율적인 epoll() 을 씀, 다른 OS에서는 poll()을 사용
– 클라이언트 로그인, 로그인이 acceptor 쓰레드를 블락함, 그리고 네트워크 IO 가 싱크방식으로 완료됨, 이는 느린 클라이언트가 다른 클라이언트들의 로그인을 막게 됨
~~~> 요거 5.6.36 에서 어떻게 변했는지 확인 필요
– wait_timeout 기능이 MySQL 엔터프라이즈 쓰레드풀에서 동작하지 않음
– KILL 명령이 높은 오버헤드를 가지고 있고 효율적이지 못한 구현방식때문에 락 발생에 주의가 필요함
– 쓰레드풀에 대한 인터널정보가 information_schema 에 존재

4. MySQL 쓰레드풀에 있는 것:
– 동시 트랜잭션의 숫자를 제한 (부정적 측면의 이야기)
MariaDB 는 일반적으로 하이 큐 우선 구동시킴, MySQL은 (“BEGIN” 구문 이후) 트랜잭션이 한 번 시작하게 되면 커넥션의 우선순위를 낮춤 (로우큐 우선 사용)
아마도 특정 MySQL 버전에서 kernel_mutex 문제가 이 방식으로 해결되는 것일 수 있고, 지금까지는 sysbench 결과를 높이기 위한 트릭일 수 있다고 MariaDB 주장
– 쓰레드풀에 대한 인터널정보가 information_schema 에 존재

http://mikaelronstrom.blogspot.kr/2011/10/mysql-thread-pool-limiting-number-of_21.html
MySQL 쓰레드풀에 대해서는 Mikael Ronstrom 블로그에 나와있는데, MySQL 서버가 동시에 많은 트랜잭션을 핸들링 할 때 부하를 받으며, 너무 많은 트랜잭션이 병렬로 수행되는 상황을 피해야 한다고 함
쓰레드풀은 이미 트랜잭션을 시작했는지 혹은 아닌지에 따라 큐잉하는 쿼리의 우선순위를 핸들링하고
이러한 우선순위화는 너무 긴 트랜잭션이 존재할 때 livelock 이슈를 가지는데 이런 문제를 피하기위해 설정된 시간이 지난 후에 높은 우선순위큐로 쿼리를 이동시킴(thread_pool_prio_kickup_timer)
하지만 짧은 시간동안 너무 많은 이동이 발생되지 않도록, 쓰레드풀은 쓰레드그룹당 10ms 에 한 쿼리를 이동시킴 (초당 100쿼리가 timer에 걸리면 높은 우선순위큐로 이동)
서버에서의 쿼리 수행을 빠르게 하기 위해 유저커넥션을 항상 높은 우선 순위 큐에 존재하도록 설정 가능함

5. DB별 쓰레드풀 파라미터의 차이:
MySQL에만 있는 것//
thread_pool_high_priority_connection # 동시 트랜잭션 수 제한과 관련(기본값은 낮은 우선순위 큐 먼저 사용)
thread_pool_prio_kickup_timer # 동시 트랜잭션 수 제한과 관련(낮은 우선순위 큐에서 높은 우선순위 큐로 이동)
thread_pool_max_unused_threads # MySQL 쓰레드풀만의 쓰레드 종료 로직, MariaDB 에서는 thread_pool_idle_timeout 를 사용
thread_pool_algorithm # 실험적인 변수, 벤치마킹 점수용?

MariaDB에만 있는 것//
thread_pool_max_threads # 풀 내 최대 쓰레드 수 설정, 최대값에 도달하면 추가로 쓰레드가 생성되지 않음, MariaDB 10.2.4 부터 디폴트 65536
thread_pool_idle_timeout # idle worker 쓰레드에 대한 timeout 설정, 기본값은 60
MySQL, MariaDB에 모두 존재하나 동작 방식이 다른 것//
thread_pool_stall_limit  # 큐에서 지연으로 판단하는 임계치, MySQL 쓰레드풀에서는 10 ms 단위로 체크, MariaDB 에서는 1ms 단위로 체크

6. MariaDB 와 Percona 의 차이:
– MariaDB 의 thread_pool_priority=auto,high,low https://mariadb.com/kb/en/mariadb/thread-pool-system-and-status-variables/#thread_pool_priority 는
Percona 의 thread_pool_high_prio_mode=transactions,statements,none https://www.percona.com/doc/percona-server/5.7/performance/threadpool.html#thread_pool_high_prio_mode 와 일치
– Percona 에는 thread_pool_high_prio_tickets 세팅으로 새로운 커넥션 쿼리를 하이 큐에 얼마나 들어오게 할건지 지정 (기본값: 4294967295)
https://www.percona.com/doc/percona-server/5.7/performance/threadpool.html#thread_pool_high_prio_tickets
MariaDB 는 thread_pool_prio_kickup_timer 피쳐가 있음
https://mariadb.com/kb/en/mariadb/thread-pool-system-and-status-variables/#thread_pool_prio_kickup_timer

7. MySQL 쓰레드풀 사용시 쿼리 수행이 지연되는 최악의 케이스 예시
로우큐에 200개 구문이 존재
하이큐에 10개 구문이 존재
thread_pool_prio_kickup_timer=500 (500ms)
thread_pool_stall_limit=30 (300ms)

최악의 케이스로 하이큐에 지속적으로 장시간 수행되는 10개 트랜잭션이 있어 로우큐에서 하이큐로 옮겨갈 수 있는 구문이 없다면,
thread_pool_prio_kickup_timer=500ms 이후, 새로운 구문이 하이큐로 옮겨갈 수 있게 됨
로우큐에서 하이큐로 이동하는 속도는 최대 초당 100개(10ms 당 1개)로 고정되어있어 200개 구문이 모두 하이큐로 옮겨가는데 2초가 걸림
옮겨지는 구문들이 하이큐에 도달했을 때 하이큐에 이미 많은 롱런 구문들이 먼저 존재할 수 있음
이때 모든 구문들이 지연이되고 다음 구문이 하이큐로부터 받기 전 매 구문당 thread_pool_stall_limit=30(300ms)가 걸림
그리하여, 이 시나리오에서 새 구문이 수행을 시작하기 전 토탈..

(하이큐이동대기 100개*2회=1초 + 하이큐이동 100개*2회=2초) + 하이큐 전체가 다 차있어서 이동한 쿼리가 모두 지연되면 200개*300ms=60초 = 63초가 소요 (로우큐에서만 최소 3초가 걸림)

Advertisements

답글 남기기

아래 항목을 채우거나 오른쪽 아이콘 중 하나를 클릭하여 로그 인 하세요:

WordPress.com 로고

WordPress.com의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Twitter 사진

Twitter의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Facebook 사진

Facebook의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

Google+ photo

Google+의 계정을 사용하여 댓글을 남깁니다. 로그아웃 / 변경 )

%s에 연결하는 중