InfoGrab DocsInfoGrab Docs

데이터베이스 로드 밸런싱

GitLab Rails 및 Sidekiq에서 데이터베이스 로드 밸런싱이 구현되는 방식에 대한 기술적 개요를 설명합니다.

데이터베이스 로드 밸런싱을 사용하면 읽기 전용 쿼리가 여러 PostgreSQL 노드로 분산됩니다. 구성과 관리 방법은 데이터베이스 로드 밸런싱 을 참고합니다. 용어 # 용어 정의 Host 데이터베이스 호스트입니다. 프라이머리 또는 레플리카일 수 있습니다. Primary 모든 쓰기 작업과 읽기-쓰기 트랜잭션에 사용되는 기본 PostgreSQL 호스트입니다. Replica 읽기 전용 쿼리에 사용되는 보조 PostgreSQL 호스트입니다. Workload 데이터베이스 연결이 필요한 Rails 요청 또는 Sidekiq job 입니다. Sticking 쓰기 이후 레플리카가 따라잡을 때까지 워크로드를 프라이머리로 라우팅하는 동작입니다. 주요 클래스 # 모든 로드 밸런싱 클래스는 Gitlab::Database::LoadBalancing 네임스페이스에 있습니다. 클래스 역할 ConnectionProxy ActiveRecord 연결 요청을 가로채 LoadBalancer 로 라우팅합니다. LoadBalancer 호스트(프라이머리 또는 레플리카)를 선택하고 해당 풀에서 연결을 제공합니다. Host 단일 데이터베이스 호스트를 나타냅니다. online 상태와 복제 지연을 추적합니다. Session 워크로드별 데이터베이스 상태, 즉 쓰기 발생 여부와 워크로드의 프라이머리 고정 여부를 추적합니다. SessionMap 워크로드 안에서 로드 밸런싱 대상 데이터베이스 각각을 고유한 Session 인스턴스에 매핑합니다. Sticking 네임스페이스와 ID를 키로 하여 Redis에 프라이머리 고정 상태를 관리합니다. 쿼리 라우팅 # 각 워크로드는 로드 밸런싱 대상 데이터베이스마다 새로운 Session 인스턴스로 시작합니다. Session 은 해당 워크로드의 모든 데이터베이스 작업을 추적하고, 연결을 프라이머리로 보낼지 레플리카로 보낼지 판단합니다. ActiveRecord 가 연결을 요청하면 ConnectionProxy 는 다음을 순서대로 평가합니다. 해당 작업이 쓰기(insert, update, delete)인지 확인합니다. 쓰기라면 프라이머리로 라우팅하고 세션을 쓰기 발생 상태로 표시합니다. 이전 쓰기로 인해 세션이 이미 프라이머리에 고정되어 있는지 확인합니다. 고정되어 있다면 프라이머리로 라우팅합니다. 쿼리가 SELECT ... FOR UPDATE 와 같은 잠금 읽기인지 확인합니다. 그렇다면 프라이머리로 라우팅합니다. use_primary 블록이 활성 상태인지 확인합니다. 활성 상태라면 프라이머리로 라우팅합니다. 그 밖의 경우에는 레플리카로 라우팅합니다. 특수 라우팅 블록 # 다음 블록은 기본 라우팅 동작을 재정의합니다. 블록 효과 use_primary 블록 안의 모든 쿼리를 프라이머리로 강제합니다. use_primary! 남은 워크로드 동안 현재 세션을 프라이머리에 고정합니다. ignore_writes 프라이머리에서 쓰기를 수행하되 프라이머리 고정을 트리거하지 않습니다. use_replicas_for_read_queries 세션이 프라이머리에 고정된 경우에도 읽기를