특정 작업 클래스 처리

경고: 이러한 설정은 고급 설정입니다. GitLab.com에서 사용되지만 대부분의 GitLab 인스턴스는 모든 큐를 수신 대기하는 더 많은 프로세스를 추가해야 합니다. 이것은 우리가 참조 아키텍처에서 취하는 접근 방식과 동일합니다.

GitLab에는 특정 작업 클래스만 처리하는 Sidekiq 프로세스를 만드는 두 가지 옵션이 있습니다.

  1. Routing rules는 GitLab.com에서 사용됩니다. 이것들은 응용 프로그램 내에서 작업을 관리자가 구성한 대기열 이름으로 보냅니다. 이렇게 하면 매우 대규모의 배포에서 중요한 Redis의 부하를 줄일 수 있습니다.
  2. Queue selectors는 응용 프로그램 외부에서 작업을 선택합니다. Sidekiq 프로세스를 시작할 때 사용됩니다. 이것은 2021년 9월까지 GitLab.com에서 사용되었으며 호환성을 유지하기 위해 유지되었습니다.

이 두 가지는 동일한 worker matching query 구문을 사용합니다. 기술적으로 함께 사용될 수 있지만, 대부분의 배포에서는 하나를 선택해야 합니다. 그들을 결합하는 것에는 특별한 이점이 없습니다.

Routing rules

참고: 메일러 작업은 라우팅 규칙으로 라우팅 할 수 없으며 항상 mailers 대기열에 전송됩니다. 라우팅 규칙을 사용할 때 mailers 대기열에 대기중인 적어도 하나의 프로세스가 수신 대기하는지 확인하세요. 일반적으로 이는 default 대기열 옆에 놓일 수 있습니다.

라우팅 규칙을 사용하여 대부분의 GitLab 인스턴스가 Sidekiq 큐를 관리하는 것이 좋습니다. 이렇게 하면 관리자가 속성에 따라 작업 클래스 그룹에 대한 단일 큐 이름을 선택할 수 있습니다. 구문은 [query, queue]의 순서가 지정된 배열입니다.

  1. 쿼리는 worker matching query입니다.
  2. 큐 이름은 유효한 Sidekiq 큐 이름이어야 합니다. 대기열 이름이 nil이거나 빈 문자열이면 작업자는 대신 작업자 이름으로 생성된 큐로 라우팅됩니다. (사용 가능한 작업 클래스 목록을 더 알아보세요). 큐 이름은 사용 가능한 작업 클래스 목록에 있는 기존 큐 이름과 일치할 필요가 없습니다.
  3. 작업자와 일치하는 첫 번째 쿼리가 해당 작업자를 위해 선택됩니다. 나중의 규칙은 무시됩니다.

라우팅 규칙 이전

Sidekiq 라우팅 규칙이 변경된 후, 대기 중인 작업이 많은 시스템에서 작업을 완전히 잃지 않도록 마이그레이션에 주의해야 합니다. 사용된 마이그레이션 단계에 따라 마이그레이션을 수행해야 합니다 Sidekiq job migration에 언급된 단계를 따릅니다.

스케일된 아키텍처에서의 라우팅 규칙

라우팅 규칙은 GitLab 노드 전체(특히 GitLab Rails와 Sidekiq 노드)에서 동일해야 합니다. 대기열 선택기는 GitLab 노드마다 다를 수 있습니다. 그런데 그들은 시작된 Sidekiq 프로세스의 인수만 변경합니다.

상세 예제

이것은 다양한 가능성을 보여주기 위한 폭넓은 예제입니다. 권장하는 방법은 아닙니다.

  1. /etc/gitlab/gitlab.rb를 편집합니다:

    sidekiq['routing_rules'] = [
      # 모든 CPU 바운드 작업 클래스를 수신 대기하고 있으며 긴급한 것들을 `high-urgency` 대기열로 라우팅합니다
      ['resource_boundary!=cpu&urgency=high', 'high-urgency'],
      # 모든 데이터베이스, gitaly 및 글로벌 검색 작업들을 대기 중인 상태인 것들을 `throttled` 대기열로 라우팅합니다
      ['feature_category=database,gitaly,global_search&urgency=throttled', 'throttled'],
      # 모든 외부와 연락이 있는 작업들을 `network-intensive` 대기열로 라우팅합니다
      ['has_external_dependencies=true|feature_category=hooks|tags=network', 'network-intensive'],
      # 모든 가져오기 작업을 작업자 이름으로 생성된 대기열로 라우팅합니다. 예를 들어, JiraImportWorker는 `jira_import`, SVNWorker는 `svn_worker`
      ['feature_category=import', 'import'],
      # 와일드카드 일치, 나머지는 `default` 대기열로 라우팅합니다
      ['*', 'default']
    ]
    

    그런 다음 queue_groups를 이러한 생성된 큐 이름과 일치하도록 설정할 수 있습니다. 예를 들어:

    sidekiq['queue_selector'] = false
    sidekiq['queue_groups'] = [
      # 높은 긴급성을 가진 작업을 두 개의 high-urgency 프로세스로 실행합니다
      'high-urgency',
      'high-urgency',
      # 대기 중인, 네트워크 중심, 가져오기 작업을하려면 한 개의 프로세스를 실행하세요
      'throttled,network-intensive,import',
      # 기본 및 메일러 대기열에 'catchall' 프로세스를 하나 실행하세요
      'default,mailers'
    ]
    
  2. 파일을 저장하고 GitLab을 다시 구성합니다:

    sudo gitlab-ctl reconfigure
    

