InfoGrab DocsInfoGrab Docs

데이터베이스 로드 밸런싱

요약

데이터베이스 로드 밸런싱을 사용하면 읽기 쿼리가 여러 PostgreSQL 노드에 분산되어 성능이 향상되고 기본 데이터베이스의 부하가 줄어듭니다. 데이터베이스 로드 밸런싱을 활성화하려면: 외부 데이터베이스 서비스의 경우 db_load_balancing 구성만 필요합니다.

데이터베이스 로드 밸런싱을 사용하면 읽기 쿼리가 여러 PostgreSQL 노드에 분산되어 성능이 향상되고 기본 데이터베이스의 부하가 줄어듭니다. 쓰기 작업은 항상 기본에서 실행됩니다. GitLab은 외부 로드 밸런서 없이 쿼리 라우팅을 자동으로 처리합니다.

요구 사항#

데이터베이스 로드 밸런싱을 활성화하려면:

  • PostgreSQL에 기본을 복제하는 하나 이상의 보조 노드가 있어야 합니다.
  • 각 노드가 동일한 포트와 동일한 자격 증명으로 접근 가능해야 합니다.

외부 데이터베이스 서비스의 경우 db_load_balancing 구성만 필요합니다. 연결 풀링은 대규모에서 연결 수를 관리하는 데 도움이 될 수 있지만, 올바른 접근 방식은 공급자에 따라 다르며 이 가이드의 범위를 벗어납니다. 연결 관리 지침은 연결 관리를 참조하세요.

Note

AWS RDS Proxy는 GitLab에서 사용하도록 검증되지 않았습니다.

Linux 패키지 설치의 경우 데이터베이스 로드 밸런싱을 활성화하기 전에 다중 노드 HA PostgreSQL을 구성해야 합니다. 자세한 내용은 다중 노드 설정 구성을 참조하세요.

복제본 수#

복제본 수에는 제한이 없습니다. 실제로는 특히 세 개의 가용 영역에 분산된 환경에서 세 개가 일반적인 시작점입니다. Consul 및 Redis Sentinel을 포함한 여러 GitLab 구성 요소는 정족수(quorum)에 의존하며 홀수 개의 노드를 필요로 합니다. 데이터베이스 복제본 수를 이 패턴에 맞추면 아키텍처가 더 일관되고, 재해 복구 커버리지가 향상되며, 단일 가용 영역 장애의 영향이 제한됩니다. 규모가 작은 환경은 두 개의 복제본으로 시작하여 부하가 증가함에 따라 더 추가할 수 있습니다.

규모별 지침은 참조 아키텍처 문서를 참조하세요.

데이터베이스 로드 밸런싱 구성#

데이터베이스 로드 밸런싱은 다음 두 가지 방법 중 하나로 구성할 수 있습니다:

  • 호스트: PostgreSQL 호스트의 정적 목록. 구성이 더 간단하며 대부분의 환경에 적합합니다.
  • 서비스 디스커버리: PostgreSQL 호스트 목록을 반환하는 DNS 레코드. Consul을 사용하는 Linux 패키지 HA 설정처럼 복제본 목록이 동적으로 변경될 때 사용합니다.

호스트#

호스트 목록에 기본을 포함하는 것은 선택 사항입니다. 포함하면 기본이 복제본과 함께 읽기 쿼리의 대상이 되어 보조 서버의 전체 부하가 줄어듭니다. 기본이 이미 지속적으로 높은 부하를 받고 있다면 제외하여 쓰기용 용량을 확보할 수 있습니다. 기본은 이 목록에 포함되는지 여부와 상관없이 항상 쓰기 쿼리를 처리합니다.

호스트 목록을 구성하려면 균형을 조정하려는 각 환경의 모든 GitLab Rails 및 Sidekiq 노드에서 다음 단계를 수행합니다:

  1. /etc/gitlab/gitlab.rb 파일을 편집합니다.

  2. gitlab_rails['db_load_balancing']에서 균형을 조정할 데이터베이스 호스트 배열을 만듭니다. 예를 들어 primary.example.com, secondary1.example.com, secondary2.example.com 호스트에서 PostgreSQL이 실행되는 환경에서:

    gitlab_rails['db_load_balancing'] = { 'hosts' => ['primary.example.com', 'secondary1.example.com', 'secondary2.example.com'] }
    

    이 호스트들은 gitlab_rails['db_port']로 구성된 동일한 포트에서 접근 가능해야 합니다.

  3. 파일을 저장하고 GitLab을 재구성합니다.

