데이터베이스 부하 분산
Offering: Self-managed
데이터베이스 부하 분산을 사용하면 읽기 전용 쿼리를 여러 PostgreSQL 노드에 분산시켜 성능을 증가시킬 수 있습니다.
이 기능은 GitLab Rails와 Sidekiq에서 기본적으로 제공되며, 외부 의존성 없이 데이터베이스 읽기 쿼리를 라운드 로빈 방식으로 균형을 맞추도록 구성할 수 있습니다:
데이터베이스 부하 분산을 활성화하기 위한 요구 사항
데이터베이스 부하 분산을 활성화하려면 다음을 확인하세요:
- HA PostgreSQL 설정에 하나 이상의 보조 노드가 기본(primary)을 복제해야 합니다.
- 각 PostgreSQL 노드는 동일한 자격증명을 사용하고 동일한 포트에 연결되어야 합니다.
Linux 패키지 설치의 경우, 각 PostgreSQL 노드에서 모든 부하 분산 연결을 풀링하기 위해 PgBouncer가 구성되어 있어야 합니다 다중 노드 설정 구성.
데이터베이스 부하 분산 구성
데이터베이스 부하 분산은 두 가지 방법 중 하나로 구성할 수 있습니다:
호스트
호스트 목록을 구성하려면, 균형을 맞추고자 하는 각 환경의 모든 GitLab Rails 및 Sidekiq 노드에서 다음 단계를 수행하세요:
-
/etc/gitlab/gitlab.rb
파일을 편집합니다. -
gitlab_rails['db_load_balancing']
에서 균형을 맞추고자 하는 데이터베이스 호스트의 배열을 생성합니다. 예를 들어 PostgreSQL이 호스트primary.example.com
,secondary1.example.com
,secondary2.example.com
에서 실행되는 환경에서는:gitlab_rails['db_load_balancing'] = { 'hosts' => ['primary.example.com', 'secondary1.example.com', 'secondary2.example.com'] }
이러한 호스트는
gitlab_rails['db_port']
로 구성된 동일한 포트에서 접근 가능해야 합니다. - 파일을 저장하고 GitLab 재구성을 수행합니다.
참고:
호스트 목록에 기본 호스트를 추가하는 것은 선택 사항이지만 권장됩니다.
이렇게 하면 기본 호스트가 부하 분산된 읽기 쿼리에 적합하게 되며, 기본 호스트가 이러한 쿼리를 처리할 수 있는 경우 시스템 성능이 향상됩니다.
트래픽이 매우 많은 인스턴스는 기본 호스트에 읽기 복제본으로서의 용량이 부족할 수 있습니다.
기본 호스트는 이 목록에 포함되었든 아니든 쓰기 쿼리에 사용됩니다.
서비스 디스커버리
서비스 디스커버리는 GitLab이 사용할 PostgreSQL 호스트 목록을 자동으로 검색할 수 있게 해줍니다. 주기적으로 DNS A
레코드를 확인하며, 이 레코드에서 반환된 IP를 보조 주소로 사용합니다. 서비스 디스커버리가 작동하려면 DNS 서버와 보조 IP 주소를 포함하는 A
레코드만 있으면 됩니다.
Linux 패키지 설치를 사용할 때 제공된 Consul 서비스는 DNS 서버로 작동하며 postgresql-ha.service.consul
레코드를 통해 PostgreSQL 주소를 반환합니다. 예를 들어:
-
각 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' } }
-
파일을 저장하고 GitLab을 재구성하여 변경 사항을 적용합니다.
옵션 | 설명 | 기본값 |
---|---|---|
nameserver |
DNS 레코드를 조회할 때 사용할 네임서버입니다. | localhost |
record |
조회할 레코드입니다. 이 옵션은 서비스 디스커버리가 작동하기 위해 필요합니다. | |
record_type |
조회할 선택적 레코드 유형입니다. A 또는 SRV 일 수 있습니다. |
A |
port |
네임서버의 포트입니다. | 8600 |
interval |
DNS 레코드를 확인하는 최소 시간(초)입니다. | 60 |
disconnect_timeout |
호스트 목록이 업데이트된 후 오래된 연결이 종료될 때까지의 시간(초)입니다. | 120 |
use_tcp |
DNS 리소스를 UDP 대신 TCP를 사용하여 조회합니다. | false |
max_replica_pools |
각 Rails 프로세스가 연결할 수 있는 최대 복제본 수입니다. 이 설정은 많은 Postgres 복제본과 많은 Rails 프로세스를 실행하는 경우 유용합니다. 이 한계가 없으면 기본적으로 모든 Rails 프로세스가 모든 복제본에 연결됩니다. 설정하지 않으면 기본 동작은 제한이 없습니다. | nil |
record_type
이 SRV
로 설정되면 GitLab은 라운드 로빈 알고리즘을 계속 사용하며 레코드의 weight
와 priority
를 무시합니다. SRV
레코드는 일반적으로 IP 대신 호스트 이름을 반환하므로, GitLab은 응답의 추가 섹션에서 반환된 호스트 이름의 IP를 찾아야 합니다. 호스트 이름에 대한 IP가 발견되지 않으면 GitLab은 해당 호스트 이름에 대해 구성된 nameserver
에 ANY
레코드를 쿼리하여 A
또는 AAAA
레코드를 찾고, IP를 확인할 수 없는 경우 해당 호스트 이름을 회전에서 제외합니다.
interval
값은 검사 간의 최소 시간을 지정합니다. A
레코드의 TTL이 이 값보다 크면 서비스 디스커버리는 해당 TTL을 존중합니다. 예를 들어, A
레코드의 TTL이 90초인 경우 서비스 디스커버리는 최소 90초 동안 A
레코드를 다시 확인하지 않습니다.
호스트 목록이 업데이트되면 이전 연결이 종료되는 데 시간이 걸릴 수 있습니다. disconnect_timeout
설정은 모든 오래된 데이터베이스 연결을 종료하는 데 걸리는 시간의 상한선을 적용하는 데 사용할 수 있습니다.
오래된 읽기 처리
- 14.0에서 GitLab Premium에서 GitLab Free로 이동됨.
구식 보조 데이터로부터의 읽기를 방지하기 위해 로드 밸런서는 해당 보조 데이터가 기본 데이터와 동기화되어 있는지 확인합니다. 데이터가 충분히 최신이라면 보조 데이터를 사용하고, 그렇지 않으면 무시합니다. 이러한 확인의 오버헤드를 줄이기 위해 우리는 특정 간격에서만 이들을 수행합니다.
이 동작에 영향을 미치는 세 가지 구성 옵션이 있습니다:
옵션 | 설명 | 기본값 |
---|---|---|
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
- 항상 로그로 기록되는 컨텍스트 정보. 예를 들어,
severity
와time
.
예를 들어:
{"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은 특정 기간 동안 기본을 사용합니다.
GitLab은 보조 데이터가 따라잡았거나 30초 후에 다시 보조로 돌아갑니다.
장애 조치 처리
장애 조치가 발생하거나 데이터베이스가 응답하지 않는 경우 로드 밸런서는 다음 사용할 수 있는 호스트를 사용하려고 시도합니다.
보조 데이터가 없으면 기본에서 작업이 수행됩니다.
데이터를 쓰는 동안 연결 오류가 발생하는 경우,
작업은 최대 3회까지 지수 백오프를 사용하여 재시도됩니다.
로드 밸런싱을 사용하는 경우 데이터를 안전하게 재시작할 수 있어야 하며, 이는 곧바로 사용자에게 오류를 제시하는 결과로 이어지지 않아야 합니다.
개발 가이드
데이터베이스 로드 밸런싱에 대한 자세한 개발 가이드는
개발 문서를 참조하세요.