Skip to content

Patch RedisCacheStore to use pipelined cmds

Sylvester Chin requested to merge sc1-patch-rails-cache-multikey-method into master

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
  1. 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"]
  1. Run read_multi command
Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands {|| Rails.cache.read_multi('x', 'y', 'z')}
  1. 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
  1. Enable feature flag
Feature.enable(:enable_rails_cache_pipeline_patch)
  1. 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"]
  1. Run read_multi command
Gitlab::Instrumentation::RedisClusterValidator.allow_cross_slot_commands {|| Rails.cache.read_multi('x', 'y', 'z')}
  1. 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.

Edited by Sylvester Chin

Merge request reports