서비스 디스커버리#

서비스 디스커버리를 사용하면 GitLab이 PostgreSQL 호스트 목록을 자동으로 검색할 수 있습니다. DNS A 레코드를 주기적으로 확인하여 반환된 IP 주소를 복제본 주소로 사용합니다. 서비스 디스커버리를 사용하려면 DNS 서버와 보조 서버의 IP 주소가 포함된 A 레코드가 필요합니다.

Linux 패키지 설치를 사용하는 경우 제공된 Consul 서비스가 DNS 서버로 작동하며 postgresql-ha.service.consul 레코드를 통해 PostgreSQL 주소를 반환합니다. 다음 다이어그램은 이 배포 모델을 보여줍니다:

PlantUML 다이어그램 (38줄)
소스 코드 보기
@startuml
!theme plain
card "**Internal Load Balancer**" as ilb
skinparam linetype ortho

together { collections "GitLab Rails x3" as gitlab collections "Sidekiq x4" as sidekiq }

collections "Consul x3" as consul

card "Database" as database { collections "PGBouncer x3\n//Consul//" as pgbouncer

card "PostgreSQL //Primary//\n//Patroni//\n//PgBouncer//\n//Consul//" as postgres_primary collections "PostgreSQL //Secondary// x2\n//Patroni//\n//PgBouncer//\n//Consul//" as postgres_secondary

pgbouncer --> postgres_primary postgres_primary .r-> postgres_secondary }

gitlab --> ilb gitlab -[hidden]-> pgbouncer gitlab .[norank]-> postgres_primary gitlab .[norank]-> postgres_secondary

sidekiq --> ilb sidekiq -[hidden]-> pgbouncer sidekiq .[norank]-> postgres_primary sidekiq .[norank]-> postgres_secondary

ilb --> pgbouncer

consul -r-> pgbouncer consul .[norank]r-> postgres_primary consul .[norank]r-> postgres_secondary @enduml

Consul로 서비스 디스커버리를 구성하려면:

  1. 각 GitLab Rails / Sidekiq 노드에서 /etc/gitlab/gitlab.rb를 편집하고 다음을 추가합니다:

    gitlab_rails['db_load_balancing'] = { 'discover' => {
        'nameserver' => 'localhost'
        'record' => 'postgresql-ha.service.consul'
        'record_type' => 'A'
        'port' => '8600'
        'interval' => '60'
        'disconnect_timeout' => '120'
      }
    }
    
  2. 변경 사항이 적용되도록 파일을 저장하고 GitLab을 재구성합니다.

옵션 설명 기본값
nameserver DNS 레코드 조회에 사용할 네임서버. localhost
record 조회할 레코드. 이 옵션은 서비스 디스커버리가 작동하려면 필수입니다.
record_type 조회할 선택적 레코드 유형. A 또는 SRV 중 하나일 수 있습니다. A
port 네임서버의 포트. 8600
interval DNS 레코드 확인 사이의 최소 시간(초). 60
disconnect_timeout 호스트 목록이 업데이트된 후 이전 연결이 닫히는 시간(초). 120
use_tcp UDP 대신 TCP를 사용하여 DNS 리소스 조회. false
max_replica_pools 각 GitLab 프로세스가 연결하는 최대 복제본 수. 서비스 디스커버리를 사용할 때만 적용됩니다. 이 한도가 없으면 모든 프로세스가 모든 복제본에 연결합니다. 많은 복제본과 많은 GitLab 노드를 함께 실행할 때 사용합니다. nil

record_typeSRV로 설정된 경우 GitLab은 라운드 로빈을 사용하고 레코드의 weightpriority를 무시합니다. SRV 레코드는 보통 IP 대신 호스트 이름을 반환하기 때문에 GitLab은 SRV 응답의 추가 섹션에서 IP 주소를 찾습니다. 호스트 이름에 대한 IP를 찾을 수 없으면 GitLab은 구성된 nameserver에 해당 호스트 이름에 대한 ANY 레코드를 쿼리하여 A 또는 AAAA 레코드를 찾습니다. IP를 확인할 수 없으면 GitLab은 해당 호스트 이름을 순환에서 제거합니다.

interval 값은 확인 사이의 최소 시간을 지정합니다. A 레코드의 TTL이 이 값보다 큰 경우 서비스 디스커버리는 해당 TTL을 따릅니다. 예를 들어 TTL이 90초이면 서비스 디스커버리는 다시 확인하기 전에 최소 90초를 기다립니다.

호스트 목록이 업데이트될 때 이전 연결이 종료되는 데 시간이 걸릴 수 있습니다. disconnect_timeout을 사용하여 이 작업에 걸리는 시간의 상한을 설정할 수 있습니다.

오래된 읽기#

히스토리
  • GitLab 14.0에서 GitLab Premium에서 GitLab Free로 이동.

GitLab은 읽기를 보조 서버로 라우팅하기 전에 각 보조 서버의 복제 상태를 확인합니다. 보조 서버가 기본보다 너무 뒤처져 있으면 따라잡을 때까지 건너뜁니다.

옵션 설명 기본값
max_replication_difference 보조 서버가 최근에 데이터를 복제하지 않은 경우 보조 서버가 뒤처질 수 있는 데이터 양(바이트). 8 MB
max_replication_lag_time 건너뛰기 전에 보조 서버가 뒤처질 수 있는 최대 시간(초). 60초
replica_check_interval 보조 서버 상태 확인 사이의 최소 시간(초). 60초

기본값은 대부분의 환경에 충분합니다.

호스트 목록과 함께 이 옵션을 구성하려면 다음 예시를 사용합니다:

gitlab_rails['db_load_balancing'] = {
  'hosts' => ['primary.example.com', 'secondary1.example.com', 'secondary2.example.com'],
  'max_replication_difference' => 16777216, # 16 MB
  'max_replication_lag_time' => 30,
  'replica_check_interval' => 30
}

로깅#

로드 밸런서는 database_load_balancing.log에 다음과 같은 다양한 이벤트를 기록합니다:

  • 호스트가 오프라인으로 표시될 때.
  • 호스트가 다시 온라인 상태가 될 때.
  • 모든 보조 서버가 오프라인 상태일 때.
  • 쿼리 충돌로 인해 다른 호스트에서 읽기가 재시도될 때.

로그는 각 항목이 최소한 다음을 포함하는 JSON 객체로 구조화됩니다:

  • 필터링에 유용한 event 필드.
  • 사람이 읽을 수 있는 message 필드.
  • 이벤트별 메타데이터. 예: db_host.
  • 항상 기록되는 컨텍스트 정보. 예: severitytime.

예:

{"severity":"INFO","time":"2019-09-02T12:12:01.728Z","correlation_id":"abcdefg","event":"host_online","message":"Host came back online","db_host":"111.222.333.444","db_port":null,"tag":"rails.database_load_balancing","environment":"production","hostname":"web-example-1","fqdn":"gitlab.example.com","path":null,"params":null}

데이터베이스 로드 밸런싱 작동 방식#

쿼리 균형 조정#

읽기 쿼리는 구성된 모든 데이터베이스 호스트에 분산됩니다. 쓰기 작업은 구성된 복제본 수와 상관없이 항상 기본에서 실행됩니다.

기본 고정#

쓰기 후 GitLab은 최대 30초 동안 해당 사용자의 읽기를 기본으로 일시적으로 라우팅합니다. GitLab은 항상 전체 30초를 기다리지 않고 복제본이 따라잡는 즉시 복제본 사용으로 되돌아갑니다. 백그라운드 작업도 오래된 데이터를 방지하기 위해 쓰기 후 읽기 전에 복제본이 따라잡을 때까지 기다립니다.

장애 조치 처리#

보조 서버를 사용할 수 없게 되면 로드 밸런서는 다음 사용 가능한 호스트로 라우팅합니다. 사용 가능한 보조 서버가 없으면 읽기는 기본으로 폴백됩니다.

쓰기가 실패하면 작업이 최대 3번 재시도됩니다. 데이터베이스 서버를 재시작해도 사용자에게 즉시 오류가 발생하지 않습니다.

데이터베이스 로드 밸런싱

