ProxySQL Internals 및 시스템 구성 둘러보기
ProxySQL Internals 및 시스템 구성 둘러보기
l Version : ProxySQL
이번 포스트에서는 ProxySQL의 인터널 구조와 설정 파일의 구조에 대해서 살펴본다. 상세한 인터널 구조를 모두 설명하지는 않으며 전체적인 구조 및 특징만 소개하도록 한다. 세부적인 내용은 다른 포스트에서 하나씩 다뤄볼 예정이다.
ProxySQL이 시작되면 즉시 새 프로세스를 생성한다. 상위 프로세스는 엔젤 프로세스(와치독과 비슷한 의미로 해석됨)로 작동하고 ProxySQL이 크래시 되었을 때 수 밀리초 내에 서비스를 다시 시작한다. MySQL에 비유하면 mysqld_safe와 매우 유사하다.
ProxySQL에는 기본적으로 두 개의 포트가 필요하다. 트래픽을 수신하는 6033 포트와 ProxySQL을 관리하기 위한 게이트웨이 역할을 하는 6032포트이다. 명령줄 관리 인터페이스(CLI)는 MySQL 클라이언트에서 액세스할 수 있다. 대부분의 구성은 SQL을 사용하여 수행된다. ProxySQL이 구성을 저장하는 데 사용하는 기본 데이터베이스는 SQLite이지만 가능한 한 MySQL에 가까운 환경을 만들기 위해 노력한 흔적을 볼 수 있다. 그 예로 일부 MySQL 구문을 사용하여 ProxySQL 구성을 확인하거나(SHOW GLOBAL VARIABLES) 새 구성을 설정 (SET GLOBAL variable_name = value) 할 수 있다. 백엔드 구성은 테이블에 저장된다. 모든 변경 사항은 SQL(INSERT, UPDATE, DELETE)을 통해 이루어진다.
l Query processor/rules engine : ProxySQL은 MySQL 프로토콜(쿼리)을 해석한다. 규칙 엔진은 들어오는 트래픽을 일치시키고 쿼리를 캐시할지 또는 호스트 그룹 대상에 쿼리를 차단, 경로 재지정, 쿼리 재작성 또는 미러링 할지 여부를 정의한다.
l User authentication : 기본 데이터베이스에 대한 사용자 자격 증명이 해시되어 프록시에 저장된다.
l Hostgroup manager : 트래픽을 보낼 서버 그룹을 관리하고 해당 상태를 추적한다.
l Connection pool : 백엔드 데이터베이스에 대한 연결을 관리한다. 연결 풀은 백엔드를 향해 설정되며 모든 애플리케이션에서 공유/재사용된다.
l Monitoring : 백엔드를 모니터링하고 지표를 수집한다. 모니터링을 하면서 응답하지 않는 호스트 또는 복제 지연에 대해 필요에 따라 트래픽을 제어한다.
Query Processor는 SQL 트래픽을 분석하고 이해할 수 있으므로 광범위한 라우팅을 수행할 수 있다. 스키마, 사용자, 호스트, 포트 또는 정규 표현식과 같은 다양한 속성으로 쿼리를 일치시킬 수 있다. 이렇게 하면 변경하려는 쿼리와 관련하여 상당한 유연성을 얻을 수 있다. 예를들어 쿼리캐시는 쿼리 대기 시간을 줄일 수 있도록 정의된 시간(TTL) 동안 캐시할 수 있다. 이러한 기능은 일반적으로 응용 프로그램에 추가 복잡성을 도입하는 외부 캐싱 계층의 필요성을 제거할 수도 있다. 또한 MySQL 쿼리 캐시(결국 8.0에서 제거됨)보다 훨씬 나은 솔루션일 수도 있다. 그리고 사용자 정의에 따라 쿼리를 제한할 수도 있다. 예를들어 성능에 영향을 미치는 무거운 쿼리들을 초당 한 번 또는 분당 한 번만 실행되도록 할 수 커스텀하게 설정할 수 있다. 쿼리 미러링기능도 있지만 아직은 모든 트래픽이 미러되는 것은 아니기 때문에 큰 기대를 할 정도는 아니다. 그러나 특정 상황에서 매우 유용하게 활용하 수 있다. 주어진 쿼리에 대해 프로덕션 호스트뿐만 아니라 별도의 위치로 보내서 슬로우 로그에서 캡처하거나 일부 디버깅을 수행할 수 있다. 쿼리 재작성을 통해 쿼리를 즉석에서 재작성할 수 있다. 간단한 FORCE INDEX로 문제를 해결할 수 있지만 앱 수정, 테스트, 새 코드 롤 등의 시간 소모적인 프로세스를 거치지 않고는 문제를 추가할 수 없는 상황에서, ProxySQL에서 쿼리를 다시 작성하면서 인덱스 힌트 등을 추가할 수 있다.
ProxySQL은 매우 복잡한 구조를 가진것 처럼 보이지만, 시스템을 구성하고 사용하는데 있어서는 4개의 계층(Runtime, Memory, Disk, Configuration file)을 제공하여 쉽게 사용할 수 있다. 특징으로는 설정에 대해서 즉시 업데이트가 되고, 데몬의 재시작 없이 적용할 수 있다. 또한 잘못 구성되었을 경우에도 쉽게 롤백 할 수 있다.
RUNTIME
Runtime은 ProxySQL 기동 및 운영에 사용된다. 요청을 처리하는 스레드에서 사용하는 ProxySQL의 메모리 내 데이터 구조를 나타낸다. 여기에는 사용된 전역 변수의 값, 호스트 그룹으로 그룹화된 백엔드 서버 목록 또는 프록시에 연결할 수 있는 MySQL 사용자 목록이 포함된다. 운영자는 RUNTIME 구성 섹션의 내용을 직접 수정할 수 없다. 하위 레이어를 수정하고 그 내용을 적용시킬 수 있다.
MEMORY
MEMORY(메인이라고도 함)는 MySQL 호환 인터페이스를 통해 외부에 노출되는 메모리 내 SQLite3 데이터베이스를 나타낸다. 사용자는 이 인터페이스에 MySQL 클라이언트를 연결하고 다른 테이블과 데이터베이스를 쿼리할 수 있다. 이 인터페이스를 통해 사용할 수 있는 구성 테이블은 다음과 같다.
l mysql_servers : ProxySQL에서 중계할 서버들의 목록을 관리한다. 중계 대상 서버를 백엔드 서버라고 부른다.
l mysql_users : ProxySQL에 연결할 수 있는 사용자 및 자격 증명 목록으로, ProxySQL은 이러한 자격 증명을 사용하여 백엔드 서버에도 연결한다.
l mysql_query_rules : 다른 백엔드 서버로 트래픽을 라우팅하기 위한 규칙 목록으로 이러한 규칙으로 인해 쿼리를 다시 작성하거나 결과를 캐싱할 수도 있다.
l global_variables : 런타임에 조정할 수 있는 프록시 전체에서 사용되는 전역 변수 목록이다. 아래 그림은 글로벌 전역 변수 예시이다.
l mysql_collations : 프록시가 작업할 수 있는 MySQL 데이터 정렬 목록으로 클라이언트 라이브러리에서 직접 추출된다.
l debug_levels (디버그 빌드에서만 사용 가능) : ProxySQL이 세부 수준과 함께 내보내는 디버그 문의 유형 목록이다. 이를 통해 다양한 문제를 디버깅하기 위해 로그에 어떤 종류의 명령문이 있는지 런타임에 쉽게 구성할 수 있다. 성능에 영향을 줄 수 있으므로 디버그 빌드에서만 사용할 수 있다.
DISK
DISK는 기본 위치가 $(DATADIR)/proxysql.db인 온디스크 SQLite3 데이터베이스를 나타낸다. ProxySQL 자체 데이터베이스가 실제로 동작하는 곳의 이름이 memory인 이유는, 실제로 in-memory 형태의 SQLite3 데이터베이스가 상주하고 있기 때문이다. ProxySQL 서비스를 다시 시작하면 유지되지 않은 메모리 내 구성이 손실되므로 구성을 DISK에 유지하는 것이 중요하다.
CONFIG
CONFIG 파일은 전형적인 구성 파일이다. Memory에서 운영중인 설정 파일을 덤프할 수 있다. 서비스를 시작하는 동안 ProxySQL은 구성 파일(있는 경우)을 읽어, 지정된 경로에서 내부 데이터베이스 파일을 찾으려고 시도한다. 지정된 경로에 데이터베이스 파일을 발견되면 ProxySQL은 디스크의 데이터베이스를 사용하여 메모리 구성을 초기화한다. 즉, 디스크 구성이 MEMORY에 로드되고 RUNTIME에도 전파된다. 데이터베이스 파일을 찾을 수 없는 경우(예: ProxySQL이 처음으로 실행 중이거나 데이터베이스가 삭제된 경우) 구성 파일의 정보가 MEMORY에 로드되고 DISK 데이터베이스에 저장되며 RUNTIME에도 전파된다.
l Initial startup (옵션 –initial) : ProxySQL을 처음 시작하는 동안 메모리 및 런타임 구성이 구성 파일에서 채워지고 그 후 모든 구성이 ProxySQL의 내부 데이터베이스에 저장된다. –initial 옵션은 SQLite 데이터베이스 파일을 원래 상태(즉, 구성 파일에 정의된 상태)로 재설정하고 기존 SQLite 데이터베이스 파일의 이름을 바꾸는 플래그 와 함께 proxysql을 실행하여 초기 구성을 강제로 다시 발생시킬 수 있다. 롤백이 필요한 경우 사용한다.
l Reload startup (옵션 –reload flag) : ProxySQL 바이너리가 --reload플래그와 함께 실행되면 구성 파일의 구성을 데이터베이스 파일의 내용과 병합하려고 시도한다. 그런 다음 새로 병합된 구성을 사용하여 시작된다. 충돌이 있을 때 ProxySQL이 두 구성 소스를 성공적으로 병합할 것이라는 보장은 없으며 사용자는 항상 병합이 예상대로 실행되었는지 확인해야 한다.
l Runtime ProxySQL Configuration : 런타임 시 구성 설정은 ProxySQL(기본적으로 6032)의 ProxySQL 관리 포트를 통해 수행된다. MySQL 호환 클라이언트로 연결하면 다양한 기본 ProxySQL 구성 및 통계 테이블을 쿼리하기 위한 표준 MySQL 스타일 인터페이스가 표시된다.
계층 간에 구성을 이동하기 위해 관리 인터페이스를 통해 사용할 수 있는 다양한 관리 명령 세트가 있다. 각 레이어간 이동 및 명령어은 아래 링크를 참고한다.
l Moving config between layers : https://github.com/sysown/proxysql/blob/master/doc/configuration_system.md
[참고자료]
l Database load balancing for MySQL and MariaDB with ProxySQL : https://severalnines.com/resources/whitepapers/database-load-balancing-for-mysql-and-mariadb-with-proxysql/
l Multi layer configuration system : https://proxysql.com/documentation/configuring-proxysql/
l Configuration system : https://github.com/sysown/proxysql/blob/master/doc/configuration_system.md
2023-07-24 / Sungwook Kang / http://sungwookkang.com
MySQL, ProxySQL, MySQL Replication, MySQL HA, Replication, MySQL복제, 마스터 슬레이브, ProxySQL설치, MySQL복제설치, 쿼리룰설정 ,ProxySQL Internals, ProxySQL Architecture, ProxySQL 아키텍처, ProxySQL 인터널스