데이터베이스 로드 밸런싱

Tier: Free, Premium, Ultimate Offering: Self-Managed

데이터베이스 로드 밸런싱을 사용하면 읽기 전용 쿼리를 여러 PostgreSQL 노드에 분산하여 성능을 향상시킬 수 있습니다.

이 기능은 GitLab Rails 및 Sidekiq에서 기본 제공되며 외부 의존성 없이 라운드로빈 방식으로 데이터베이스 읽기 쿼리를 균형있게 구성할 수 있습니다.

데이터베이스 로드 밸런싱을 활성화하는 요구 사항

데이터베이스 로드 밸런싱을 활성화하려면 다음 사항을 확인하세요:

  • HA(PostgreSQL 고 가용성) 설정에 기본을 복제하는 하나 이상의 보조 노드가 있어야 합니다.
  • 각 PostgreSQL 노드가 동일한 자격 증명으로 동일한 포트에 연결되어 있어야 합니다.

Linux 패키지 설치의 경우 다중 노드 설정을 구성할 때 각 PostgreSQL 노드에 PgBouncer가 구성되어 있어야 합니다.

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

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

  • (권장) 호스트: PostgreSQL 호스트 디렉터리.
  • 서비스 탐색: PostgreSQL 호스트 디렉터리을 반환하는 DNS 레코드.

호스트

호스트 디렉터리을 구성하려면 균형을 맞추려는 각 환경의 모든 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을 재구성합니다.
note
Primary를 호스트 디렉터리에 추가하는 것은 선택 사항이지만 권장됩니다. 이렇게 하면 Primary가 로드 밸런스된 읽기 쿼리를 처리할 수 있으며 시스템 성능을 향상시킵니다. 매우 높은 트래픽의 경우 Primary에는 읽기 복제본을 처리할 용량이 없을 수도 있습니다. Primary는 여기에 포함되지 않았더라도 쓰기 쿼리에 사용됩니다.

서비스 탐색

서비스 탐색을 사용하면 GitLab이 사용할 PostgreSQL 호스트 디렉터리을 자동으로 검색할 수 있습니다. 일정 간격으로 DNS A 레코드를 확인하여이 레코드가 반환한 IP를 두 번째 서버의 주소로 사용합니다. 서비스 탐색을 사용하려면 DNS 서버와 두 번째 서버의 IP를 포함하는 A 레코드가 필요합니다.

Linux 패키지 설치를 사용하는 경우 제공된 Consul 서비스는 postgresql-ha.service.consul 레코드를 통해 PostgreSQL 주소를 반환합니다. 예를 들어:

  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'
    }
  }
  1. 파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
옵션 설명 기본값
nameserver DNS 레코드 조회에 사용할 이름 서버. localhost
record 조회할 레코드. 서비스 탐색을 활성화하려면 이 옵션이 필요합니다.  
record_type 조회할 선택적 레코드 유형. A 또는 SRV 중 하나가 될 수 있습니다. A
port 이름 서버의 포트. 8600
interval DNS 레코드를 확인하는 간격(초). 60
disconnect_timeout 호스트 디렉터리이 업데이트된 후 이전 연결이 종료되기까지의 시간(초). 120

record_typeSRV로 설정된 경우 GitLab은 여전히 round-robin 알고리즘을 사용하고 레코드의 weightpriority를 무시합니다. 왜냐하면 SRV 레코드는 일반적으로 IP 대신 호스트 이름을 반환하며 GitLab은 반환된 호스트 이름의 IP를 찾아야 합니다. 호스트 이름에 대한 IP가 없는 경우 GitLab은 해당 호스트 이름에 대해 A 또는 AAAA 레코드를 찾기 위해 구성된 nameserver를 쿼리해야합니다. 최종적으로 이 호스트 이름의 IP를 해결할 수 없는 경우에는 회전은 해당 호스트를 삭제해야합니다.

interval 값은 확인 사이의 최소 시간을 지정합니다. A 레코드의 TTL이 이 값보다 크면 서비스 탐색은 해당 TTL을 준수합니다. 예를 들어, A 레코드의 TTL이 90 초인 경우, 서비스 탐색은 90 초 이상 기다린 후 다시 A 레코드를 확인합니다.

호스트 디렉터리이 업데이트되면 이전 연결이 종료하는 데 시간이 오래 걸릴 수 있습니다. disconnect_timeout 설정을 사용하여 모든 이전 데이터베이스 연결이 종료되는 데 걸리는 시간을 상한으로 설정할 수 있습니다.

스테일한 읽기 처리

  • 이전에 GitLab Premium에서 GitLab 무료로 이동됨 (14.0).

중요 참고사항: 후지료 원격에서 녹화된 데이터를 너무 오래 전에 읽으면, 무효화된 상태일 수 있어 발생할 수 있는 문제에 관해 아래와 같이 체크합니다. 이때, 로드 밸런서는 자주 이 체크를 하는 게 아니라 특정 간격으로만 이 체크를 수행하여 체크에 따른 부하를 줄입니다.

이러한 동작을 영향을 주는 세 가지 구성 옵션이 있습니다.

구성 옵션은 다음과 같습니다.

옵션 설명 기본값
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}

구현 세부 정보

쿼리 균형

읽기 전용 SELECT 쿼리는 주어진 호스트 전체로 분배됩니다. 트랜잭션을 포함한 기타 모든 것(거래)은 기본으로 실행됩니다. SELECT ... FOR UPDATE와 같은 쿼리는 주로 기본에서 실행됩니다.

준비된 문

준비된 문은 로드 밸런싱과 잘 작동하지 않으며, 로드 밸런싱을 활성화하면 자동으로 비활성화됩니다. 이것이 응답 시간에 영향을 미치지 않아야 합니다.

기본 고정

쓰기가 이루어진 후, GitLab은 일정 기간 동안 쓰는 사용자로 범위지어(유저 지정 파싱) 기본을 사용하게 됩니다. 인 수가 업데이트된 경우나 30초 후에 GitLab는 다시 두번째를 사용하게 됩니다.

장애 조치 처리

장애 조치 또는 응답하지 않는 데이터베이스 발생 시, 로드 밸런서는 다음 이용 가능한 호스트를 사용하려고 시도합니다. 두번째 서버가 이용 불가능한 경우, 작업은 대신 기본에서 수행됩니다.

데이터를 쓸 때 연결 오류가 발생하면, 지수적 백오프를 사용하여 최대 3번까지 작업이 다시 시도됩니다.

로드 밸런싱을 사용할 때는 데이터베이스 서버를 재시작해도 사용자에게 오류가 즉시 표시되지 않아야 합니다.

개발 가이드

데이터베이스 로드 밸런싱에 대한 자세한 개발 가이드는 개발 설명서를 참조하세요.