GitLab v19.2
Tier: Free, Premium, Ultimate
Offering: GitLab Self-Managed
원문 보기
요약

데이터베이스 로드 밸런싱을 사용하면 읽기 쿼리가 여러 PostgreSQL 노드에 분산되어 성능이 향상되고 기본 데이터베이스의 부하가 줄어듭니다. 데이터베이스 로드 밸런싱을 활성화하려면: 외부 데이터베이스 서비스의 경우 db_load_balancing 구성만 필요합니다.

데이터베이스 로드 밸런싱을 사용하면 읽기 쿼리가 여러 PostgreSQL 노드에 분산되어 성능이 향상되고 기본 데이터베이스의 부하가 줄어듭니다. 쓰기 작업은 항상 기본에서 실행됩니다. GitLab은 외부 로드 밸런서 없이 쿼리 라우팅을 자동으로 처리합니다.

요구 사항#

데이터베이스 로드 밸런싱을 활성화하려면:

  • PostgreSQL에 기본을 복제하는 하나 이상의 보조 노드가 있어야 합니다.
  • 각 노드가 동일한 포트와 동일한 자격 증명으로 접근 가능해야 합니다.

외부 데이터베이스 서비스의 경우 db_load_balancing 구성만 필요합니다. 연결 풀링은 대규모에서 연결 수를 관리하는 데 도움이 될 수 있지만, 올바른 접근 방식은 공급자에 따라 다르며 이 가이드의 범위를 벗어납니다. 연결 관리 지침은 연결 관리를 참조하세요.

Note

AWS RDS Proxy는 GitLab에서 사용하도록 검증되지 않았습니다.

Linux 패키지 설치의 경우 데이터베이스 로드 밸런싱을 활성화하기 전에 다중 노드 HA PostgreSQL을 구성해야 합니다. 자세한 내용은 다중 노드 설정 구성을 참조하세요.

복제본 수#

복제본 수에는 제한이 없습니다. 실제로는 특히 세 개의 가용 영역에 분산된 환경에서 세 개가 일반적인 시작점입니다. Consul 및 Redis Sentinel을 포함한 여러 GitLab 구성 요소는 정족수(quorum)에 의존하며 홀수 개의 노드를 필요로 합니다. 데이터베이스 복제본 수를 이 패턴에 맞추면 아키텍처가 더 일관되고, 재해 복구 커버리지가 향상되며, 단일 가용 영역 장애의 영향이 제한됩니다. 규모가 작은 환경은 두 개의 복제본으로 시작하여 부하가 증가함에 따라 더 추가할 수 있습니다.

규모별 지침은 참조 아키텍처 문서를 참조하세요.

데이터베이스 로드 밸런싱 구성#

데이터베이스 로드 밸런싱은 다음 두 가지 방법 중 하나로 구성할 수 있습니다:

  • 호스트: PostgreSQL 호스트의 정적 목록. 구성이 더 간단하며 대부분의 환경에 적합합니다.
  • 서비스 디스커버리: PostgreSQL 호스트 목록을 반환하는 DNS 레코드. Consul을 사용하는 Linux 패키지 HA 설정처럼 복제본 목록이 동적으로 변경될 때 사용합니다.

호스트#

호스트 목록에 기본을 포함하는 것은 선택 사항입니다. 포함하면 기본이 복제본과 함께 읽기 쿼리의 대상이 되어 보조 서버의 전체 부하가 줄어듭니다. 기본이 이미 지속적으로 높은 부하를 받고 있다면 제외하여 쓰기용 용량을 확보할 수 있습니다. 기본은 이 목록에 포함되는지 여부와 상관없이 항상 쓰기 쿼리를 처리합니다.

호스트 목록을 구성하려면 균형을 조정하려는 각 환경의 모든 GitLab Rails 및 Sidekiq 노드에서 다음 단계를 수행합니다:

  1. /etc/gitlab/gitlab.rb 파일을 편집합니다.

  2. gitlab_rails['db_load_balancing']에서 균형을 조정할 데이터베이스 호스트 배열을 만듭니다. 예를 들어 primary.example.com, secondary1.example.com, secondary2.example.com 호스트에서 PostgreSQL이 실행되는 환경에서:

    gitlab_rails['db_load_balancing'] = { 'hosts' => ['primary.example.com', 'secondary1.example.com', 'secondary2.example.com'] }
    

    이 호스트들은 gitlab_rails['db_port']로 구성된 동일한 포트에서 접근 가능해야 합니다.

  3. 파일을 저장하고 GitLab을 재구성합니다.

서비스 디스커버리#

서비스 디스커버리를 사용하면 GitLab이 PostgreSQL 호스트 목록을 자동으로 검색할 수 있습니다. DNS A 레코드를 주기적으로 확인하여 반환된 IP 주소를 복제본 주소로 사용합니다. 서비스 디스커버리를 사용하려면 DNS 서버와 보조 서버의 IP 주소가 포함된 A 레코드가 필요합니다.

Linux 패키지 설치를 사용하는 경우 제공된 Consul 서비스가 DNS 서버로 작동하며 postgresql-ha.service.consul 레코드를 통해 PostgreSQL 주소를 반환합니다. 다음 다이어그램은 이 배포 모델을 보여줍니다:

PlantUML 다이어그램 (38줄)
소스 코드 보기
@startuml
!theme plain
card "**Internal Load Balancer**" as ilb
skinparam linetype ortho

together { collections "GitLab Rails x3" as gitlab collections "Sidekiq x4" as sidekiq }

collections "Consul x3" as consul

card "Database" as database { collections "PGBouncer x3\n//Consul//" as pgbouncer

card "PostgreSQL //Primary//\n//Patroni//\n//PgBouncer//\n//Consul//" as postgres_primary collections "PostgreSQL //Secondary// x2\n//Patroni//\n//PgBouncer//\n//Consul//" as postgres_secondary

pgbouncer --> postgres_primary postgres_primary .r-> postgres_secondary }

gitlab --> ilb gitlab -[hidden]-> pgbouncer gitlab .[norank]-> postgres_primary gitlab .[norank]-> postgres_secondary

sidekiq --> ilb sidekiq -[hidden]-> pgbouncer sidekiq .[norank]-> postgres_primary sidekiq .[norank]-> postgres_secondary

ilb --> pgbouncer

consul -r-> pgbouncer consul .[norank]r-> postgres_primary consul .[norank]r-> postgres_secondary @enduml

Consul로 서비스 디스커버리를 구성하려면:

  1. 각 GitLab Rails / Sidekiq 노드에서 /etc/gitlab/gitlab.rb를 편집하고 다음을 추가합니다:

    gitlab_rails['db_load_balancing'] = { 'discover' => {
        'nameserver' => 'localhost'
        'record' => 'postgresql-ha.service.consul'
        'record_type' => 'A'
        'port' => '8600'
        'interval' => '60'
        'disconnect_timeout' => '120'
      }
    }
    
  2. 변경 사항이 적용되도록 파일을 저장하고 GitLab을 재구성합니다.

옵션 설명 기본값
nameserver DNS 레코드 조회에 사용할 네임서버. localhost
record 조회할 레코드. 이 옵션은 서비스 디스커버리가 작동하려면 필수입니다.
record_type 조회할 선택적 레코드 유형. A 또는 SRV 중 하나일 수 있습니다. A
port 네임서버의 포트. 8600
interval DNS 레코드 확인 사이의 최소 시간(초). 60
disconnect_timeout 호스트 목록이 업데이트된 후 이전 연결이 닫히는 시간(초). 120
use_tcp UDP 대신 TCP를 사용하여 DNS 리소스 조회. false
max_replica_pools 각 GitLab 프로세스가 연결하는 최대 복제본 수. 서비스 디스커버리를 사용할 때만 적용됩니다. 이 한도가 없으면 모든 프로세스가 모든 복제본에 연결합니다. 많은 복제본과 많은 GitLab 노드를 함께 실행할 때 사용합니다. nil

record_typeSRV로 설정된 경우 GitLab은 라운드 로빈을 사용하고 레코드의 weightpriority를 무시합니다. SRV 레코드는 보통 IP 대신 호스트 이름을 반환하기 때문에 GitLab은 SRV 응답의 추가 섹션에서 IP 주소를 찾습니다. 호스트 이름에 대한 IP를 찾을 수 없으면 GitLab은 구성된 nameserver에 해당 호스트 이름에 대한 ANY 레코드를 쿼리하여 A 또는 AAAA 레코드를 찾습니다. IP를 확인할 수 없으면 GitLab은 해당 호스트 이름을 순환에서 제거합니다.

