데이터베이스 로드 밸런싱
데이터베이스 로드 밸런싱을 사용하면 읽기 전용 쿼리를 여러 PostgreSQL 노드에 분산하여 성능을 향상시킬 수 있습니다.
이 기능은 GitLab Rails 및 Sidekiq에서 네이티브로 제공되며, 외부 종속성 없이 라운드 로빈 방식으로 데이터베이스 읽기 쿼리를 밸런스 조정할 수 있습니다.
데이터베이스 로드 밸런싱 활성화 요구 사항
데이터베이스 로드 밸런싱을 활성화하려면 다음 사항을 확인하세요:
- HA(PostgreSQL(Binary Large Object)) 설정에 복제된 기본 노드가 하나 이상 있어야 합니다.
- 각 PostgreSQL 노드가 동일한 자격 증명으로 동일한 포트에 연결되어 있어야 합니다.
Linux 패키지 설치의 경우, 멀티 노드 설정을 구성할 때 각 PostgreSQL 노드에 PgBouncer를 구성해야 합니다.
데이터베이스 로드 밸런싱 구성
데이터베이스 로드 밸런싱은 다음 중 하나의 방법으로 구성할 수 있습니다:
호스트
호스트 목록을 구성하려면 각 환경의 모든 GitLab Rails 및 Sidekiq 노드에서 다음 단계를 수행하세요:
-
/etc/gitlab/gitlab.rb
파일을 편집합니다. -
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']
로 구성된 동일한 포트에서 Reachable해야 합니다. - 파일을 저장하고 GitLab 다시 구성을 수행합니다.
참고: 기본을 호스트 목록에 추가하는 것은 선택 사항이지만 권장됩니다. 이렇게 하면 기본이 밸런스 조정된 읽기 쿼리에 대한 자격이 부여되어 용량이 있는 경우 시스템 성능이 향상됩니다. 매우 높은 트래픽 인스턴스에서는 기본이 읽기 복제본으로 사용될 수 있는 용량이 없을 수 있습니다. 기본은 여부와 관계없이 쓰기 쿼리에 사용됩니다.
서비스 검색
서비스 검색을 사용하면 GitLab이 사용할 PostgreSQL 호스트 목록을 자동으로 검색할 수 있습니다. 정기적으로 DNS ‘A’ 레코드를 확인하여이 레코드에서 반환된 IP를 두 번째로 사용하는 주소로 사용합니다. 서비스 검색이 작동하려면 DNS 서버와 ‘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
|
port
| 네임 서버의 포트 | 8600 |
interval
| DNS 레코드를 확인하는 최소 시간(초) | 60 |
disconnect_timeout
| 호스트 목록이 업데이트된 후 이전 연결이 종료되기까지의 시간 제한, (초) | 120 |
use_tcp
| UDP 대신 TCP를 사용하여 DNS 리소스 조회를 수행할지 여부 | false |
max_replica_pools
| 각 Rails 프로세스가 연결하는 최대 레플리카 수. 많은 Postgres 레플리카와 많은 Rails 프로세스를 실행하는 경우 유용합니다. 무제한으로 설정되지 않은 경우 기본 동작은 무제한입니다. | nil |
record_type
를 SRV
로 설정하면 GitLab은 여전히 라운드 로빈 알고리즘을 사용하고 레코드의 ‘중량’과 ‘우선 순위’를 무시합니다. SRV
레코드는 대개 IP 대신 호스트 이름을 반환하기 때문에 GitLab은 SRV
응답의 추가 섹션에서 반환된 호스트 이름의 IP를 찾아야 합니다. 호스트 이름에 대한 IP를 찾을 수 없는 경우 GitLab은 A
또는 AAAA
레코드를 찾기 위해 구성된 nameserver
에 대해 각 호스트 이름에 대해 ANY
레코드를 조회해야 하며 결국 회전에서 이 호스트 이름을 삭제해야 합니다.
interval
값은 확인 사이의 최소 시간을 지정합니다. ‘A’ 레코드의 TTL이이 값보다 크면 서비스 검색은 해당 TTL을 따릅니다. 예를 들어 ‘A’ 레코드의 TTL이 90초이면 서비스 검색은 ‘A’ 레코드를 다시 확인하기 전에 적어도 90초 기다립니다.
호스트 목록이 업데이트되면 이전 연결이 종료되는 데 시간이 오래 걸릴 수 있습니다. ‘disconnect_timeout’ 설정을 사용하여 이전 데이터베이스 연결이 종료되는 데 소요되는 시간을 상한으로 지정할 수 있습니다.
스테일된 읽기 처리
- 14.0에서 GitLab 프리미엄에서 GitLab 무료로 이동.
오래된 보조에서 읽기를 방지하기 위해 로드 밸런서는 주(primary)와 동기화되었는지 확인합니다. 데이터가 충분히 최신인 경우 보조가 사용되고, 그렇지 않으면 무시됩니다. 이러한 확인의 부하를 줄이기 위해 일정 간격으로만 수행합니다.
이 동작에 영향을 주는 세 가지 구성 옵션이 있습니다.
옵션 | 설명 | 기본값 |
---|---|---|
max_replication_difference
| 어느 정도의 데이터(바이트)까지 보조가 데이터를 복제하지 않아도 되는지 설정합니다. | 8MB |
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, # 16MB
'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
쿼리는 주어진 모든 호스트 사이에서 균형을 이룹니다. 트랜잭션을 포함한 모든 것은 주(primary)에서 실행됩니다. SELECT ... FOR UPDATE
와 같은 쿼리도 주(primary)에서 실행됩니다.
준비된 문장
준비된 문장은 로드 밸런싱과 잘 작동하지 않으며 로드 밸런싱이 활성화되면 자동으로 비활성화됩니다. 이로 인해 응답 시간에 영향을 끼치지 않아야 합니다.
주(primary) 고수
쓰기가 수행된 후, GitLab은 일정 기간 동안 사용자 범위로 주(primary)를 사용하게 됩니다. 보조가 잡아잡는 경우 또는 30초가 지나면 GitLab은 보조를 다시 사용하도록 돌아갑니다.
장애 조치
장애 조치나 응답이 없는 데이터베이스의 경우, 로드 밸런서는 다음 사용 가능한 호스트를 사용하도록 시도합니다. 보조가 없는 경우에는 작업이 대신 주(primary)에서 수행됩니다.
데이터를 쓰는 동안 연결 오류가 발생하면 작업은 지수적 백오프를 사용하여 최대 3회까지 재시도합니다.
로드 밸런싱을 사용할 때, 데이터베이스 서버를 안전하게 다시 시작할 수 있어야 하며 이로 인해 사용자에게 오류가 즉시 표시되지는 않아야 합니다.
개발 가이드
데이터베이스 로드 밸런싱에 대한 자세한 개발 가이드는 개발 문서를 참조하십시오.