대기열 선택기 (사용 중지됨)

경고: 이 기능은 GitLab 15.9에서 사용 중지되었으며 17.0에서 제거될 예정입니다. 대부분의 인스턴스는 모든 프로세스가 모든 대기열을 수신하도록 설정되어야 합니다. 다른 대안은 라우팅 규칙을 사용하는 것입니다 (이는 고급 설정임에 유의하십시오). 이 변경은 파괴적인 변화입니다.

queue_selector 옵션을 사용하면 작업자 일치 쿼리를 사용하여 대기열 그룹을 더 일반적으로 선택할 수 있습니다. queue_selector가 설정된 후 모든 queue_groups은 위에서 언급된 구문을 따라야 합니다.

대기열 선택기 사용

  1. /etc/gitlab/gitlab.rb를 편집합니다.

    sidekiq['enable'] = true
    sidekiq['routing_rules'] = [['*', nil]]
    sidekiq['queue_selector'] = true
    sidekiq['queue_groups'] = [
      # 모든 CPU 바운드 대기열을 실행, 고급도가 높음
      'resource_boundary!=cpu&urgency=high',
      # 고급도가 높지 않은 모든 지속적 통합 및 페이지 대기열을 실행
      'feature_category=continuous_integration,pages&urgency!=high',
      # 모든 대기열 실행
      '*'
    ]
    
  2. 파일을 저장하고 GitLab을 다시 구성합니다.

    sudo gitlab-ctl reconfigure
    

부정 설정 (사용 중지됨)

경고: 이 기능은 GitLab 15.9에서 사용 중지되었으며 17.0에서 제거될 예정입니다. 대부분의 인스턴스는 모든 프로세스가 모든 대기열을 수신하도록 설정되어야 합니다. 다른 대안은 라우팅 규칙을 사용하는 것입니다 (이는 고급 설정임에 유의하십시오). 이 변경은 파괴적인 변화입니다.

이를 사용하면 Sidekiq 프로세스가 제외한 모든 대기열에서 작동하도록 설정할 수 있습니다. 여러 Sidekiq 노드가 있는 경우에만 일반적으로 사용됩니다. 이 예에서는 Sidekiq 노드에서 모든 가져오기 관련 작업을 제외합니다.

  1. /etc/gitlab/gitlab.rb를 편집합니다.

    sidekiq['routing_rules'] = [['*', nil]]
    sidekiq['negate'] = true
    sidekiq['queue_selector'] = true
    sidekiq['queue_groups'] = [
       "feature_category=importers"
    ]
    
  2. 파일을 저장하고 GitLab을 다시 구성합니다.

    sudo gitlab-ctl reconfigure
    

대기열 선택기에서 라우팅 규칙으로 마이그레이션

GitLab 배포에서 참조 아키텍처와 같이 모든 대기열을 수신하는 추가 Sidekiq 프로세스를 추가하는 것을 권장합니다. 매우 대규모의 배포에 대해서는 대기열 선택기 대신 라우팅 규칙을 권장합니다. GitLab.com에서 라우팅 규칙을 사용하는 것은 Redis의 부하를 줄이는 데 도움이 됩니다.

단일 노드 설정