interval 값은 확인 사이의 최소 시간을 지정합니다. A 레코드의 TTL이 이 값보다 큰 경우 서비스 디스커버리는 해당 TTL을 따릅니다. 예를 들어 TTL이 90초이면 서비스 디스커버리는 다시 확인하기 전에 최소 90초를 기다립니다.

호스트 목록이 업데이트될 때 이전 연결이 종료되는 데 시간이 걸릴 수 있습니다. disconnect_timeout을 사용하여 이 작업에 걸리는 시간의 상한을 설정할 수 있습니다.

오래된 읽기#

히스토리
  • GitLab 14.0에서 GitLab Premium에서 GitLab Free로 이동.

GitLab은 읽기를 보조 서버로 라우팅하기 전에 각 보조 서버의 복제 상태를 확인합니다. 보조 서버가 기본보다 너무 뒤처져 있으면 따라잡을 때까지 건너뜁니다.

옵션 설명 기본값
max_replication_difference 보조 서버가 최근에 데이터를 복제하지 않은 경우 보조 서버가 뒤처질 수 있는 데이터 양(바이트). 8 MB
max_replication_lag_time 건너뛰기 전에 보조 서버가 뒤처질 수 있는 최대 시간(초). 60초
replica_check_interval 보조 서버 상태 확인 사이의 최소 시간(초). 60초

기본값은 대부분의 환경에 충분합니다.

호스트 목록과 함께 이 옵션을 구성하려면 다음 예시를 사용합니다:

gitlab_rails['db_load_balancing'] = {
  'hosts' => ['primary.example.com', 'secondary1.example.com', 'secondary2.example.com'],
  'max_replication_difference' => 16777216, # 16 MB
  'max_replication_lag_time' => 30,
  'replica_check_interval' => 30
}

로깅#

로드 밸런서는 database_load_balancing.log에 다음과 같은 다양한 이벤트를 기록합니다:

  • 호스트가 오프라인으로 표시될 때.
  • 호스트가 다시 온라인 상태가 될 때.
  • 모든 보조 서버가 오프라인 상태일 때.
  • 쿼리 충돌로 인해 다른 호스트에서 읽기가 재시도될 때.

로그는 각 항목이 최소한 다음을 포함하는 JSON 객체로 구조화됩니다:

  • 필터링에 유용한 event 필드.
  • 사람이 읽을 수 있는 message 필드.
  • 이벤트별 메타데이터. 예: db_host.
  • 항상 기록되는 컨텍스트 정보. 예: severitytime.

예:

{"severity":"INFO","time":"2019-09-02T12:12:01.728Z","correlation_id":"abcdefg","event":"host_online","message":"Host came back online","db_host":"111.222.333.444","db_port":null,"tag":"rails.database_load_balancing","environment":"production","hostname":"web-example-1","fqdn":"gitlab.example.com","path":null,"params":null}

데이터베이스 로드 밸런싱 작동 방식#

쿼리 균형 조정#

읽기 쿼리는 구성된 모든 데이터베이스 호스트에 분산됩니다. 쓰기 작업은 구성된 복제본 수와 상관없이 항상 기본에서 실행됩니다.

기본 고정#

쓰기 후 GitLab은 최대 30초 동안 해당 사용자의 읽기를 기본으로 일시적으로 라우팅합니다. GitLab은 항상 전체 30초를 기다리지 않고 복제본이 따라잡는 즉시 복제본 사용으로 되돌아갑니다. 백그라운드 작업도 오래된 데이터를 방지하기 위해 쓰기 후 읽기 전에 복제본이 따라잡을 때까지 기다립니다.

장애 조치 처리#

보조 서버를 사용할 수 없게 되면 로드 밸런서는 다음 사용 가능한 호스트로 라우팅합니다. 사용 가능한 보조 서버가 없으면 읽기는 기본으로 폴백됩니다.

쓰기가 실패하면 작업이 최대 3번 재시도됩니다. 데이터베이스 서버를 재시작해도 사용자에게 즉시 오류가 발생하지 않습니다.