-
Notifications
You must be signed in to change notification settings - Fork 7
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
APERTA-9087 Configure rails+sidekiq for redis sentinel in tahi/ihat #2965
APERTA-9087 Configure rails+sidekiq for redis sentinel in tahi/ihat #2965
Conversation
config/initializers/sidekiq.rb
Outdated
@@ -1,7 +1,7 @@ | |||
sentinels = ENV['REDIS_SENTINELS'] | |||
Sidekiq.configure_server do |config| | |||
if sentinels.present? | |||
sentinel_list = sentinels.map do |sentinel_host| | |||
sentinel_list = sentinels.join(',').map do |sentinel_host| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you mean split(/,/)
config/initializers/sidekiq.rb
Outdated
@@ -1,7 +1,7 @@ | |||
sentinels = ENV['REDIS_SENTINELS'] | |||
Sidekiq.configure_server do |config| | |||
if sentinels.present? | |||
sentinel_list = sentinels.map do |sentinel_host| | |||
sentinel_list = sentinels.join(',').map do |sentinel_host| | |||
{ host: sentinel_host, port: ENV['REDIS_PORT'] } | |||
end.join(',') |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Per https://brigade.engineering/high-availability-sidekiq-with-redis-sentinel-2c562e65ecd2 the key sentinels
expects an array. Why are we joining using ,
?
Can you explain what |
config/initializers/sidekiq.rb
Outdated
@@ -31,9 +34,9 @@ | |||
|
|||
Sidekiq.configure_client do |config| | |||
if sentinels.present? | |||
sentinel_list = sentinels.map do |sentinel_host| | |||
sentinel_list = sentinels.split(',').map do |sentinel_host| |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should not copy & paste code.
config/initializers/sidekiq.rb
Outdated
# YAML is part of the Ruby standard library and it is used here to convert | ||
# "['server1', 'server2', 'server3']" into ['server1', 'server2', 'server3'] | ||
require 'yaml' | ||
sentinels = YAML::load(ENV['REDIS_SENTINELS']) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When you are parsing a string dumped by some other process, we need to know that what we are parsing is what the other process is dumping. What is salt dumping? Just because YAML 'works' doesn't mean this is an appropriate solution
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Salt is dumping YAML and defaults to YAML for its settings, so we can safely assume that this will work. https://docs.saltstack.com/en/latest/topics/tutorials/starting_states.html
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@tadp, I don't think this is true. YAML is the default format for .sls files, but the means by which salt serializes python objects in a jinja template is another matter I think, it might just use whatever default serializing python uses (print
).
When setting up a system like this, where one application is serializing information and another is deserializing, I think it's important to have a well-established contract that's easy to use. To this end, I think we should keep the deserializing logic in TahiEnv
. It would be great to add a validator for array
values that ensures that they're serialized properly in our env files. It would be pretty cool to just write
TahiEnv.redis_sentinels
and automatically get a ruby list back instead of some string that still needs further parsing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nice. Yeah, we should be extending TahiEnv
here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great idea everyone. I'll move the YAML:load into TahiEnv
and include a test for TahiEnv
to make sure it is converting the string correctly.
config/initializers/sidekiq.rb
Outdated
Sidekiq.configure_server do |config| | ||
if sentinels.present? | ||
sentinel_list = sentinels.map do |sentinel_host| | ||
{ host: sentinel_host, port: ENV['REDIS_PORT'] } | ||
end.join(',') | ||
end |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I still don't understand this. The sidekiq configuration seems to want an array of values URLs. Why are we passing it an array of hashes? See https://brigade.engineering/high-availability-sidekiq-with-redis-sentinel-2c562e65ecd2
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So when I tried URLs initially, everything would break with an error because it was expecting HOST and PORT to be defined. This is one of the things I would like to test in a sentinel environment.
c8d495f
to
3259e0c
Compare
It should be possible to test this code in your local vagrant by modifying your |
@egh I'll revert the other related merges in a separate pr and try in vagrant tomorrow before proceeding with this pr |
3259e0c
to
3acbe14
Compare
3acbe14
to
2355d3b
Compare
2355d3b
to
f2a1338
Compare
Hey @tadp, I didn't explore this PR in detail and you may have already done so, but could you verify that switching to sentinel still works with the health check endpoint and especially on the endpoint on the heroku review apps? |
@surfacedamage The heroku review apps and our development environment should be unaffected because it will use the previous settings unless I plan to do some testing in the CI and Stage environments soon and I'll look out for health check issues. Thanks for the heads up. |
f2a1338
to
8690559
Compare
225319d
to
3031e43
Compare
config/initializers/sidekiq.rb
Outdated
redis_config = if TahiEnv.redis_sentinel_enabled? | ||
{ | ||
master_name: 'aperta', | ||
sentinels: TahiEnv.redis_sentinels, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This config doesn't actually work. This does:
redis_config = if TahiEnv.redis_sentinel_enabled?
{
url: ENV[ENV['REDIS_PROVIDER'] || 'REDIS_URL'],
role: :master,
master_name: 'aperta',
sentinels: TahiEnv.redis_sentinels.map do |s|
u = URI.parse(s)
{ host: u.host, port: (u.port || 26_379) }
end,
failover_reconnect_timeout: 20,
namespace: "tahi_#{Rails.env}"
}
else
{
namespace: "tahi_#{Rails.env}"
}
end
More consistent than rolling our own.
@egh and I walked through the change to ensure that this deploys with the right configuration. We also took down one of the redis instances to see it failover (while watching the health_check route). Everything worked as expected. |
This can go in when these are complete: |
- 25 workers is already the default
JIRA issue: https://developer.plos.org/jira/browse/APERTA-9087
What this PR does:
This implements Redis Sentinel for sidekiq in tahi and ihat.
Dependent Prs:
IHAT pr: https://github.com/Tahi-project/ihat/pull/134
aperta-formula pr: https://github.com/PLOS-Formulas/aperta-formula/pull/31
Notes:
QA: This deploys correctly when the right settings are in place. I don't think there is much else to check. @egh and I also verified the failover of the sentinel setup.
Code Review Tasks:
Reviewer tasks:
After the Code Review:
Author tasks: