동시성 제한

Gitaly를 실행하는 서버를 과도하게 느리게 만들지 않으려면 다음을 동시성으로 제한할 수 있습니다.

  • RPCs.
  • Pack 객체.

이러한 제한은 고정되거나 적응적으로 설정할 수 있습니다.

경고: 환경에서 제한을 활성화하는 것은 신중히하고 예상치 못한 트래픽에 대비하는 경우 등 선택적 상황에서만 수행되어야 합니다. 제한이 도달되면 사용자에게 부정적인 영향을 미치는 연결 해제가 발생합니다. 일관된 안정적인 성능을 위해 먼저 노드 사양 조정과 대형 저장소 또는 작업을 확인하는 등 다른 옵션을 고려해야 합니다.

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개의 동시 PostUploadPackWithSidechannelSSHUploadPackWithSidechannel RPC 호출을 보유할 수 있습니다.
  • 다른 요청이 20개의 슬롯을 모두 사용한 리포지토리에 대해 들어오면, 해당 요청은 대기열에 넣입니다.
  • 대기열에서 요청이 1초 이상 기다린 경우, 오류가 발생합니다.
  • 대기열이 10개 이상으로 확장되면, 후속 요청이 오류로 거부됩니다.

참고: 이러한 제한에 도달하면 사용자가 연결이 해제됩니다.

이 대기열의 동작은 Gitaly 로그 및 Prometheus를 사용하여 확인할 수 있습니다. 자세한 내용은 관련 문서를 참조하십시오.

pack-objects 동시성 제한

  • 소개됨: 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 구성 파일에서 pack-objects 동시성 제한을 설정하여 처리할 수 있습니다. 이 설정은 원격 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개의 동시 pack-object 프로세스를 실행할 수 있습니다.
  • 다른 요청이 15개의 슬롯을 모두 사용한 IP에서 들어오면, 해당 요청은 대기열에 들어갑니다.
  • 대기열에서 요청이 1분 이상 기다린 경우, 오류가 발생합니다.
  • 대기열이 200개 이상으로 확장되면, 후속 요청이 오류로 거부됩니다.

pack-object 캐시가 활성화되었을 때는, pack-objects 제한은 캐시 미스인 경우에만 발생합니다. 자세한 내용은 Pack-objects cache을 참조하십시오.

이 대기열의 동작은 Gitaly 로그 및 Prometheus를 사용하여 확인할 수 있습니다. 자세한 내용은 Monitor Gitaly pack-objects concurrency limiting를 참조하십시오.

적응형 동시성 제한

Gitaly는 두 가지 동시성 제한을 지원합니다.

  • RPC 동시성 제한은 각 Gitaly RPC에 대해 동시에 처리되는 최대 요청 수를 구성할 수 있습니다. 이 제한은 RPC 및 저장소 별로 적용됩니다.
  • Pack-objects 동시성 제한은 IP별로 동시에 처리되는 Git 데이터 전송 요청 수를 제한합니다.

이 제한을 초과하는 경우 다음 중 하나가 발생합니다.

  • 요청이 대기열에 넣입니다.
  • 대기열이 가득 차거나 요청이 오래 대기열에 있으면 요청이 거부됩니다.

이러한 두 동시성 제한은 정적으로 구성할 수 있습니다. 정적 제한은 좋은 보호 결과를 얻을 수 있지만 다음과 같은 단점이 있습니다.

  • 정적 제한은 모든 사용 패턴에 적합하지 않습니다. 일관된 값이 존재하지 않습니다. 제한이 너무 낮으면 큰 저장소에 부정적인 영향을 미치게 됩니다. 제한이 너무 높으면 보호가 사실상 상실됩니다.
  • 각 저장소의 작업 부하가 시간에 따라 변경되는 경우, 동시성 제한에 적절한 값을 유지하는 것이 번거롭습니다.
  • 요청이 거부될 수 있으며 서버가 유휴 상태인 경우에도 요청이 거부됩니다. 왜냐하면 속도는 서버의 부하를 고려하지 않기 때문입니다.

모든 이러한 단점을 극복하고 동시성 제한의 이점을 유지하기 위해 적응형 동시성 제한을 구성함으로써 이러한 측면을 극복할 수 있습니다. 적응형 동시성 제한은 선택 사항이며 두 가지 동시성 제한 유형을 기반으로 구축됩니다. 적응형 동시성 제한은 가산 증가/곱셈 감소(AIMD) 알고리즘을 사용합니다. 각 적응형 제한은 다음을 수행합니다.

  • 일반적인 프로세스 작동 중에 특정 상한값까지 서서히 증가합니다.
  • 호스트 머신에 리소스 문제가 발생할 때 신속하게 감소합니다.

이 메커니즘은 기계에 여유 공간을 제공하고 현재 처리 중인 요청을 가속화합니다.

Gitaly 적응형 동시성 제한

적응형 제한기는 제한값을 30초마다 보정하고 다음을 수행합니다.

  • 상한값에 도달할 때까지 제한값을 1씩 증가시킵니다.
  • 상위 cgroup이 메모리 사용량이 90%를 초과하거나 (고도로 제거 가능한 페이지 캐시를 제외한) 관측 시간의 50% 이상이 CPU 쓰로틀링되었을 때 제한값을 절반으로 감소시킵니다.

그렇지 않은 경우, 상한에 도달할 때까지 제한값을 1씩 증가시킵니다. 이 시스템의 기술적 구현에 대한 자세한 내용은 이 설계도를 참조하십시오.

적응형 제한은 개별적으로 각 RPC 또는 pack-objects 캐시에 대해 활성화됩니다. 그러나 제한이 동시에 보정됩니다.

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 동시성을 참조하십시오.