特定のジョブクラスの処理

caution
これらは高度な設定です。GitLab.comでは使われていますが、ほとんどのGitLabインスタンスでは、すべてのキューをリッスンするプロセスを追加するだけです。これは、私たちがリファレンスアーキテクチャで取っているのと同じアプローチです。

GitLabには、特定のジョブクラスだけを扱うSidekiqプロセスを作成するための2つのオプションがあります:

  1. ルーティングルールはGitLab.comで使用されます。ルーティングルールはGitLab.comで使用されており、アプリケーション内のジョブを管理者が設定したキュー名に誘導します。これはRedisの負荷を下げ、非常に大規模なデプロイにおいて重要です。
  2. キューセレクタは、Sidekiqプロセスの起動時にアプリケーションの外側でジョブの選択を行います。これは2021年9月までGitLab.comで使用されていたもので、互換性の理由からそのまま残されています。

どちらも同じワーカーマッチングクエリ構文を使用します。技術的には一緒に使うこともできますが、ほとんどのデプロイではどちらか一方を選ぶべきです。

ルーティングルール

note
メーラジョブはルーティングルールでルーティングすることはできず、常にmailers キューに mailers送られます。mailers ルーティングルールを使うときは、少なくとも一つのプロセスが mailersキューをmailers リッスンしていることを確認して mailersください。通常、これはdefault キューと並べて置くことができます。

ほとんどのGitLabインスタンスでは、ルーティングルールを使ってSidekiqキューを管理することを推奨します。これにより、管理者はジョブクラスのグループに対して、その属性に基づいた単一のキュー名を選択することができます。構文は、[query, queue] のペアを並べた配列です:

  1. クエリはワーカーマッチングクエリです。
  2. キュー名は、有効な Sidekiq キュー名でなければなりません。キュー名がnil 、または空文字列の場合、ワーカーは、代わりにワーカー名で生成されたキューにルーティングされます。(詳細については、利用可能なジョブクラスのリストを参照してください)。キュー名は、利用可能なジョブクラスのリストにある既存のキュー名と一致する必要はありません。
  3. ワーカーにマッチする最初のクエリが、そのワーカーに対して選択されます。

ルーティングルールのマイグレーション

Sidekiqルーティングルールが変更された後、管理者は、特にジョブの長いキューを持つシステムにおいて、ジョブが完全に失われないようにマイグレーションに注意する必要があります。マイグレーションは、Sidekiqジョブマイグレーションに記載されているマイグレーションステップに従って行うことができます。

スケールされたアーキテクチャにおけるルーティングルール

ルーティングルールはアプリケーション設定の一部なので、すべてのGitLabノード(特にGitLab RailsとSidekiqノード)で同じでなければなりません。キューセレクタは、起動したSidekiqプロセスへの引数を変更するだけなので、GitLabノード間で異なっていても構いません。

詳細な例

これは様々な可能性を示すことを意図した包括的な例です。推奨するものではありません。

  1. /etc/gitlab/gitlab.rb を編集します:

    sidekiq['routing_rules'] = [
      # Route all non-CPU-bound workers that are high urgency to `high-urgency` queue
      ['resource_boundary!=cpu&urgency=high', 'high-urgency'],
      # Route all database, gitaly and global search workers that are throttled to `throttled` queue
      ['feature_category=database,gitaly,global_search&urgency=throttled', 'throttled'],
      # Route all workers having contact with outside world to a `network-intenstive` queue
      ['has_external_dependencies=true|feature_category=hooks|tags=network', 'network-intensive'],
      # Route all import workers to the queues generated by the worker name, for
      # example, JiraImportWorker to `jira_import`, SVNWorker to `svn_worker`
      ['feature_category=import', 'import'],
      # Wildcard matching, route the rest to `default` queue
      ['*', 'default']
    ]
    

    queue_groups は、生成されたキュー名と一致するように設定することができます。インスタンスンス:

    sidekiq['queue_selector'] = false
    sidekiq['queue_groups'] = [
      # Run two high-urgency processes
      'high-urgency',
      'high-urgency',
      # Run one process for throttled, network-intensive, import
      'throttled,network-intensive,import',
      # Run one 'catchall' process on the default and mailers queues
      'default,mailers'
    ]
    
  2. ファイルを保存して GitLab を再設定してください:

    sudo gitlab-ctl reconfigure
    

キューセレクタ (非推奨)

caution
この機能は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'] = [
      # Run all non-CPU-bound queues that are high urgency
      'resource_boundary!=cpu&urgency=high',
      # Run all continuous integration and pages queues that are not high urgency
      'feature_category=continuous_integration,pages&urgency!=high',
      # Run all queues
      '*'
    ]
    
  2. ファイルを保存して GitLab を再設定してください:

    sudo gitlab-ctl reconfigure
    

設定の削除 (非推奨)

caution
この機能は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
    
note
GitLabを再設定した直後にRakeタスクを実行することがインポートです。GitLabを再設定した後、Rakeタスクがジョブのマイグレーションを開始するまで、既存のジョブは処理されません。

