동시성 제한
Gitaly를 실행하는 서버가 과부하되지 않도록 하기 위해 다음의 동시성을 제한할 수 있습니다:
- RPC
- 패킹 객체
이 제한은 고정되거나 적응형으로 설정할 수 있습니다.
경고: 환경에서 제한을 활성화하는 것은 주의해야 하며 예기치 않은 트래픽으로부터 보호하기 위해 특정 상황에서만 수행해야 합니다.
한계에 도달할 경우, 사용자가 부정적인 영향을 받는 연결 끊김이 발생합니다.
일관되고 안정적인 성능을 위해 노드 사양을 조정하거나 대규모 리포지토리 검토하기 또는 작업 부하를 탐색하는 것과 같은 다른 옵션을 먼저 고려해야 합니다.
RPC 동시성 제한
리포지토리를 클론하거나 풀할 때 다양한 RPC가 백그라운드에서 실행됩니다. 특히, Git 패킹 RPC:
-
SSHUploadPackWithSidechannel
(Git SSH용). -
PostUploadPackWithSidechannel
(Git HTTP용).
이 RPC는 많은 리소스를 소모할 수 있으며, 이는 다음과 같은 상황에서 상당한 영향을 미칠 수 있습니다:
- 예기치 않게 높은 트래픽
- 모범 사례를 따르지 않는 대규모 리포지토리에 대한 실행
Gitaly 서버가 이러한 상황에서 과부하되지 않도록 하기 위해 Gitaly 구성 파일에서 동시성 제한을 사용할 수 있습니다. 예를 들어:
# /etc/gitlab/gitlab.rb에서
gitaly['configuration'] = {
# ...
concurrency: [
{
rpc: '/gitaly.SmartHTTPService/PostUploadPackWithSidechannel',
max_per_repo: 20,
max_queue_wait: '1s',
max_queue_size: 10,
},
{
rpc: '/gitaly.SSHService/SSHUploadPackWithSidechannel',
max_per_repo: 20,
max_queue_wait: '1s',
max_queue_size: 10,
},
],
}
-
rpc
는 리포지토리당 동시성 제한을 설정하기 위한 RPC의 이름입니다. -
max_per_repo
는 주어진 RPC에 대해 리포지토리당 최대 비행 중인 RPC 호출 수입니다. -
max_queue_wait
는 Gitaly가 요청을 수락할 때까지 동시성 대기열에서 요청이 대기할 수 있는 최대 시간입니다. -
max_queue_size
는 Gitaly에서 요청이 거부되기 전에 동시성 대기열(각 RPC 방법당)의 최대 크기입니다.
이것은 주어진 RPC 호출에 대해 비행 중인 RPC 호출의 수를 제한합니다. 제한은 리포지토리마다 적용됩니다. 위의 예에서:
- Gitaly 서버에 의해 제공되는 각 리포지토리는 최대 20개의 동시
PostUploadPackWithSidechannel
및SSHUploadPackWithSidechannel
RPC 호출을 가질 수 있습니다. - 20개의 슬롯을 모두 사용한 리포지토리에 다른 요청이 들어오면, 해당 요청은 대기열에 추가됩니다.
- 요청이 대기열에서 1초 이상 대기하면 오류와 함께 거부됩니다.
- 대기열이 10을 초과하면, 이후 요청은 오류와 함께 거부됩니다.
참고: 이러한 제한에 도달하면 사용자가 연결이 끊깁니다.
Gitaly 로그 및 Prometheus를 사용하여 이 대기열의 동작을 관찰할 수 있습니다. 더 많은 정보는 관련 문서를 참조하세요.
패킹 객체 동시성 제한
- GitLab 15.11에 도입됨 플래그와 함께
gitaly_pack_objects_limiting_remote_ip
로. 기본적으로 비활성화됨.- GitLab 16.0에서 일반적으로 사용 가능. 기능 플래그
gitaly_pack_objects_limiting_remote_ip
가 제거됨.
Gitaly는 SSH 및 HTTPS 트래픽을 처리할 때 git-pack-objects
프로세스를 트리거하여 리포지토리를 클론하거나 풀할 수 있습니다. 이 프로세스는 pack-file
을 생성하며, 특히 예기치 않게 높은 트래픽이나 대규모 리포지토리에서 동시에 풀을 시도할 때 많은 리소스를 소모할 수 있습니다. GitLab.com에서는 느린 인터넷 연결을 가진 클라이언트와 관련된 문제도 관찰하고 있습니다.
Gitaly 서버가 과부하되지 않도록 하기 위해 Gitaly 구성 파일에서 패킹 객체 동시성 제한을 설정할 수 있습니다. 이 설정은 원격 IP 주소당 비행 중인 패킹 객체 프로세스의 수를 제한합니다.
경고: 이러한 제한을 환경에서 활성화하는 것은 조심스럽게 수행해야 하며 예기치 않은 트래픽으로부터 보호하기 위한 특정 상황에서만 수행해야 합니다. 한계에 도달하면 이 제한은 사용자를 연결이 끊깁니다. 일관되고 안정적인 성능을 위해 노드 사양 조정 또는 대규모 리포지토리 검토하기와 같은 다른 옵션을 먼저 탐색해야 합니다.
예제 구성:
# /etc/gitlab/gitlab.rb에서
gitaly['pack_objects_limiting'] = {
'max_concurrency' => 15,
'max_queue_length' => 200,
'max_queue_wait' => '60s',
}
-
max_concurrency
는 키당 비행 중인 패킹 객체 프로세스의 최대 수입니다. -
max_queue_length
는 Gitaly에서 요청이 거부되기 전에 동시성 대기열(키당)의 최대 크기입니다. -
max_queue_wait
는 Gitaly에서 요청을 수락하기 위해 동시성 대기열에서 대기할 수 있는 최대 시간입니다.
위의 예에서:
- 각 원격 IP는 Gitaly 노드에서 최대 15개의 동시 패킹 객체 프로세스를 가질 수 있습니다.
- 슬롯을 모두 사용한 IP에서 다른 요청이 들어오면, 해당 요청은 대기열에 추가됩니다.
- 요청이 대기열에서 1분 이상 대기하면 오류와 함께 거부됩니다.
- 대기열이 200을 초과하면, 이후 요청은 오류와 함께 거부됩니다.
패킹 객체 캐시가 활성화되면, 캐시가 부재할 경우에만 패킹 객체 제한이 적용됩니다. 더 많은 내용은 패킹 객체 캐시를 참조하세요.
Gitaly 로그 및 Prometheus를 사용하여 이 대기열의 동작을 관찰할 수 있습니다. 더 많은 정보는 Gitaly 패킹 객체 동시성 제한 모니터링을 참조하십시오.
적응형 동시성 제한
- 소개됨 GitLab 16.6에서.
Gitaly는 두 가지 동시성 한계를 지원합니다:
- 각 Gitaly RPC에 대해 최대 동시 비행 요청 수를 구성할 수 있는 RPC 동시성 한계. 이 한계는 RPC 및 저장소별로 구분됩니다.
- IP별로 동시 Git 데이터 전송 요청 수를 제한하는 패킹 객체 동시성 한계.
이 한계를 초과하면 다음 중 하나가 발생합니다:
- 요청이 대기열에 들어갑니다.
- 대기열이 가득 차거나 요청이 대기열에 너무 오래 남아 있으면 요청이 거부됩니다.
이 두 가지 동시성 한계는 정적으로 구성할 수 있습니다. 정적 한계는 좋은 보호 결과를 낼 수 있지만 몇 가지 단점이 있습니다:
- 정적 한계는 모든 사용 패턴에 적합하지 않습니다. 만능 해결책은 없습니다. 한계가 너무 낮으면 대형 저장소에 부정적인 영향을 미칩니다. 한계가 너무 높으면 보호가 본질적으로 손실됩니다.
- 각 저장소의 작업 부하가 시간이 지남에 따라 변화할 때, 동시성 한계에 대해 적절한 값을 유지하는 것은 번거롭습니다.
- 요청이 서버가 유휴 상태임에도 거부될 수 있습니다. 이는 비율이 서버의 부하를 고려하지 않기 때문입니다.
모든 단점을 극복하고 동시성 제한의 이점을 유지하려면 적응형 동시성 한계를 구성하면 됩니다. 적응형 동시성 한계는 선택 사항이며 두 가지 동시성 제한 유형을 기반으로 합니다. 이는 가산적 증가/곱셈 감소(AIMD) 알고리즘을 사용합니다. 각 적응형 한계:
- 일반적인 프로세스 작동 중에 특정 상한까지 점진적으로 증가합니다.
- 호스트 머신에 리소스 문제가 발생하면 빠르게 감소합니다.
이 메커니즘은 머신이 “호흡”할 수 있는 여유를 제공하고 현재 비행 중인 요청의 속도를 높입니다.
적응형 제한기는 매 30초마다 한계를 조정하고:
- 상한에 도달할 때까지 한계를 1씩 증가시킵니다.
- 최상위 cgroup이 메모리 사용량이 90%를 초과하거나 관찰 시간의 50% 이상 CPU가 제한된 경우 한계를 절반으로 감소시킵니다.
그렇지 않으면, 한계는 상한에 도달할 때까지 1씩 증가합니다. 이 시스템의 기술 구현에 대한 자세한 내용은 관련 설계 문서를 참조하십시오.
적응형 제한은 각 RPC 또는 패킹 객체 캐시에 대해 개별적으로 활성화됩니다. 그러나 한계는 동시에 조정됩니다.
RPC 동시성에 대한 적응성 활성화
사전 요구 사항:
- 적응형 제한은 제어 그룹에 따라 달라지므로, 적응형 제한을 사용하기 전에 제어 그룹을 활성화해야 합니다.
다음은 RPC 동시성에 대한 적응형 한계를 구성하는 예입니다:
# in /etc/gitlab/gitlab.rb
gitaly['configuration'] = {
# ...
concurrency: [
{
rpc: '/gitaly.SmartHTTPService/PostUploadPackWithSidechannel',
max_queue_wait: '1s',
max_queue_size: 10,
adaptive: true,
min_limit: 10,
initial_limit: 20,
max_limit: 40
},
{
rpc: '/gitaly.SSHService/SSHUploadPackWithSidechannel',
max_queue_wait: '10s',
max_queue_size: 20,
adaptive: true,
min_limit: 10,
initial_limit: 50,
max_limit: 100
},
],
}
이 예제에서:
-
adaptive
는 적응성이 활성화되었는지 여부를 설정합니다. 설정되면,max_per_repo
값은 다음 구성을 우선하여 무시됩니다. -
initial_limit
은 Gitaly가 시작될 때 사용할 저장소별 동시성 한계입니다. -
max_limit
은 구성된 RPC의 최소 저장소별 동시성 한계입니다. Gitaly는 현재 한계를 증가시켜 이 숫자에 도달합니다. -
min_limit
은 구성된 RPC의 최소 저장소별 동시성 한계입니다. 호스트 머신에 리소스 문제가 발생할 경우 Gitaly는 이 값에 도달할 때까지 빠르게 한계를 줄입니다.
자세한 내용은 RPC 동시성을 참조하십시오.
pack-objects 동시성에 대한 적응성 활성화
사전 요구 사항:
- 적응형 제한은 control groups에 의존하기 때문에, 적응형 제한을 사용하기 전에 control groups를 활성화해야 합니다.
다음은 pack-objects 동시성을 위한 적응형 제한을 구성하는 예입니다:
# /etc/gitlab/gitlab.rb에서
gitaly['pack_objects_limiting'] = {
'max_queue_length' => 200,
'max_queue_wait' => '60s',
'adaptive' => true,
'min_limit' => 10,
'initial_limit' => 20,
'max_limit' => 40
}
이 예에서:
-
adaptive
는 적응성이 활성화되었는지 여부를 설정합니다. 설정된 경우,max_concurrency
의 값은 다음 구성에 따라 무시됩니다. -
initial_limit
은 Gitaly 시작 시 사용할 per-IP 동시성 제한입니다. -
max_limit
은 pack-objects에 대한 최소 per-IP 동시성 제한입니다. Gitaly는 현재 제한을 이 숫자에 도달할 때까지 증가시킵니다. -
min_limit
은 pack-objects에 대한 최소 per-IP 동시성 제한입니다. 호스트 머신에 리소스 문제가 있을 때, Gitaly는 이 값에 도달할 때까지 제한을 빠르게 줄입니다.
자세한 내용은 pack-objects 동시성을 참조하세요.