From 9e2964c15a7d387e46e25c83afa478c12a856d77 Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Fri, 4 Nov 2016 12:53:12 -0600 Subject: Allow certain Sidekiq jobs to be throttled --- Gemfile | 1 + Gemfile.lock | 3 +++ .../admin/application_settings_controller.rb | 1 + app/models/application_setting.rb | 1 + .../admin/application_settings/_form.html.haml | 13 ++++++++++ config/initializers/sidekiq.rb | 16 ++++++++++++ ...d_sidekiq_throttling_to_application_settings.rb | 29 ++++++++++++++++++++++ db/schema.rb | 1 + lib/gitlab/current_settings.rb | 1 + 9 files changed, 66 insertions(+) create mode 100644 db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb diff --git a/Gemfile b/Gemfile index cb2a8470126..f2291568d25 100644 --- a/Gemfile +++ b/Gemfile @@ -137,6 +137,7 @@ gem 'acts-as-taggable-on', '~> 4.0' gem 'sidekiq', '~> 4.2' gem 'sidekiq-cron', '~> 0.4.0' gem 'redis-namespace', '~> 1.5.2' +gem 'sidekiq-limit_fetch', '~> 3.4' # HTTP requests gem 'httparty', '~> 0.13.3' diff --git a/Gemfile.lock b/Gemfile.lock index 290e4c3e1b3..81b43f2238a 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -685,6 +685,8 @@ GEM redis-namespace (>= 1.5.2) rufus-scheduler (>= 2.0.24) sidekiq (>= 4.0.0) + sidekiq-limit_fetch (3.4.0) + sidekiq (>= 4) simplecov (0.12.0) docile (~> 1.1.0) json (>= 1.8, < 3) @@ -961,6 +963,7 @@ DEPENDENCIES shoulda-matchers (~> 2.8.0) sidekiq (~> 4.2) sidekiq-cron (~> 0.4.0) + sidekiq-limit_fetch (~> 3.4) simplecov (= 0.12.0) slack-notifier (~> 1.2.0) spinach-rails (~> 0.2.1) diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index 52e0256943a..a9dcf7615c4 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -117,6 +117,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :send_user_confirmation_email, :container_registry_token_expire_delay, :enabled_git_access_protocol, + :sidekiq_throttling_enabled, :housekeeping_enabled, :housekeeping_bitmaps_enabled, :housekeeping_incremental_repack_period, diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index bb60cc8736c..b728083e91c 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -180,6 +180,7 @@ class ApplicationSetting < ActiveRecord::Base container_registry_token_expire_delay: 5, repository_storages: ['default'], user_default_external: false, + sidekiq_throttling_enabled: false, housekeeping_enabled: true, housekeeping_bitmaps_enabled: true, housekeeping_incremental_repack_period: 10, diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 450ec322f2c..01a14accbba 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -283,6 +283,19 @@ The amount of points to store in a single UDP packet. More points results in fewer but larger UDP packets being sent. + %fieldset + %legend Background Jobs + %p + These settings require a restart to take effect. + .form-group + .col-sm-offset-2.col-sm-10 + .checkbox + = f.label :sidekiq_throttling_enabled do + = f.check_box :sidekiq_throttling_enabled + Enable Sidekiq Job Throttling + .help-block + Limit the amount of resources slow running jobs are assigned. + %fieldset %legend Spam and Anti-bot Protection .form-group diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 023af2af23c..6e660a8c026 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,3 +1,6 @@ +require 'gitlab/current_settings' +include Gitlab::CurrentSettings + # Custom Redis configuration redis_config_hash = Gitlab::Redis.params redis_config_hash[:namespace] = Gitlab::Redis::SIDEKIQ_NAMESPACE @@ -29,6 +32,19 @@ Sidekiq.configure_server do |config| end Sidekiq::Cron::Job.load_from_hash! cron_jobs + # allow it to fail: it may do so when create_from_defaults is executed before migrations are actually done + begin + throttling_enabled = current_application_settings.sidekiq_throttling_enabled + rescue + throttling_enabled = false + end + + if throttling_enabled + { 'project_cache' => 0.1, 'pipeline' => 0.1 }.each do |queue, ratio| + Sidekiq::Queue[queue].limit = (ratio * Sidekiq.options[:concurrency]).ceil + end + end + # Database pool should be at least `sidekiq_concurrency` + 2 # For more info, see: https://github.com/mperham/sidekiq/blob/master/4.0-Upgrade.md config = ActiveRecord::Base.configurations[Rails.env] || diff --git a/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb b/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb new file mode 100644 index 00000000000..e2839219fb7 --- /dev/null +++ b/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb @@ -0,0 +1,29 @@ +# See http://doc.gitlab.com/ce/development/migration_style_guide.html +# for more information on how to write migrations for GitLab. + +class AddSidekiqThrottlingToApplicationSettings < ActiveRecord::Migration + include Gitlab::Database::MigrationHelpers + + # Set this constant to true if this migration requires downtime. + DOWNTIME = false + + # When a migration requires downtime you **must** uncomment the following + # constant and define a short and easy to understand explanation as to why the + # migration requires downtime. + # DOWNTIME_REASON = '' + + # When using the methods "add_concurrent_index" or "add_column_with_default" + # you must disable the use of transactions as these methods can not run in an + # existing transaction. When using "add_concurrent_index" make sure that this + # method is the _only_ method called in the migration, any other changes + # should go in a separate migration. This ensures that upon failure _only_ the + # index creation fails and can be retried or reverted easily. + # + # To disable transactions uncomment the following line and remove these + # comments: + # disable_ddl_transaction! + + def change + add_column :application_settings, :sidekiq_throttling_enabled, :boolean, default: false + end +end diff --git a/db/schema.rb b/db/schema.rb index 62c325a52d7..31d01403508 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -98,6 +98,7 @@ ActiveRecord::Schema.define(version: 20161106185620) do t.text "help_page_text_html" t.text "shared_runners_text_html" t.text "after_sign_up_text_html" + t.boolean "sidekiq_throttling_enabled", default: false t.boolean "housekeeping_enabled", default: true, null: false t.boolean "housekeeping_bitmaps_enabled", default: true, null: false t.integer "housekeeping_incremental_repack_period", default: 10, null: false diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index ef9160d6437..801c2d5abcd 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -50,6 +50,7 @@ module Gitlab repository_checks_enabled: true, container_registry_token_expire_delay: 5, user_default_external: false, + sidekiq_throttling_enabled: false, ) end -- cgit v1.2.1 From b95216aabadb336e4ed8cdc01f69e873f47f10d0 Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Fri, 4 Nov 2016 16:54:24 -0600 Subject: Allow the Sidekiq queues to throttle and the factor by which to throttle them to be configurable --- app/controllers/admin/application_settings_controller.rb | 4 +++- app/helpers/application_settings_helper.rb | 4 ++++ app/models/application_setting.rb | 10 ++++++++++ app/views/admin/application_settings/_form.html.haml | 12 ++++++++++++ config/initializers/sidekiq.rb | 16 ++++------------ ...444_add_sidekiq_throttling_to_application_settings.rb | 2 ++ db/schema.rb | 2 ++ lib/gitlab/current_settings.rb | 4 ++++ 8 files changed, 41 insertions(+), 13 deletions(-) diff --git a/app/controllers/admin/application_settings_controller.rb b/app/controllers/admin/application_settings_controller.rb index a9dcf7615c4..b81842e319b 100644 --- a/app/controllers/admin/application_settings_controller.rb +++ b/app/controllers/admin/application_settings_controller.rb @@ -118,6 +118,7 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController :container_registry_token_expire_delay, :enabled_git_access_protocol, :sidekiq_throttling_enabled, + :sidekiq_throttling_factor, :housekeeping_enabled, :housekeeping_bitmaps_enabled, :housekeeping_incremental_repack_period, @@ -126,7 +127,8 @@ class Admin::ApplicationSettingsController < Admin::ApplicationController repository_storages: [], restricted_visibility_levels: [], import_sources: [], - disabled_oauth_sign_in_sources: [] + disabled_oauth_sign_in_sources: [], + sidekiq_throttling_queues: [] ) end end diff --git a/app/helpers/application_settings_helper.rb b/app/helpers/application_settings_helper.rb index 45a567a1eba..be5e0301a43 100644 --- a/app/helpers/application_settings_helper.rb +++ b/app/helpers/application_settings_helper.rb @@ -100,4 +100,8 @@ module ApplicationSettingsHelper options_for_select(options, @application_setting.repository_storages) end + + def sidekiq_queue_options_for_select + options_for_select(Sidekiq::Queue.all.map(&:name), @application_setting.sidekiq_throttling_queues) + end end diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index b728083e91c..075e4f4fc9d 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -19,6 +19,7 @@ class ApplicationSetting < ActiveRecord::Base serialize :domain_whitelist, Array serialize :domain_blacklist, Array serialize :repository_storages + serialize :sidekiq_throttling_queues cache_markdown_field :sign_in_text cache_markdown_field :help_page_text @@ -85,6 +86,15 @@ class ApplicationSetting < ActiveRecord::Base presence: { message: 'Domain blacklist cannot be empty if Blacklist is enabled.' }, if: :domain_blacklist_enabled? + validates :sidekiq_throttling_factor, + numericality: { greater_than: 0, less_than: 1 }, + presence: { message: 'Throttling factor cannot be empty if Sidekiq Throttling is enabled.' }, + if: :sidekiq_throttling_enabled? + + validates :sidekiq_throttling_queues, + presence: { message: 'Queues to throttle cannot be empty if Sidekiq Throttling is enabled.' }, + if: :sidekiq_throttling_enabled? + validates :housekeeping_incremental_repack_period, presence: true, numericality: { only_integer: true, greater_than: 0 } diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 01a14accbba..9b1b3f0e16e 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -295,6 +295,18 @@ Enable Sidekiq Job Throttling .help-block Limit the amount of resources slow running jobs are assigned. + .form-group + = f.label :sidekiq_throttling_queues, 'Sidekiq queues to throttle', class: 'control-label col-sm-2' + .col-sm-10 + = f.select :sidekiq_throttling_queues, sidekiq_queue_options_for_select, { include_hidden: false }, multiple: true, class: 'select2 select-wide', data: { field: 'sidekiq_throttling_queues' } + .help-block + Choose which queues you wish to throttle. + .form-group + = f.label :sidekiq_throttling_factor, 'Throttling Factor', class: 'control-label col-sm-2' + .col-sm-10 + = f.number_field :sidekiq_throttling_factor, class: 'form-control', min: '0', max: '0.99', step: '0.01' + .help-block + The factor by which the queues should be throttled. A value between 0.1 and 0.9. %fieldset %legend Spam and Anti-bot Protection diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 6e660a8c026..7cc5e396f98 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -1,6 +1,3 @@ -require 'gitlab/current_settings' -include Gitlab::CurrentSettings - # Custom Redis configuration redis_config_hash = Gitlab::Redis.params redis_config_hash[:namespace] = Gitlab::Redis::SIDEKIQ_NAMESPACE @@ -32,16 +29,11 @@ Sidekiq.configure_server do |config| end Sidekiq::Cron::Job.load_from_hash! cron_jobs - # allow it to fail: it may do so when create_from_defaults is executed before migrations are actually done - begin - throttling_enabled = current_application_settings.sidekiq_throttling_enabled - rescue - throttling_enabled = false - end + if Gitlab::CurrentSettings.sidekiq_throttling_enabled? + factor = current_application_settings.sidekiq_throttling_factor - if throttling_enabled - { 'project_cache' => 0.1, 'pipeline' => 0.1 }.each do |queue, ratio| - Sidekiq::Queue[queue].limit = (ratio * Sidekiq.options[:concurrency]).ceil + current_application_settings.sidekiq_throttling_queues.each do |queue| + Sidekiq::Queue[queue].limit = (factor * Sidekiq.options[:concurrency]).ceil end end diff --git a/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb b/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb index e2839219fb7..e644a174964 100644 --- a/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb +++ b/db/migrate/20161103191444_add_sidekiq_throttling_to_application_settings.rb @@ -25,5 +25,7 @@ class AddSidekiqThrottlingToApplicationSettings < ActiveRecord::Migration def change add_column :application_settings, :sidekiq_throttling_enabled, :boolean, default: false + add_column :application_settings, :sidekiq_throttling_queues, :string + add_column :application_settings, :sidekiq_throttling_factor, :decimal end end diff --git a/db/schema.rb b/db/schema.rb index 31d01403508..666b54690c1 100644 --- a/db/schema.rb +++ b/db/schema.rb @@ -99,6 +99,8 @@ ActiveRecord::Schema.define(version: 20161106185620) do t.text "shared_runners_text_html" t.text "after_sign_up_text_html" t.boolean "sidekiq_throttling_enabled", default: false + t.string "sidekiq_throttling_queues" + t.decimal "sidekiq_throttling_factor" t.boolean "housekeeping_enabled", default: true, null: false t.boolean "housekeeping_bitmaps_enabled", default: true, null: false t.integer "housekeeping_incremental_repack_period", default: 10, null: false diff --git a/lib/gitlab/current_settings.rb b/lib/gitlab/current_settings.rb index 801c2d5abcd..3a651ef318a 100644 --- a/lib/gitlab/current_settings.rb +++ b/lib/gitlab/current_settings.rb @@ -23,6 +23,10 @@ module Gitlab settings || fake_application_settings end + def sidekiq_throttling_enabled? + current_application_settings.sidekiq_throttling_enabled + end + def fake_application_settings OpenStruct.new( default_projects_limit: Settings.gitlab['default_projects_limit'], -- cgit v1.2.1 From 1d3ada80ad6cb9a4927512fdf4018907bf3098a6 Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Mon, 7 Nov 2016 15:44:55 -0600 Subject: Added documentation and CHANGELOG item. --- changelogs/unreleased/sidekiq-job-throttling.yml | 4 +++ doc/administration/operations.md | 1 + .../operations/img/sidekiq_job_throttling.png | Bin 0 -> 114784 bytes .../operations/sidekiq_job_throttling.md | 32 +++++++++++++++++++++ 4 files changed, 37 insertions(+) create mode 100644 changelogs/unreleased/sidekiq-job-throttling.yml create mode 100644 doc/administration/operations/img/sidekiq_job_throttling.png create mode 100644 doc/administration/operations/sidekiq_job_throttling.md diff --git a/changelogs/unreleased/sidekiq-job-throttling.yml b/changelogs/unreleased/sidekiq-job-throttling.yml new file mode 100644 index 00000000000..1f3aad7ae96 --- /dev/null +++ b/changelogs/unreleased/sidekiq-job-throttling.yml @@ -0,0 +1,4 @@ +--- +title: Added ability to throttle Sidekiq Jobs +merge_request: 7292 +author: Patricio Cano diff --git a/doc/administration/operations.md b/doc/administration/operations.md index 4b582d16b64..0daceb98d99 100644 --- a/doc/administration/operations.md +++ b/doc/administration/operations.md @@ -1,6 +1,7 @@ # GitLab operations - [Sidekiq MemoryKiller](operations/sidekiq_memory_killer.md) +- [Sidekiq Job throttling](operations/sidekiq_job_throttling.md) - [Cleaning up Redis sessions](operations/cleaning_up_redis_sessions.md) - [Understanding Unicorn and unicorn-worker-killer](operations/unicorn.md) - [Moving repositories to a new location](operations/moving_repositories.md) diff --git a/doc/administration/operations/img/sidekiq_job_throttling.png b/doc/administration/operations/img/sidekiq_job_throttling.png new file mode 100644 index 00000000000..7f29a4d3c46 Binary files /dev/null and b/doc/administration/operations/img/sidekiq_job_throttling.png differ diff --git a/doc/administration/operations/sidekiq_job_throttling.md b/doc/administration/operations/sidekiq_job_throttling.md new file mode 100644 index 00000000000..33cedee7ebd --- /dev/null +++ b/doc/administration/operations/sidekiq_job_throttling.md @@ -0,0 +1,32 @@ +# Sidekiq Job throttling + +> Note: Introduced with GitLab 8.14 + +When your GitLab installation needs to handle tens of thousands of background +jobs, it can be convenient to prioritize queues that need to be executed +immediately, e.g. user initiated actions like merging a Merge Request. + +In order to accomplish this, you can limit the amount of workers that certain +slow running queues get can have available. This is what we call Sidekiq Job +Throttling. Depending on your infrastructure, you might have different slow +running queues, which is why you can choose which queues to throttle and by +how much you want to throttle them. + +These settings are available in the Application Settings of your GitLab +installation. + +![Sidekiq Job Throttling](img/sidekiq_job_throttling.png) + +The throttle factor determines the maximum number of workers a queue can run on. +This value gets multiplied by `:concurrency` value set in the Sidekiq settings +and rounded up to the closest full integer. + +So, for example, you set the `:concurrency` to 25 and the `Throttling factor` to +0.1, the maximum workers assigned to the selected queues would be 3. + +``` +limit = (factor * Sidekiq.options[:concurrency]).ceil +``` + +After enabling the job throttling, you will need to restart your GitLab +instance, in order for the changes to take effect. \ No newline at end of file -- cgit v1.2.1 From 208530494e5d2c5c62a3e1c24489aae0e4935e3a Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Tue, 8 Nov 2016 16:31:37 -0600 Subject: Refactored initializer code to its own class and added tests --- config/initializers/sidekiq.rb | 8 +------- lib/gitlab/sidekiq_throttler.rb | 21 +++++++++++++++++++ spec/lib/gitlab/sidekiq_throttler_spec.rb | 34 +++++++++++++++++++++++++++++++ 3 files changed, 56 insertions(+), 7 deletions(-) create mode 100644 lib/gitlab/sidekiq_throttler.rb create mode 100644 spec/lib/gitlab/sidekiq_throttler_spec.rb diff --git a/config/initializers/sidekiq.rb b/config/initializers/sidekiq.rb index 7cc5e396f98..b87b31d9697 100644 --- a/config/initializers/sidekiq.rb +++ b/config/initializers/sidekiq.rb @@ -29,13 +29,7 @@ Sidekiq.configure_server do |config| end Sidekiq::Cron::Job.load_from_hash! cron_jobs - if Gitlab::CurrentSettings.sidekiq_throttling_enabled? - factor = current_application_settings.sidekiq_throttling_factor - - current_application_settings.sidekiq_throttling_queues.each do |queue| - Sidekiq::Queue[queue].limit = (factor * Sidekiq.options[:concurrency]).ceil - end - end + Gitlab::SidekiqThrottler.execute! # Database pool should be at least `sidekiq_concurrency` + 2 # For more info, see: https://github.com/mperham/sidekiq/blob/master/4.0-Upgrade.md diff --git a/lib/gitlab/sidekiq_throttler.rb b/lib/gitlab/sidekiq_throttler.rb new file mode 100644 index 00000000000..771736e7606 --- /dev/null +++ b/lib/gitlab/sidekiq_throttler.rb @@ -0,0 +1,21 @@ +module Gitlab + class SidekiqThrottler + class << self + def execute! + if Gitlab::CurrentSettings.sidekiq_throttling_enabled? + current_application_settings.sidekiq_throttling_queues.each do |queue| + Sidekiq::Queue[queue].limit = set_limit + end + end + end + + private + + def set_limit + factor = current_application_settings.sidekiq_throttling_factor + + (factor * Sidekiq.options[:concurrency]).ceil + end + end + end +end diff --git a/spec/lib/gitlab/sidekiq_throttler_spec.rb b/spec/lib/gitlab/sidekiq_throttler_spec.rb new file mode 100644 index 00000000000..ac4a64c0f43 --- /dev/null +++ b/spec/lib/gitlab/sidekiq_throttler_spec.rb @@ -0,0 +1,34 @@ +require 'spec_helper' + +describe Gitlab::SidekiqThrottler do + before do + Sidekiq.options[:concurrency] = 35 + + stub_application_setting( + sidekiq_throttling_enabled: true, + sidekiq_throttling_factor: 0.1, + sidekiq_throttling_queues: %w[build project_cache] + ) + end + + describe '#set_limit' do + it 'returns the correct limit' do + expect(Gitlab::SidekiqThrottler.send(:set_limit)).to eq 4 + end + end + + describe '#execute!' do + it 'sets limits on the selected queues' do + Gitlab::SidekiqThrottler.execute! + + expect(Sidekiq::Queue['build'].limit).to eq 4 + expect(Sidekiq::Queue['project_cache'].limit).to eq 4 + end + + it 'does not set limits on other queues' do + Gitlab::SidekiqThrottler.execute! + + expect(Sidekiq::Queue['merge'].limit).to be_nil + end + end +end -- cgit v1.2.1 From e840749b84ceb226e46ebdfb489c735e3370cff7 Mon Sep 17 00:00:00 2001 From: Patricio Cano Date: Thu, 10 Nov 2016 11:36:52 -0600 Subject: Refactored Sidekiq Throttler and updated documentation --- app/models/application_setting.rb | 2 +- app/views/admin/application_settings/_form.html.haml | 4 ++-- changelogs/unreleased/sidekiq-job-throttling.yml | 2 +- doc/administration/operations/sidekiq_job_throttling.md | 15 ++++++++------- lib/gitlab/sidekiq_throttler.rb | 14 ++++++++------ spec/lib/gitlab/sidekiq_throttler_spec.rb | 6 ------ 6 files changed, 20 insertions(+), 23 deletions(-) diff --git a/app/models/application_setting.rb b/app/models/application_setting.rb index 075e4f4fc9d..d1e1b45ab43 100644 --- a/app/models/application_setting.rb +++ b/app/models/application_setting.rb @@ -19,7 +19,7 @@ class ApplicationSetting < ActiveRecord::Base serialize :domain_whitelist, Array serialize :domain_blacklist, Array serialize :repository_storages - serialize :sidekiq_throttling_queues + serialize :sidekiq_throttling_queues, Array cache_markdown_field :sign_in_text cache_markdown_field :help_page_text diff --git a/app/views/admin/application_settings/_form.html.haml b/app/views/admin/application_settings/_form.html.haml index 9b1b3f0e16e..a236335131a 100644 --- a/app/views/admin/application_settings/_form.html.haml +++ b/app/views/admin/application_settings/_form.html.haml @@ -304,9 +304,9 @@ .form-group = f.label :sidekiq_throttling_factor, 'Throttling Factor', class: 'control-label col-sm-2' .col-sm-10 - = f.number_field :sidekiq_throttling_factor, class: 'form-control', min: '0', max: '0.99', step: '0.01' + = f.number_field :sidekiq_throttling_factor, class: 'form-control', min: '0.01', max: '0.99', step: '0.01' .help-block - The factor by which the queues should be throttled. A value between 0.1 and 0.9. + The factor by which the queues should be throttled. A value between 0.0 and 1.0, exclusive. %fieldset %legend Spam and Anti-bot Protection diff --git a/changelogs/unreleased/sidekiq-job-throttling.yml b/changelogs/unreleased/sidekiq-job-throttling.yml index 1f3aad7ae96..ec4e2051c7e 100644 --- a/changelogs/unreleased/sidekiq-job-throttling.yml +++ b/changelogs/unreleased/sidekiq-job-throttling.yml @@ -1,4 +1,4 @@ --- title: Added ability to throttle Sidekiq Jobs merge_request: 7292 -author: Patricio Cano +author: diff --git a/doc/administration/operations/sidekiq_job_throttling.md b/doc/administration/operations/sidekiq_job_throttling.md index 33cedee7ebd..ddeaa22e288 100644 --- a/doc/administration/operations/sidekiq_job_throttling.md +++ b/doc/administration/operations/sidekiq_job_throttling.md @@ -3,14 +3,15 @@ > Note: Introduced with GitLab 8.14 When your GitLab installation needs to handle tens of thousands of background -jobs, it can be convenient to prioritize queues that need to be executed -immediately, e.g. user initiated actions like merging a Merge Request. +jobs, it can be convenient to throttle queues that do not need to be executed +immediately, e.g. long running jobs like Pipelines, thus allowing jobs that do +need to be executed immediately to have access to more resources. In order to accomplish this, you can limit the amount of workers that certain -slow running queues get can have available. This is what we call Sidekiq Job +slow running queues can have available. This is what we call Sidekiq Job Throttling. Depending on your infrastructure, you might have different slow -running queues, which is why you can choose which queues to throttle and by -how much you want to throttle them. +running queues, which is why you can choose which queues you want to throttle +and by how much you want to throttle them. These settings are available in the Application Settings of your GitLab installation. @@ -24,8 +25,8 @@ and rounded up to the closest full integer. So, for example, you set the `:concurrency` to 25 and the `Throttling factor` to 0.1, the maximum workers assigned to the selected queues would be 3. -``` -limit = (factor * Sidekiq.options[:concurrency]).ceil +```ruby +queue_limit = (factor * Sidekiq.options[:concurrency]).ceil ``` After enabling the job throttling, you will need to restart your GitLab diff --git a/lib/gitlab/sidekiq_throttler.rb b/lib/gitlab/sidekiq_throttler.rb index 771736e7606..d4d39a888e7 100644 --- a/lib/gitlab/sidekiq_throttler.rb +++ b/lib/gitlab/sidekiq_throttler.rb @@ -3,18 +3,20 @@ module Gitlab class << self def execute! if Gitlab::CurrentSettings.sidekiq_throttling_enabled? - current_application_settings.sidekiq_throttling_queues.each do |queue| - Sidekiq::Queue[queue].limit = set_limit + Gitlab::CurrentSettings.current_application_settings.sidekiq_throttling_queues.each do |queue| + Sidekiq::Queue[queue].limit = queue_limit end end end private - def set_limit - factor = current_application_settings.sidekiq_throttling_factor - - (factor * Sidekiq.options[:concurrency]).ceil + def queue_limit + @queue_limit ||= + begin + factor = Gitlab::CurrentSettings.current_application_settings.sidekiq_throttling_factor + (factor * Sidekiq.options[:concurrency]).ceil + end end end end diff --git a/spec/lib/gitlab/sidekiq_throttler_spec.rb b/spec/lib/gitlab/sidekiq_throttler_spec.rb index ac4a64c0f43..ff32e0e699d 100644 --- a/spec/lib/gitlab/sidekiq_throttler_spec.rb +++ b/spec/lib/gitlab/sidekiq_throttler_spec.rb @@ -11,12 +11,6 @@ describe Gitlab::SidekiqThrottler do ) end - describe '#set_limit' do - it 'returns the correct limit' do - expect(Gitlab::SidekiqThrottler.send(:set_limit)).to eq 4 - end - end - describe '#execute!' do it 'sets limits on the selected queues' do Gitlab::SidekiqThrottler.execute! -- cgit v1.2.1