Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes #33277: Change Puma default workers to 1.5 * CPU, max threads to 5 #986

Merged
merged 1 commit into from
Aug 24, 2021

Conversation

ehelms
Copy link
Member

@ehelms ehelms commented Aug 17, 2021

The Puma documentation recommends for MRI based installations to
start with number of CPUs times 1.5 and defaults to 5 on Ruby MRI.
The previous maximum threads of 16 was based on an incorrect reading
of the Puma documentation and is only the default on non-MRI Ruby.

I am recommending we make these default changes (and consider resetting existing installations that match the old defaults by way of an installer migration) based upon some of the following info:

@ehelms ehelms changed the title Change Puma default workers to 1.5 * CPU, max threads to 5 Fixes #33277: Change Puma default workers to 1.5 * CPU, max threads to 5 Aug 17, 2021
manifests/params.pp Outdated Show resolved Hide resolved
@ehelms
Copy link
Member Author

ehelms commented Aug 17, 2021 via email

@ekohl
Copy link
Member

ekohl commented Aug 18, 2021

We could borrow from Gitlab and do the min of 1.5 * CPU and (memory - 1.5).

What's memory here? Memory in GB?

@ehelms
Copy link
Member Author

ehelms commented Aug 18, 2021

We could borrow from Gitlab and do the min of 1.5 * CPU and (memory - 1.5).

What's memory here? Memory in GB?

Correct

@ehelms
Copy link
Member Author

ehelms commented Aug 18, 2021

I am working on a version with memory considered, while I fix up test this would look something like:

  $foreman_service_puma_workers = floor(min($facts['processors']['count'] * 1.5, (($facts['memory']['system']['total_bytes'] * 1024 * 1024 * 1024) - 1.5)))

@ekohl
Copy link
Member

ekohl commented Aug 18, 2021

Something else: we talked about making things more dynamic. If we do this in params.pp it'll be static for the installer (since the answer is saved). If we make the default undef and do the calculation right before we determine the real min threads value (was that config.pp?) it'll be dynamic. Maybe something we also want to consider in this PR.

@ehelms
Copy link
Member Author

ehelms commented Aug 18, 2021

Something else: we talked about making things more dynamic. If we do this in params.pp it'll be static for the installer (since the answer is saved). If we make the default undef and do the calculation right before we determine the real min threads value (was that config.pp?) it'll be dynamic. Maybe something we also want to consider in this PR.

That does make this more robust to memory or CPU changes which is a nice feature. Users would get an automatically scaling number of workers. The only downside is users understanding that in the installer when looking to the installers answer file or the help text for knowing what the currently configured value is. They have to know to go look at the systemd file or use systemctl to print out that info. While not a blocker, it just adds knowledge complexity.

So two workflows:

  1. We store it in answers and give guidance to users: If you adjust CPU or memory, unset this value and re-run the installer
  2. We don't store it, and give guidance to users: If you adjust CPU or memory, re-run the installer

@ekohl
Copy link
Member

ekohl commented Aug 18, 2021

That's why I said "consider". I'm fine with leaving that out for now. However, we should try to find an answer. Perhaps do a poll in the community?

@@ -6,6 +6,7 @@
let(:facts) { facts }
let(:params) { {} }
let(:apache_user) { facts[:osfamily] == 'Debian' ? 'www-data' : 'apache' }
let(:puma_workers) { [facts[:processors]['count'] * 1.5, ((facts[:memory]['system']['total_bytes'] * 1024 * 1024 * 1024) - 1.5)].min.floor }
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How about we override the processors and memory facts instead? I think if you modify line 6 to be something like this it should work (but I may have missed some braces somewhere):

Suggested change
let(:puma_workers) { [facts[:processors]['count'] * 1.5, ((facts[:memory]['system']['total_bytes'] * 1024 * 1024 * 1024) - 1.5)].min.floor }
let(:facts) { override_facts(facts, processors: { count: 3 }, memory: { system: { total_bytes: SOMETHING }}) }