대기열 선택기에서 라우팅 규칙으로 마이그레이션하는 방법:

  1. /etc/gitlab/gitlab.rb을 엽니다.
  2. sidekiq['queue_selector']false로 설정합니다.
  3. sidekiq['queue_groups']의 모든 selector를 가져옵니다.
  4. selectorqueue_name을 지정하고 [selector, queue_name] 형식으로 넣습니다.
  5. sidekiq['routing_rules'][selector, queue_name] 항목의 배열로 바꿉니다.
  6. sidekiq['routing_rules']['*', 'default'] 와일드카드 일치를 추가합니다. 이 “catchall” 대기열은 default로 이름이 지정되어야 합니다.
  7. sidekiq['queue_groups']queue_name으로 바꿉니다.
  8. 적어도 하나의 default 대기열과 적어도 하나의 mailers 대기열을 sidekiq['queue_groups']에 추가합니다.
  9. 파일을 저장하고 GitLab을 다시 구성합니다.

    sudo gitlab-ctl reconfigure
    
  10. 기존 작업을 마이그레이션하기 위해 Rake 태스크를 실행합니다.

    sudo gitlab-rake gitlab:sidekiq:migrate_jobs:retry gitlab:sidekiq:migrate_jobs:schedule gitlab:sidekiq:migrate_jobs:queued
    

참고: GitLab을 다시 구성한 후 즉시 Rake 태스크를 실행하는 것이 중요합니다. GitLab을 다시 구성한 후에는 기존 작업이 Rake 태스크가 작업을 마이그레이션하기 시작할 때까지 처리되지 않습니다.

이주 예시

다음 예시는 위의 이주 과정을 더 잘 설명합니다:

  1. /etc/gitlab/gitlab.rb에서 sidekiq['queue_groups']urgency 쿼리를 확인합니다. 예:

    sidekiq['routing_rules'] = []
    sidekiq['queue_selector'] = true
    sidekiq['queue_groups'] = [
      'urgency=high',
      'urgency=low',
      'urgency=throttled',
      '*'
    ]
    
  2. 이와 같은 urgency 쿼리를 사용하여 /etc/gitlab/gitlab.rb를 업데이트하여 라우팅 규칙을 사용합니다:

    sidekiq['min_concurrency'] = 20
    sidekiq['max_concurrency'] = 20
    
    sidekiq['routing_rules'] = [
      ['urgency=high', 'high_urgency'],
      ['urgency=low', 'low_urgency'],
      ['urgency=throttled', 'throttled_urgency'],
      # 와일드카드 매칭, 나머지는 `default` 대기열로 라우팅
      ['*', 'default']
    ]
    
    sidekiq['queue_selector'] = false
    sidekiq['queue_groups'] = [
      'high_urgency',
      'low_urgency',
      'throttled_urgency',
      'default,mailers'
    ]
    
  3. 파일을 저장하고 GitLab을 다시 구성합니다:

    sudo gitlab-ctl reconfigure
    
  4. 기존 작업을 이주하는 레이크 작업을 실행합니다:

    sudo gitlab-rake gitlab:sidekiq:migrate_jobs:retry gitlab:sidekiq:migrate_jobs:schedule gitlab:sidekiq:migrate_jobs:queued
    

경고: 동시성 섹션에서 설명한 대로, min_concurrencymax_concurrency를 동일한 값으로 설정하는 것을 권장합니다. 예를 들어, 대기열 그룹 항목의 대기열 수가 1인 경우 min_concurrency0으로 설정되고 max_concurrency20으로 설정된 경우, 결과적으로 동시성이 2로 설정됩니다. 대부분의 경우에는 동시성이 2는 너무 낮을 수 있습니다. 매우 CPU 집약적인 작업을 제외하고는 말이죠.

다중 노드 설정

다중 노드 설정의 경우:

  • 모든 GitLab Rails 및 Sidekiq 노드를 동일한 sidekiq['routing_rules'] 설정으로 다시 구성합니다.
  • 노드를 업데이트 및 다시 구성하는 동안 GitLab Rails 및 Sidekiq 노드를 교대로 사용합니다. 이렇게 함으로써 새로 구성된 Sidekiq이 마이그레이션 중에 새로운 대기열에서 작업을 소비할 준비가 되도록 합니다. 그렇지 않으면 새 작업들은 마이그레이션이 끝날 때까지 대기 상태에 있습니다.

다음은 세 개의 GitLab Rails 노드 및 두 개의 Sidekiq 노드의 예시를 고려해 대기열 선택기에서 라우팅 규칙으로 마이그레이션하는 방법입니다:

  1. Sidekiq 1에서 단일 노드 설정에서 하나를 제외한 모든 단계를 따릅니다. 기존 작업을 이주하는 레이크 작업을 실행하지 않습니다.
  2. 외부로드 밸런서를 구성하여 Rails 1이 트래픽을 수락하지 않도록합니다. 이 단계는 Rails 프로세스가 다시 시작될 때까지 Rails 1이 어떠한 요청도 처리하지 않도록합니다. 자세한 내용은 issue 428794을 참조하십시오.
  3. Rails 1에서 Sidekiq 1과 동일한 sidekiq['routing_rules'] 설정을 사용하도록 /etc/gitlab/gitlab.rb를 업데이트합니다. 레일 노드에서 요구되는 것은 sidekiq['routing_rules'] 뿐입니다.
  4. 외부 로드 밸런서를 등록하여 Rails 1을 다시 등록합니다.
  5. Sidekiq 2 및 Rails 2에 대해 단계 1에서 4를 반복합니다.
  6. Rails 3에 대해 단계 2에서 4를 반복합니다.
  7. 더 많은 Sidekiq 노드가 있으면 나머지 Sidekiq 노드에서 단계 1을 따릅니다.
  8. 기존 작업을 이주하는 레이크 작업을 실행합니다:

    sudo gitlab-rake gitlab:sidekiq:migrate_jobs:retry gitlab:sidekiq:migrate_jobs:schedule gitlab:sidekiq:migrate_jobs:queued
    

