ProxySQL
은 MySQL 호환 데이터베이스(MySQL, Persona, MariaDB 등)를 backend로 두고, 외부의 connection을 받아 쿼리를 중계해 주는 쿼리 라우팅(Query routing)
을 핵심으로 하는 MySQL Proxy Database
다. 설정되어 있는 backend들에 주기적으로 health check를 보내고, 이들 중 하나가 죽으면 auto failover해주는 등, 로드 밸런싱과 유사하다. 이 외에도 쿼리 캐싱, 다운타임 없는 설정 변경 등을 지원한다. Amazon RDS 등에서 이야기하는 Master/Slave 구조로 인해 데이터베이스가 많은 수로 read replication되어 있는 상태에서 이들에게 효율적으로 커넥션을 분배해 주거나, 외부에서 많은 양의 커넥션이 들어오는 경우 효과적으로 connection을 pooling하기 위해 자주 사용된다.
구성
ProxySQL은 Runtime, Memory, Disk, Config file의 4가지 계층으로 이루어져 있다. 어느 곳에서 영감을 받았는진 모르겠지만, 처음 봤을 땐 꽤 생소하다.
Runtime
ProxySQL로 들어오는 요청을 처리하는 스레드의 메모리 내 데이터 구조를 표현한다. 시스템 수준에서 디버깅을 하는 정도가 아니라면 비교적 신경쓸 일이 적다.
Memory
main이라고도 부른다. MySQL 호환 인터페이스를 사용할 수 있는, in-memory로 동작하는 데이터베이스를 나타낸다. 쉽게 말하면 여기서 설정 값이 상주하고 있고, MySQL 클라이언트로 쿼리 가능하다는 의미다. Memory 내에는 대표적으로 아래 4개의 테이블이 존재한다.
- mysql_servers : ProxySQL이 실제로 중계할 서버들의 목록을 관리한다. 중계 대상 서버들을 백엔드 서버라고도 부른다.
- mysql_users : ProxySQL이 관리하는 사용자의 자격 증명 목록이다. '얘는 이 데이터베이스에 read, 얘는 이 데이터베이스에 read/write 권한, ..' 같은 설정들을 다룬다.
- mysql_query_rules : 백엔드 서버로 트래픽이 라우팅될 때 평가되는 쿼리 규칙의 목록이다. 이 테이블을 사용하면, 'LIMIT 없는 쿼리는 사용하지 못한다' 와 같은 동작이 가능하다.
- global_variables : 프록시가 사용하도록 구성된 전역 변수의 목록이며, MySQL connection timeout이나, connect retry 횟수와 같은 메타데이터들을 다룬다.
Disk
ProxySQL 자체 데이터베이스가 실제로 동작하는 곳의 이름이 memory인 이유는, 실제로 in-memory 형태의 SQLite3 데이터베이스가 상주하고 있기 때문이다. 따라서 영속성이 보장되지 않기 때문에, memory 내 구성을 유지하기 위한 계층으로서 Disk가 사용된다.
Config file
Memory에서 돌아가고 있는 데이터베이스에 설정 값들을 dump시킬 수 있는, 전형적인 설정 파일이다.
production level의 MySQL Proxy로 ProxySQL을 가장 많이 사용하고 있는 것 같다. 설치 과정은 ProxySQL Github의 wiki에 잘 나와 있다. 백엔드 인프라의 고도화 단계엔 정말 들어가는 게 많은 것 같다.