spec/classes/foreman_spec.rb Outdated Show resolved Hide resolved
@ehelms
Copy link
Member Author

ehelms commented Aug 18, 2021 via email

@ehelms ehelms requested review from ekohl and wbclark August 19, 2021 10:32
@ehelms
Copy link
Member Author

ehelms commented Aug 19, 2021

This now moves Puma workers to be optional, and if not defined then it uses the prior mentioned calculation to determine what to set this as. This will allow more dynamic setting of this value based on system resources and allow tuning profiles to set these values.

manifests/config.pp Outdated Show resolved Hide resolved
ehelms added a commit to ehelms/foreman-installer that referenced this pull request Aug 19, 2021
This resets the foreman_server_puma_workers value to pick up the
newest default which is undef. The change from theforeman/puppet-foreman#986
makes the default a dynamically calculated value that should
provide better out of the box experience for users.
ehelms added a commit to ehelms/foreman-installer that referenced this pull request Aug 19, 2021
This resets the foreman_server_puma_workers value to pick up the
newest default which is undef. The change from theforeman/puppet-foreman#986
makes the default a dynamically calculated value that should
provide better out of the box experience for users.
@ehelms
Copy link
Member Author

ehelms commented Aug 19, 2021

Installer migration -- theforeman/foreman-installer#714

Copy link
Contributor

@wbclark wbclark left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At this point it looks great to me

The Puma documentation recommends for CRuby based installations to
start with number of CPUs times 1.5 for workers and defaults to a maxium
of 5 threads when using CRuby.
The previous maximum threads of 16 was based on an incorrect reading
of the Puma documentation and is only the default on non-CRuby Ruby.
ehelms added a commit to ehelms/foreman-installer that referenced this pull request Aug 19, 2021
This resets the foreman_server_puma_workers value to pick up the
newest default which is undef. The change from theforeman/puppet-foreman#986
makes the default a dynamically calculated value that should
provide better out of the box experience for users.
ehelms added a commit to ehelms/foreman-installer that referenced this pull request Aug 19, 2021
This initially sets the Puma tuning values based on the same ideas
from theforeman/puppet-foreman#986 statically
calculated for each of the CPU and memory values that exist for the
various profiles.
@wbclark
Copy link
Contributor

wbclark commented Aug 19, 2021

We discussed this some more and one idea that came up was making foreman_service_puma_threads_max also Optional and using a similar pattern where the default is determined dynamically.

This allows users to start with a baseline that is based on the recommendations from Puma documentation. Then as we gain knowledge about what works best for Katello specifically, those values can be defined in the tuning profiles and will override the module defaults here unless the user has already supplied their own values.

The idea is that the tuning profiles can also start with initial values that are based on the same calculations used in the module defaults, and can be updated in the future as our knowledge improves. An installer migration would reset manually values, with a release note explaining the change.

Users of the individual puppet modules would still have any of their settings persisted unless they clear them to opt-in to the new defaults defined here.

Users of foreman-installer would have their settings reset at first, but they could be manually set again. If they are not manually set again, foreman-installer users would get settings from their applied tuning profile. As the tuning profiles get updated based on new data, they would automatically receive the performance improvement benefits unless they have opted out by supplying their own values.

@ekohl
Copy link
Member

ekohl commented Aug 20, 2021

I feel like that would be premature optimization now. At this point we're not really certain what the best practice will be. If we migrate all our settings from one style to the other and then find out it doesn't work well it's going to be painful.

Having a static value does mean you can use --(full-)help to see the value which can make it easier to admins to know what's going to happen on their system.

Currently we have a technical limitation where we can't modify answers with our tuning, but perhaps there are ways around that. We'll also need to think about how we want to really implement auto tuning. There are several ways I can think of.

So for now I'd like to table that a bit, especially since I'm really not sure if we'll end up tuning threads dynamically.

Copy link
Member