사용 가능한 속성

대기열 매칭 쿼리는 Sidekiq 스타일 가이드에 설명된 worker 속성을 기반으로 작동합니다. 우리는 다음과 같은 worker 속성의 하위 집합을 기반으로 쿼리를 지원합니다:

  • feature_category - 대기열이 속한 GitLab 기능 카테고리. 예를 들어, merge 대기열은 source_code_management 카테고리에 속합니다.
  • has_external_dependencies - 대기열이 외부 서비스에 연결되는지 여부. 예를 들어, 모든 importers는 이를 true로 설정합니다.
  • urgency - 이 대기열의 작업 실행이 얼마나 중요한지. high, low, 또는 throttled일 수 있습니다. 예를 들어, authorized_projects 대기열은 사용자 권한을 새로 고치는 데 사용되며 high urgency입니다.
  • worker_name - worker 이름. 특정 worker를 선택하려면 이 속성을 사용하세요. 작업 클래스 목록에서 모든 가능한 이름을 찾으세요.
  • name - worker 이름에서 생성된 대기열 이름. 특정 대기열을 선택하려면 이 속성을 사용하세요. 이는 worker 이름에서 생성되기 때문에 다른 라우팅 규칙의 결과에 따라 변경되지 않습니다.
  • resource_boundary - 대기열이 cpu, memory, 또는 unknown으로 제한되는지 여부. 예를 들어, ProjectExportWorker는 데이터를 내보내기 전에 메모리에 로드해야 하므로 메모리 제약이 있습니다.
  • tags - 대기열에 대한 단기간 주석. 이러한 주석들은 릴리스마다 자주 변경될 것으로 예상되며 완전히 제거될 수 있습니다.

has_external_dependencies는 부울 속성입니다: 정확한 문자열 true만이 true로 간주되며 그 외의 모든 것은 false로 간주됩니다.

tags는 집합으로, =는 교차하는 집합에 대해 확인하고, !=는 분리된 집합에 대해 확인합니다. 예를 들어, tags=a,ba, b 또는 둘 다 태그가 있는 대기열을 선택합니다. tags!=a,b는 이러한 태그 중 하나도 없는 대기열을 선택합니다.

사용 가능한 연산자

라우팅 규칙 및 대기열 선택기는 다음 우선 순위로 나열된 연산자를 지원합니다.

  • | - 논리 OR 연산자. 예를 들어, query_a|query_b (여기서 query_aquery_b는 여기에 나열된 다른 연산자로 이루어진 쿼리)는 어느 하나의 쿼리와 일치하는 대기열을 포함합니다.
  • & - 논리 AND 연산자. 예를 들어, query_a&query_b (여기서 query_aquery_b는 여기에 나열된 다른 연산자로 이루어진 쿼리)는 두 쿼리 모두와 일치하는 대기열만을 포함합니다.
  • != - NOT IN 연산자. 예를 들어, feature_category!=issue_trackingissue_tracking 기능 카테고리의 모든 대기열을 제외합니다.
  • = - IN 연산자. 예를 들어, resource_boundary=cpu는 CPU 제한된 모든 대기열을 포함합니다.
  • , - 집합 연결 연산자. 예를 들어, feature_category=continuous_integration,pagescontinuous_integration 카테고리 또는 pages 카테고리의 모든 대기열을 포함합니다. 이 예는 OR 연산자를 사용하여 가능하지만, 단순함과 함께 더 낮은 우선 순위로 가능하게 합니다.

이 구문의 연산자 우선 순위는 고정되어 있습니다. AND보다 높은 우선 순위를 부여할 수 없습니다.

표준 대기열 그룹 구문과 마찬가지로 단일 *은 모든 대기열을 선택합니다.

사용 가능한 작업 클래스 목록

기존 Sidekiq 작업 클래스 및 대기열 목록은 다음 파일을 확인하세요: