Patch RedisCacheStore to use pipelined cmds
What does this MR do and why?
This MR introduces a patch for ActiveSupport::Cache::RedisCacheStore
to switch multi-key commands like mget
and del
with a pipelined version to achieve the same effect while being compatible with Redis Cluster.
Note that just using the pipeline is not enough as the pipeline needs to fan out the list of commands to the respective nodes. That will be done in a separate MR. The purpose of this MR is to benchmark the effects of using pipelined commands on redis-cache.
See gitlab-com/gl-infra/scalability#2320 (closed) for more info
Screenshots or screen recordings
Screenshots are required for UI changes, and strongly recommended for all other merge requests.
How to set up and validate locally
a. Disabled feature flag
Click to expand
- Print current number of requests for cache
require 'prometheus/client/formats/text.rb'
Prometheus::Client::Formats::Text.marshal_multiprocess.split("\n").filter{|x| x.include?("gitlab_redis_client_requests_total{storage=\"cache\"}")}
=> ["gitlab_redis_client_requests_total{storage=\"cache\"} 7638"]
- Run
read_multi
command
Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands {|| Rails.cache.read_multi('x', 'y', 'z')}
- Check that only increased by 1
[33] pry(main)> Prometheus::Client::Formats::Text.marshal_multiprocess.split("\n").filter{|x| x.include?("gitlab_redis_client_requests_total{storage=\"cache\"}")}
=> ["gitlab_redis_client_requests_total{storage=\"cache\"} 7639"]
b. Enabled feature flag
Click to expand
- Enable feature flag
Feature.enable(:enable_rails_cache_pipeline_patch)
- Check count before running read
[36] pry(main)> Prometheus::Client::Formats::Text.marshal_multiprocess.split("\n").filter{|x| x.include?("gitlab_redis_client_requests_total{storage=\"cache\"}")}
=> ["gitlab_redis_client_requests_total{storage=\"cache\"} 7644"]
- Run
read_multi
command
Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands {|| Rails.cache.read_multi('x', 'y', 'z')}
- Check that only increased by 3
[38] pry(main)> Prometheus::Client::Formats::Text.marshal_multiprocess.split("\n").filter{|x| x.include?("gitlab_redis_client_requests_total{storage=\"cache\"}")}
=> ["gitlab_redis_client_requests_total{storage=\"cache\"} 7647"]
c. On large fetches, the patch is not used. Run the snippet below line-by-line:
Click to expand
[5] pry(main)> require 'prometheus/client/formats/text.rb'
[6] pry(main)> names = Array.new(200) {|i| 'x' }
[7] pry(main)> Prometheus::Client::Formats::Text.marshal_multiprocess.split("\n").filter{|x| x.include?("gitlab_redis_client_requests_total{storage=\"cache\"}")}
=> ["gitlab_redis_client_requests_total{storage=\"cache\"} 15334"]
[8] pry(main)> Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands {|| Rails.cache.read_multi(*names)}
=> {}
[9] pry(main)> Prometheus::Client::Formats::Text.marshal_multiprocess.split("\n").filter{|x| x.include?("gitlab_redis_client_requests_total{storage=\"cache\"}")}
=> ["gitlab_redis_client_requests_total{storage=\"cache\"} 15335"]
MR acceptance checklist
This checklist encourages us to confirm any changes have been analyzed to reduce risks in quality, performance, reliability, security, and maintainability.
-
I have evaluated the MR acceptance checklist for this MR.