InfoGrab DocsInfoGrab Docs

데이터베이스 로드 밸런싱

요약

데이터베이스 로드 밸런싱을 사용하면 읽기 전용 쿼리가 여러 PostgreSQL 노드로 분산됩니다. 모든 로드 밸런싱 클래스는 Gitlab::Database::LoadBalancing 네임스페이스에 있습니다. 각 워크로드는 로드 밸런싱 대상 데이터베이스마다 새로운 Session 인스턴스로 시작합니다.

데이터베이스 로드 밸런싱을 사용하면 읽기 전용 쿼리가 여러 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는 다음을 순서대로 평가합니다.

  1. 해당 작업이 쓰기(insert, update, delete)인지 확인합니다. 쓰기라면 프라이머리로 라우팅하고 세션을 쓰기 발생 상태로 표시합니다.
  2. 이전 쓰기로 인해 세션이 이미 프라이머리에 고정되어 있는지 확인합니다. 고정되어 있다면 프라이머리로 라우팅합니다.
  3. 쿼리가 SELECT ... FOR UPDATE와 같은 잠금 읽기인지 확인합니다. 그렇다면 프라이머리로 라우팅합니다.
  4. use_primary 블록이 활성 상태인지 확인합니다. 활성 상태라면 프라이머리로 라우팅합니다.
  5. 그 밖의 경우에는 레플리카로 라우팅합니다.

특수 라우팅 블록#

다음 블록은 기본 라우팅 동작을 재정의합니다.

블록 효과
use_primary 블록 안의 모든 쿼리를 프라이머리로 강제합니다.
use_primary! 남은 워크로드 동안 현재 세션을 프라이머리에 고정합니다.
ignore_writes 프라이머리에서 쓰기를 수행하되 프라이머리 고정을 트리거하지 않습니다.
use_replicas_for_read_queries 세션이 프라이머리에 고정된 경우에도 읽기를 레플리카로 강제합니다.
fallback_to_replicas_for_ambiguous_queries 쓰기가 발생하지 않았다면 트랜잭션과 모호한 쿼리가 레플리카를 사용하도록 허용합니다.

트랜잭션#

기본적으로 트랜잭션은 프라이머리로 라우팅됩니다. fallback_to_replicas_for_ambiguous_queries가 활성 상태이면, 트랜잭션 안에서 쓰기가 수행되지 않는 한 트랜잭션이 레플리카를 사용할 수 있습니다. 트랜잭션 안에서 쓰기가 발생하면 프라이머리로 라우팅되고 고정이 트리거됩니다.

use_replicas_for_read_queries로 표시된 블록 안에서 쓰기가 발생하면 WriteInsideReadOnlyTransactionError가 발생합니다.

프라이머리 고정#

쓰기가 발생한 뒤 GitLab은 레플리카가 따라잡을 때까지 워크로드를 프라이머리에 고정합니다. 고정 상태는 단순한 타임아웃이 아니라 PostgreSQL LSN(Log Sequence Number) 위치를 사용해 Redis에서 추적됩니다.

고정 범위#

고정은 (namespace, id) 쌍으로 범위가 정해집니다. 웹 요청의 경우 namespace는 :user 이고 id는 현재 사용자 ID 입니다. 여러 네임스페이스를 동시에 고정할 수 있으며 각각 독립적으로 추적됩니다. Redis 키 형식은 lib/gitlab/database/load_balancing/sticking.rb의 Sticking#sticking_key를 참고합니다.

API 토큰이나 세션 토큰처럼 민감한 식별자에는 고정 메서드에 hash_id: true를 전달합니다. 이렇게 하면 원본 값 대신 ID의 SHA-256 해시가 저장됩니다.

Gitlab::Database::LoadBalancing::Sticking.stick(:api_key, token, hash_id: true)

해제 메커니즘#

다음 중 하나가 발생하면 고정이 해제됩니다.

  • 레플리카의 LSN 이 기록된 쓰기 LSN에 도달하거나 이를 지나갑니다. 이때 GitLab은 30초 타임아웃을 모두 기다리지 않고 즉시 고정을 해제합니다.
  • 복제 상태와 관계없이 30초 만료 시점에 도달합니다.

LSN 비교는 동일 사용자의 동시 요청 사이에 경쟁 상태가 생기지 않도록 Redis의 원자적 Lua 스크립트를 사용합니다.

Sidekiq 고정#

Sidekiq은 백그라운드 job에서 오래된 데이터를 읽지 않도록 WAL 기반 방식을 사용합니다.

  1. 큐 등록 시점(SidekiqClientMiddleware): 로드 밸런싱 대상 데이터베이스별 현재 LSN 이 job 페이로드에 기록되며, 해당 LSN 이 프라이머리에서 온 것인지 레플리카에서 온 것인지도 함께 기록됩니다.
  2. 실행 시점(SidekiqServerMiddleware): job 이 실행되기 전에 GitLab은 레플리카가 기록된 LSN까지 따라잡았는지 확인합니다.
    • 높은 긴급도 워커: 0.5초 동안 최대 5회 시도합니다.
    • 일반 워커: 1.5초 동안 최대 3회 시도합니다.
    • 시간 안에 따라잡은 레플리카가 없으면 job은 프라이머리에서 읽는 방식으로 대체됩니다.

레플리카 지연 확인#

읽기를 레플리카로 라우팅하기 전에 LoadBalancer는 해당 레플리카가 프라이머리와 충분히 동기화되어 있는지 확인합니다.

확인 간격#

지연 확인은 replica_check_interval 초에서 2 * replica_check_interval 초 사이의 무작위 간격으로 실행됩니다. 상태 점검 부하를 분산하기 위해 간격은 프로세스마다 무작위로 정해집니다.

2단계 지연 평가#

이 확인은 두 가지 방법을 순서대로 사용합니다.

  1. 시간 기반: pg_last_wal_replay_lsn()을 프라이머리의 현재 LSN과 비교합니다. 레플리카가 max_replication_lag_time 초보다 더 지연되어 있으면 해당 레플리카는 건너뜁니다.
  2. 데이터 크기 기반 대체: 시간 기반 확인으로 지연을 판단할 수 없으면(예를 들어 프라이머리에 최근 쓰기가 없었던 경우) GitLab은 LSN의 바이트 단위 차이를 max_replication_difference와 비교하는 방식으로 대체합니다. 이렇게 하면 쓰기가 적은 기간에 레플리카가 잘못 오프라인으로 표시되는 것을 방지합니다.

논리적 레플리카#

논리적 레플리카에 대해서는 GitLab 이 복제 지연을 판단할 때 pg_last_wal_replay_lsn 대신 pg_replication_origin_status를 사용합니다. 쿼리를 실행하는 사용자가 pg_replication_origin_status에 대한 SELECT 권한을 가지고 있으면 GitLab 이 논리적 레플리카를 자동으로 감지합니다. 논리적 레플리카 감지에는 PostgreSQL 14 이상이 필요합니다.

기능 플래그#

다음 기능 플래그는 런타임에 레플리카 지연 동작에 영향을 줍니다.

플래그 효과
load_balancer_ignore_replication_lag_time 시간 기반 지연 확인을 전면 비활성화합니다.
load_balancer_double_replication_lag_time 구성된 max_replication_lag_time의 최대 2배까지 허용합니다.
load_balancer_low_statement_timeout 오버헤드를 제한하기 위해 상태 점검 쿼리에 100ms statement 타임아웃을 사용합니다.

페일오버 처리#

로드 밸런서는 실패한 작업이 읽기였는지 쓰기였는지에 따라 실패를 다르게 처리합니다.

읽기 페일오버#

연결 오류로 읽기가 실패하면 LoadBalancer는 해당 호스트를 오프라인으로 표시하고 사용 가능한 다음 레플리카로 재시도합니다. 모든 레플리카가 오프라인이면 읽기는 프라이머리로 대체됩니다.

쿼리 충돌(직렬화 실패)로 읽기가 실패하면 LoadBalancer는 프라이머리로 대체하기 전에 모든 레플리카에 걸쳐 최대 host_list.length * 3 회까지 재시도합니다.

load_balancer_force_release_hosts 기능 플래그는 현재 호스트만이 아니라 모든 호스트에서 연결을 해제하도록 강제하며, 특정 페일오버 상황에서 도움이 될 수 있습니다.

쓰기 페일오버#

쓰기 재시도는 트랜잭션 상태에 따라 달라집니다.

  • 열린 트랜잭션 밖: 지수 백오프(2초, 4초, 8초)로 최대 3회 재시도합니다.
  • 열린 트랜잭션 안: 재시도하지 않습니다. 트랜잭션을 안전하게 재실행할 수 없으므로 오류가 즉시 표면화됩니다.

서비스 디스커버리#

서비스 디스커버리를 사용하면 LoadBalancer가 구성된 DNS 레코드를 주기적으로 조회해 현재 레플리카 주소 목록을 가져옵니다. 이 목록은 DNS 응답이 변경되거나 오래된 연결에 대해 disconnect_timeout에 도달하면 갱신됩니다.

max_replica_pools#

max_replica_pools가 설정되면 Sampler 클래스가 각 GitLab 프로세스가 연결하는 레플리카 수를 제한합니다. 이 설정은 서비스 디스커버리에만 적용됩니다. 정적 호스트 목록은 항상 구성된 모든 호스트에 연결합니다.

샘플러는 일관된 시드를 사용해 프로세스마다 결정적으로 레플리카를 선택하며, 반환된 모든 호스트 이름에 연결을 고르게 분산합니다. 레플리카 수가 max_replica_pools를 초과하면 샘플러는 제외된 레플리카를 로그로 남깁니다.

쓰기 위치 쿼리#

GitLab은 현재 쓰기 LSN을 판단하기 위해 두 가지 SQL 쿼리 중 하나를 사용하며, 이는 USE_NEW_LOAD_BALANCER_QUERY 환경 변수(기본값 true)로 제어합니다. 기본 쿼리는 활성 복제 슬롯이 있는 스탠바이를 올바르게 처리합니다. 레거시 쿼리는 pg_current_wal_insert_lsn()을 조건 없이 사용합니다. 구현은 lib/gitlab/database/load_balancing/load_balancer.rb의 LoadBalancer#query_for_location을 참고합니다.

USE_NEW_LOAD_BALANCER_QUERY=false는 이전 PostgreSQL 구성에서 예상과 다른 LSN 동작을 진단할 때만 설정합니다.

배포 전략#

로드 밸런싱 변경 사항을 기능 플래그 뒤에서 롤아웃할 때는 Sidekiq 워커에 먼저 배포합니다.

Sidekiq에 먼저 배포하는 이유는 다음과 같습니다.

  • API Pod가 안정적으로 유지되므로, 필요하면 ChatOps로 플래그를 비활성화할 수 있습니다.
  • 백그라운드 job은 사용자에게 영향을 주지 않고 자동으로 재시도됩니다.

예시는 다음과 같습니다.

if Feature.enabled?(:my_flag) && Gitlab::Runtime.sidekiq?
  new_changes
else
  existing_changes
end

데이터베이스 로드 밸런싱

GitLab v19.4
원문 보기

요약

데이터베이스 로드 밸런싱을 사용하면 읽기 전용 쿼리가 여러 PostgreSQL 노드로 분산됩니다. 모든 로드 밸런싱 클래스는 Gitlab::Database::LoadBalancing 네임스페이스에 있습니다. 각 워크로드는 로드 밸런싱 대상 데이터베이스마다 새로운 Session 인스턴스로 시작합니다.

데이터베이스 로드 밸런싱을 사용하면 읽기 전용 쿼리가 여러 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는 다음을 순서대로 평가합니다.

  1. 해당 작업이 쓰기(insert, update, delete)인지 확인합니다. 쓰기라면 프라이머리로 라우팅하고 세션을 쓰기 발생 상태로 표시합니다.
  2. 이전 쓰기로 인해 세션이 이미 프라이머리에 고정되어 있는지 확인합니다. 고정되어 있다면 프라이머리로 라우팅합니다.
  3. 쿼리가 SELECT ... FOR UPDATE와 같은 잠금 읽기인지 확인합니다. 그렇다면 프라이머리로 라우팅합니다.
  4. use_primary 블록이 활성 상태인지 확인합니다. 활성 상태라면 프라이머리로 라우팅합니다.
  5. 그 밖의 경우에는 레플리카로 라우팅합니다.

특수 라우팅 블록#

다음 블록은 기본 라우팅 동작을 재정의합니다.

블록 효과
use_primary 블록 안의 모든 쿼리를 프라이머리로 강제합니다.
use_primary! 남은 워크로드 동안 현재 세션을 프라이머리에 고정합니다.
ignore_writes 프라이머리에서 쓰기를 수행하되 프라이머리 고정을 트리거하지 않습니다.
use_replicas_for_read_queries 세션이 프라이머리에 고정된 경우에도 읽기를 레플리카로 강제합니다.
fallback_to_replicas_for_ambiguous_queries 쓰기가 발생하지 않았다면 트랜잭션과 모호한 쿼리가 레플리카를 사용하도록 허용합니다.

트랜잭션#

기본적으로 트랜잭션은 프라이머리로 라우팅됩니다. fallback_to_replicas_for_ambiguous_queries가 활성 상태이면, 트랜잭션 안에서 쓰기가 수행되지 않는 한 트랜잭션이 레플리카를 사용할 수 있습니다. 트랜잭션 안에서 쓰기가 발생하면 프라이머리로 라우팅되고 고정이 트리거됩니다.

use_replicas_for_read_queries로 표시된 블록 안에서 쓰기가 발생하면 WriteInsideReadOnlyTransactionError가 발생합니다.

프라이머리 고정#

쓰기가 발생한 뒤 GitLab은 레플리카가 따라잡을 때까지 워크로드를 프라이머리에 고정합니다. 고정 상태는 단순한 타임아웃이 아니라 PostgreSQL LSN(Log Sequence Number) 위치를 사용해 Redis에서 추적됩니다.

고정 범위#

고정은 (namespace, id) 쌍으로 범위가 정해집니다. 웹 요청의 경우 namespace는 :user 이고 id는 현재 사용자 ID 입니다. 여러 네임스페이스를 동시에 고정할 수 있으며 각각 독립적으로 추적됩니다. Redis 키 형식은 lib/gitlab/database/load_balancing/sticking.rb의 Sticking#sticking_key를 참고합니다.

API 토큰이나 세션 토큰처럼 민감한 식별자에는 고정 메서드에 hash_id: true를 전달합니다. 이렇게 하면 원본 값 대신 ID의 SHA-256 해시가 저장됩니다.

Gitlab::Database::LoadBalancing::Sticking.stick(:api_key, token, hash_id: true)

해제 메커니즘#

다음 중 하나가 발생하면 고정이 해제됩니다.

  • 레플리카의 LSN 이 기록된 쓰기 LSN에 도달하거나 이를 지나갑니다. 이때 GitLab은 30초 타임아웃을 모두 기다리지 않고 즉시 고정을 해제합니다.
  • 복제 상태와 관계없이 30초 만료 시점에 도달합니다.

LSN 비교는 동일 사용자의 동시 요청 사이에 경쟁 상태가 생기지 않도록 Redis의 원자적 Lua 스크립트를 사용합니다.

Sidekiq 고정#

Sidekiq은 백그라운드 job에서 오래된 데이터를 읽지 않도록 WAL 기반 방식을 사용합니다.

  1. 큐 등록 시점(SidekiqClientMiddleware): 로드 밸런싱 대상 데이터베이스별 현재 LSN 이 job 페이로드에 기록되며, 해당 LSN 이 프라이머리에서 온 것인지 레플리카에서 온 것인지도 함께 기록됩니다.
  2. 실행 시점(SidekiqServerMiddleware): job 이 실행되기 전에 GitLab은 레플리카가 기록된 LSN까지 따라잡았는지 확인합니다.
    • 높은 긴급도 워커: 0.5초 동안 최대 5회 시도합니다.
    • 일반 워커: 1.5초 동안 최대 3회 시도합니다.
    • 시간 안에 따라잡은 레플리카가 없으면 job은 프라이머리에서 읽는 방식으로 대체됩니다.

레플리카 지연 확인#

읽기를 레플리카로 라우팅하기 전에 LoadBalancer는 해당 레플리카가 프라이머리와 충분히 동기화되어 있는지 확인합니다.

확인 간격#

지연 확인은 replica_check_interval 초에서 2 * replica_check_interval 초 사이의 무작위 간격으로 실행됩니다. 상태 점검 부하를 분산하기 위해 간격은 프로세스마다 무작위로 정해집니다.

2단계 지연 평가#

이 확인은 두 가지 방법을 순서대로 사용합니다.

  1. 시간 기반: pg_last_wal_replay_lsn()을 프라이머리의 현재 LSN과 비교합니다. 레플리카가 max_replication_lag_time 초보다 더 지연되어 있으면 해당 레플리카는 건너뜁니다.
  2. 데이터 크기 기반 대체: 시간 기반 확인으로 지연을 판단할 수 없으면(예를 들어 프라이머리에 최근 쓰기가 없었던 경우) GitLab은 LSN의 바이트 단위 차이를 max_replication_difference와 비교하는 방식으로 대체합니다. 이렇게 하면 쓰기가 적은 기간에 레플리카가 잘못 오프라인으로 표시되는 것을 방지합니다.

논리적 레플리카#

논리적 레플리카에 대해서는 GitLab 이 복제 지연을 판단할 때 pg_last_wal_replay_lsn 대신 pg_replication_origin_status를 사용합니다. 쿼리를 실행하는 사용자가 pg_replication_origin_status에 대한 SELECT 권한을 가지고 있으면 GitLab 이 논리적 레플리카를 자동으로 감지합니다. 논리적 레플리카 감지에는 PostgreSQL 14 이상이 필요합니다.

기능 플래그#

다음 기능 플래그는 런타임에 레플리카 지연 동작에 영향을 줍니다.

플래그 효과
load_balancer_ignore_replication_lag_time 시간 기반 지연 확인을 전면 비활성화합니다.
load_balancer_double_replication_lag_time 구성된 max_replication_lag_time의 최대 2배까지 허용합니다.
load_balancer_low_statement_timeout 오버헤드를 제한하기 위해 상태 점검 쿼리에 100ms statement 타임아웃을 사용합니다.

페일오버 처리#

로드 밸런서는 실패한 작업이 읽기였는지 쓰기였는지에 따라 실패를 다르게 처리합니다.

읽기 페일오버#

연결 오류로 읽기가 실패하면 LoadBalancer는 해당 호스트를 오프라인으로 표시하고 사용 가능한 다음 레플리카로 재시도합니다. 모든 레플리카가 오프라인이면 읽기는 프라이머리로 대체됩니다.

쿼리 충돌(직렬화 실패)로 읽기가 실패하면 LoadBalancer는 프라이머리로 대체하기 전에 모든 레플리카에 걸쳐 최대 host_list.length * 3 회까지 재시도합니다.

load_balancer_force_release_hosts 기능 플래그는 현재 호스트만이 아니라 모든 호스트에서 연결을 해제하도록 강제하며, 특정 페일오버 상황에서 도움이 될 수 있습니다.

쓰기 페일오버#

쓰기 재시도는 트랜잭션 상태에 따라 달라집니다.

  • 열린 트랜잭션 밖: 지수 백오프(2초, 4초, 8초)로 최대 3회 재시도합니다.
  • 열린 트랜잭션 안: 재시도하지 않습니다. 트랜잭션을 안전하게 재실행할 수 없으므로 오류가 즉시 표면화됩니다.

서비스 디스커버리#

서비스 디스커버리를 사용하면 LoadBalancer가 구성된 DNS 레코드를 주기적으로 조회해 현재 레플리카 주소 목록을 가져옵니다. 이 목록은 DNS 응답이 변경되거나 오래된 연결에 대해 disconnect_timeout에 도달하면 갱신됩니다.

max_replica_pools#

max_replica_pools가 설정되면 Sampler 클래스가 각 GitLab 프로세스가 연결하는 레플리카 수를 제한합니다. 이 설정은 서비스 디스커버리에만 적용됩니다. 정적 호스트 목록은 항상 구성된 모든 호스트에 연결합니다.

샘플러는 일관된 시드를 사용해 프로세스마다 결정적으로 레플리카를 선택하며, 반환된 모든 호스트 이름에 연결을 고르게 분산합니다. 레플리카 수가 max_replica_pools를 초과하면 샘플러는 제외된 레플리카를 로그로 남깁니다.

쓰기 위치 쿼리#

GitLab은 현재 쓰기 LSN을 판단하기 위해 두 가지 SQL 쿼리 중 하나를 사용하며, 이는 USE_NEW_LOAD_BALANCER_QUERY 환경 변수(기본값 true)로 제어합니다. 기본 쿼리는 활성 복제 슬롯이 있는 스탠바이를 올바르게 처리합니다. 레거시 쿼리는 pg_current_wal_insert_lsn()을 조건 없이 사용합니다. 구현은 lib/gitlab/database/load_balancing/load_balancer.rb의 LoadBalancer#query_for_location을 참고합니다.

USE_NEW_LOAD_BALANCER_QUERY=false는 이전 PostgreSQL 구성에서 예상과 다른 LSN 동작을 진단할 때만 설정합니다.

배포 전략#

로드 밸런싱 변경 사항을 기능 플래그 뒤에서 롤아웃할 때는 Sidekiq 워커에 먼저 배포합니다.

Sidekiq에 먼저 배포하는 이유는 다음과 같습니다.

  • API Pod가 안정적으로 유지되므로, 필요하면 ChatOps로 플래그를 비활성화할 수 있습니다.
  • 백그라운드 job은 사용자에게 영향을 주지 않고 자동으로 재시도됩니다.

예시는 다음과 같습니다.

if Feature.enabled?(:my_flag) && Gitlab::Runtime.sidekiq?
  new_changes
else
  existing_changes
end