@ekohl ekohl left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I'm happy with this. Small suggestion in the template, but both work.

@@ -4,4 +4,4 @@ Environment=FOREMAN_ENV=<%= scope['foreman::rails_env'] %>
Environment=FOREMAN_HOME=<%= scope['foreman::app_root'] %>
Environment=FOREMAN_PUMA_THREADS_MIN=<%= scope['foreman::config::min_puma_threads'] %>
Environment=FOREMAN_PUMA_THREADS_MAX=<%= scope['foreman::foreman_service_puma_threads_max'] %>
Environment=FOREMAN_PUMA_WORKERS=<%= scope['foreman::foreman_service_puma_workers'] %>
Environment=FOREMAN_PUMA_WORKERS=<%= scope['foreman::config::puma_workers'] %>
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is generated from the foreman::config scope so I think this is equal:

Suggested change
Environment=FOREMAN_PUMA_WORKERS=<%= scope['foreman::config::puma_workers'] %>
Environment=FOREMAN_PUMA_WORKERS=<%= @puma_workers %>

The same is true for min_puma_threads.

@ehelms ehelms merged commit 533c1f3 into theforeman:master Aug 24, 2021
ehelms added a commit to ehelms/foreman-installer that referenced this pull request Aug 24, 2021
This resets the foreman_server_puma_workers value to pick up the
newest default which is undef. The change from theforeman/puppet-foreman#986
makes the default a dynamically calculated value that should
provide better out of the box experience for users.
ehelms added a commit to ehelms/foreman-installer that referenced this pull request Aug 25, 2021
…uma_threads_max if set to default value

This resets the foreman_server_puma_workers value to pick up the
newest default which is undef. The change from theforeman/puppet-foreman#986
makes the default a dynamically calculated value that should
provide better out of the box experience for users.

This resets the value of foreman_service_puma_threads_max to the new
default value coming from puppet-foreman of 5. The original default of
16 has been determined to likely be too high for Ruby MRI based installations
and resetting to the recommended default by Puma should result in less
wasted resources. Users can opt to increase this value based on
their environments.
ehelms added a commit to theforeman/foreman-installer that referenced this pull request Aug 25, 2021
…uma_threads_max if set to default value

This resets the foreman_server_puma_workers value to pick up the
newest default which is undef. The change from theforeman/puppet-foreman#986
makes the default a dynamically calculated value that should
provide better out of the box experience for users.

This resets the value of foreman_service_puma_threads_max to the new
default value coming from puppet-foreman of 5. The original default of
16 has been determined to likely be too high for Ruby MRI based installations
and resetting to the recommended default by Puma should result in less
wasted resources. Users can opt to increase this value based on
their environments.
ehelms added a commit to ehelms/foreman-installer that referenced this pull request Aug 25, 2021
…uma_threads_max if set to default value

This resets the foreman_server_puma_workers value to pick up the
newest default which is undef. The change from theforeman/puppet-foreman#986
makes the default a dynamically calculated value that should
provide better out of the box experience for users.

This resets the value of foreman_service_puma_threads_max to the new
default value coming from puppet-foreman of 5. The original default of
16 has been determined to likely be too high for Ruby MRI based installations
and resetting to the recommended default by Puma should result in less
wasted resources. Users can opt to increase this value based on
their environments.

(cherry picked from commit 4c129ef)
ehelms added a commit to theforeman/foreman-installer that referenced this pull request Aug 25, 2021
…uma_threads_max if set to default value

This resets the foreman_server_puma_workers value to pick up the
newest default which is undef. The change from theforeman/puppet-foreman#986
makes the default a dynamically calculated value that should
provide better out of the box experience for users.

This resets the value of foreman_service_puma_threads_max to the new
default value coming from puppet-foreman of 5. The original default of
16 has been determined to likely be too high for Ruby MRI based installations
and resetting to the recommended default by Puma should result in less
wasted resources. Users can opt to increase this value based on
their environments.

(cherry picked from commit 4c129ef)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants