markdown # 동시성 제한
Gitaly를 실행하는 서버를 과부하로부터 보호하기 위해 다음의 제한 동시성을 설정할 수 있습니다:
- RPCs.
- Pack objects.
이러한 제한은 고정될 수도 있고, 적응형으로 설정될 수도 있습니다.
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 호출의 동시 처리량을 제한할 수 있습니다. 이러한 제한은 리포지터리별로 적용됩니다. 위의 예에서:
- Gitaly 서버에서 제공하는 각 리포지터리는 최대 20개의 동시
PostUploadPackWithSidechannel
및SSHUploadPackWithSidechannel
RPC 호출을 가질 수 있습니다. - 20개의 슬롯을 모두 사용한 리포지터리에 대해 추가 요청이 들어오는 경우, 해당 요청은 대기열로 이동됩니다.
- 대기열에서 요청이 1초 이상 대기하게 되면 오류로 거부됩니다.
- 대기열이 10개를 초과하는 경우, 후속 요청은 오류로 거부됩니다.
Gitaly 로그와 Prometheus를 사용하여 이 대기열의 동작을 관찰할 수 있습니다. 자세한 내용은 관련 문서를 참조하십시오.
팩 개체 동시성 제한
- GitLab 15.11에서 gitaly_pack_objects_limiting_remote_ip이라는 플래그로 도입되었습니다. 기본은 비활성화 상태입니다.
-
GitLab 16.0에서 이제 GA(General Availability)입니다. 피처 플래그
gitaly_pack_objects_limiting_remote_ip
가 제거되었습니다.
Gitaly는 SSH 및 HTTPS로 리포지터리를 복제하거나 가져올 때 git-pack-objects
프로세스를 트리거합니다. 이러한 프로세스는 팩-파일
을 생성하며, 예상치 못한 고트래픽이나 대형 리포지터리로부터의 동시 복제 요청과 같은 상황에서 많은 리소스를 소비할 수 있습니다. GitLab.com에서는 또한 네트워크 속도가 느린 클라이언트로 인한 문제를 관찰할 수 있습니다.
백그라운드에서 실행되는 이러한 프로세스가 Gitaly 서버를 과부하로부터 보호하기 위해 Gitaly 구성 파일에서 pack-objects
동시성 제한을 설정하여 이러한 프로세스의 동시 처리량을 제한할 수 있습니다.
예제 구성:
# in /etc/gitlab/gitlab.rb
gitaly['pack_objects_limiting'] = {
'max_concurrency' => 15,
'max_queue_length' => 200,
'max_queue_wait' => '60s',
}
-
max_concurrency
는 각 리모트 IP 주소당 동시에 진행되는pack-object
프로세스의 최대 수입니다. -
max_queue_length
는 대기열(각 키당)이 요청을 거부하기 전에 확장될 수 있는 최대 크기입니다. -
max_queue_wait
는 요청이 Gitaly에 의해 처리되기 전에 대기할 수 있는 최대 시간입니다.
위의 예에서:
- 각 리모트 IP 주소당 Gitaly 노드에서 최대 15개의 동시
pack-object
프로세스가 진행될 수 있습니다. - 15개의 슬롯을 모두 사용한 IP에서 추가 요청이 들어오는 경우, 해당 요청은 대기열로 이동됩니다.
- 대기열에서 요청이 1분을 초과하여 대기하게 되면 오류로 거부됩니다.
- 대기열이 200을 초과하는 경우, 후속 요청은 오류로 거부됩니다.
pack objects 캐시가 활성화된 경우, pack objects 제한은 캐시가 빠진 경우에만 발생합니다. 자세한 내용은 pack objects 캐시를 참조하십시오.
Gitaly 로그와 Prometheus를 사용하여 이 대기열의 동작을 관찰할 수 있습니다. 자세한 내용은 Pack-objects 동시성 제한을 참조하십시오.
적응형 동시성 제한
- GitLab 16.6에서 도입되었습니다.
Gitaly는 두 가지 동시성 제한을 지원합니다:
- RPC 동시성 제한, 각 Gitaly RPC에 대해 동시에 진행되는 요청의 최대 수를 구성할 수 있게 합니다. 이 제한은 RPC 및 리포지터리별로 적용됩니다.
- 팩-객체 동시성 제한, IP별로 동시 Git 데이터 전송 요청 수를 제한합니다.
이러한 제한을 초과하는 경우:
- 요청이 대기열에 들어갑니다.
- 대기열이 가득 차거나 요청이 너무 오랫동안 대기하는 경우, 요청이 거부됩니다.
이러한 모든 동시성 제한은 정적으로 구성될 수 있습니다. 정적 제한은 좋은 보호 결과를 낼 수 있지만 몇 가지 단점이 있습니다:
- 정적 제한은 모든 사용 패턴에 적합하지 않습니다. 일반적인 값은 없습니다. 제한이 너무 낮으면 대형 리포지터리에 부정적인 영향을 미치게 됩니다. 제한이 너무 높으면 보호가 사실상 사라집니다.
- 각 리포지터리의 워크로드가 시간이 지남에 따라 변경될 때, 동시성 제한의 합리적인 값을 유지하는 것이 까다로울 수 있습니다.
- 서버의 부하를 계산하지 않은 요청이 거부될 수 있습니다.
모든 이러한 단점을 극복하고 동시성 제한의 이점을 유지하는 것은 적응형 동시성 제한을 구성함으로써 가능합니다. 적응형 동시성 제한은 선택 사항이며 두 가지 동시성 제한 유형을 기반으로 작동합니다. 추가 증가/곱셈 감소(AIMD) 알고리즘을 사용합니다. 각 적응형 제한은:
- 일반적인 프로세스 기능 중에 특정 상한선까지 점진적으로 증가합니다.
- 호스트 머신이 리소스 문제를 가질 때 빠르게 감소합니다.
본 메커니즘은 기계에 “호흡을 할 수 있는” 여유를 제공하고 현재 진행 중인 요청을 가속화시킵니다.
적응형 제한은 각 RPC 또는 팩-객체 캐시별로 활성화됩니다. 그러나 통합적으로 교정됩니다. ```
(이하 생략)
RPC 동시성에 대한 적응성 활성화
전제 조건:
- 적응 제한은 컨트롤 그룹에 의존하므로 적응 제한을 사용하기 전에 컨트롤 그룹을 활성화해야 합니다.
다음은 RPC 동시성을 구성하는 예시입니다:
# /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 동시성에 대한 적응성 활성화
전제 조건:
- 적응 제한은 컨트롤 그룹에 의존하므로 적응 제한을 사용하기 전에 컨트롤 그룹을 활성화해야 합니다.
다음은 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 시작 시 사용할 IP당 동시성 제한입니다. -
max_limit
은 pack-objects의 IP당 동시성 제한의 최소값을 설정합니다. Gitaly는 현재 제한을 이 숫자에 도달할 때까지 증가시킵니다. -
min_limit
은 pack-objects의 IP당 동시성 제한의 최소값입니다. 호스트 머신에 리소스 문제가 발생하면 Gitaly는 이 값에 도달할 때까지 제한을 빨리 줄입니다.
자세한 내용은 pack-objects 동시성을 참조하세요.