데이터베이스 로드 밸런싱
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 세션이 프라이머리에 고정된 경우에도 읽기를 레플리카로 강제합니다. fallback_to_replicas_