次の例は、上記のマイグレーションプロセスをよりよく表しています:

  1. /etc/gitlab/gitlab.rb の内部を確認してください:

    sidekiq['routing_rules'] = []
    sidekiq['queue_selector'] = true
    sidekiq['queue_groups'] = [
      'urgency=high',
      'urgency=low',
      'urgency=throttled',
      '*'
    ]
    
  2. ルーティングルールを使用するために/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'],
      # Wildcard matching, route the rest to `default` queue
      ['*', 'default']
    ]
       
    sidekiq['queue_selector'] = false
    sidekiq['queue_groups'] = [
      'high_urgency',
      'low_urgency',
      'throttled_urgency',
      'default,mailers'
    ]
    
  3. ファイルを保存して GitLab を再設定してください:

    sudo gitlab-ctl reconfigure
    
  4. Rakeタスクを実行して既存のジョブをマイグレーションします:

    sudo gitlab-rake gitlab:sidekiq:migrate_jobs:retry gitlab:sidekiq:migrate_jobs:schedule gitlab:sidekiq:migrate_jobs:queued
    
caution
同時実行のセクションで説明したように、min_concurrencymax_concurrency を同じ値に設定することをお勧めします。例えば、キューグループエントリ内のキュー数が1の場合、min_concurrency0 に設定し、max_concurrency20に設定すると、結果として同時実行数は2 代わりに 2設定されます。22同時実行数は、非常に高い CPU バインドを持つタスクを除いて、ほとんどの場合において低すぎる可能性があります。

ワーカーマッチングクエリ

GitLab はワーカーをその属性に基づいてマッチさせるクエリ構文を提供します。このクエリ構文は、ルーティングルールと キューセレクタの両方で使われます。クエリには2つの要素があります:

  • 選択できる属性
  • クエリの構築に使用されるオペレーション。

利用可能な属性

GitLab 13.1 (tags) で導入されました

キューマッチングクエリは、Sidekiqスタイルガイドに記載されているワーカー属性に基づいて動作します。ワーカー属性のサブセットに基づくクエリをサポートしています:

  • feature_category - キューが属するGitLab 機能カテゴリ。例えば、merge キューはsource_code_management カテゴリに属します。
  • has_external_dependencies - キューが外部サービスに接続するかどうか。例えば、すべてのインポートは、true に設定されています。
  • urgency - このキューのジョブがいかに迅速に実行されることが重要であるか。highlow 、あるいはthrottled のいずれかを指定します。例えば、authorized_projects のキューはユーザの権限を更新するために使用され、high urgency となります。
  • worker_name - ワーカー名です。特定のワーカーを選択するには、この属性を使います。以下のジョブクラスリストで、利用可能な名前をすべて見つけてください。
  • name - ワーカー名から生成されたキュー名。特定のキューを選択するには、この属性を使います。これはワーカー名から生成されるので、他のルーティングルールの結果によって変わることはありません。
  • resource_boundary - キューがcpumemoryunknown でバインドされている場合。例えば、ProjectExportWorker は、エクスポートのためにデータを保存する前にメモリにロードする必要があるため、 メモリバウンドしています。
  • tags - キューに対する短命のアノテーション。これらはリリースごとに頻繁に変更されることが予想され、完全に削除される可能性もあります。

has_external_dependencies は真偽値属性です。true の文字列のみが真とみなされ、それ以外は偽とみなされます。

tags は集合です。つまり、= は交差する集合をチェックし、!= は不連続な集合をチェックします。例えば、tags=a,b は、ab 、またはその両方のタグを持つキューを選択します。tags!=a,b は、これらのタグのどちらも持たないキューを選択します。

利用可能なオペレーション

ルーティングルールとキューセレクタは、優先順位の高いものから順に、以下のオペレーションをサポートしています:

  • | - 論理演算子OR 。例えば、query_a|query_bquery_aquery_b はここにある他の演算子で構成されたクエリです)には、どちらかのクエリにマッチするキューが含まれます。
  • & - 論理AND 演算子。例えば、query_a&query_b (query_aquery_b はここで他の演算子から構成されるクエリです) は、両方のクエリにマッチするキューのみを含みます。
  • != - NOT IN 演算子。例えば、feature_category!=issue_tracking は、issue_tracking の機能カテゴリからすべてのキューを除外します。
  • = - IN 演算子。例えば、resource_boundary=cpu は、CPU バインドされているすべてのキューを含みます。
  • , - concatenate set オペレータ。例えば、feature_category=continuous_integration,pages は、continuous_integration カテゴリとpages カテゴリのどちらかのすべてのキューを含みます。この例は OR 演算子を使用しても可能ですが、より簡潔で、優先順位も低くなります。

この構文の演算子の優先順位は固定されています。ANDOR よりも高い優先順位にすることはできません。

上記の標準的なキューグループ構文と同様に、キューグループ全体として単一の* を指定すると、すべてのキューが選択されます。

利用可能なジョブクラスのリスト

既存のSidekiqジョブクラスとキューのリストについては、以下のファイルを確認してください: