diff options
| author | Jacob Vosmaer <contact@jacobvosmaer.nl> | 2016-02-18 16:55:19 +0100 | 
|---|---|---|
| committer | Jacob Vosmaer <contact@jacobvosmaer.nl> | 2016-02-18 16:55:19 +0100 | 
| commit | 9805fe1914f28693eb0be4f8c2d8377050dd2ebb (patch) | |
| tree | 6518ccf969e1aef128fa0fc384733a0f3ea5b185 | |
| parent | 943bed68bc42d02246ddea63a25432d3aba709e7 (diff) | |
| download | gitlab-ce-9805fe1914f28693eb0be4f8c2d8377050dd2ebb.tar.gz | |
Use SCAN during 'rake cache:clear'cache-clear
This allows 'rake cache:clear' to delete millions of keys without
choking. It requires Redis 2.8.0 or newer but we needed that already
anyway.
| -rw-r--r-- | config/application.rb | 4 | ||||
| -rw-r--r-- | lib/tasks/cache.rake | 19 | 
2 files changed, 18 insertions, 5 deletions
| diff --git a/config/application.rb b/config/application.rb index 1e9ec74cdbf..0d596ed22f5 100644 --- a/config/application.rb +++ b/config/application.rb @@ -6,6 +6,8 @@ I18n.config.enforce_available_locales = false  Bundler.require(:default, Rails.env)  module Gitlab +  REDIS_CACHE_NAMESPACE = 'cache:gitlab' +    class Application < Rails::Application      # Settings in config/environments/* take precedence over those specified here.      # Application configuration should go into files in config/initializers @@ -89,7 +91,7 @@ module Gitlab        redis_config_hash[:path] = redis_uri.path      end -    redis_config_hash[:namespace] = 'cache:gitlab' +    redis_config_hash[:namespace] = REDIS_CACHE_NAMESPACE      redis_config_hash[:expires_in] = 2.weeks # Cache should not grow forever      config.cache_store = :redis_store, redis_config_hash diff --git a/lib/tasks/cache.rake b/lib/tasks/cache.rake index 1728dda72cf..b262ea898d5 100644 --- a/lib/tasks/cache.rake +++ b/lib/tasks/cache.rake @@ -1,11 +1,22 @@  namespace :cache do +  CLEAR_BATCH_SIZE = 1000 +  REDIS_SCAN_START_STOP = '0' # Magic value, see http://redis.io/commands/scan +    desc "GitLab | Clear redis cache"    task :clear => :environment do -    # Hack into Rails.cache until https://github.com/redis-store/redis-store/pull/225 -    # is accepted (I hope) and we can update the redis-store gem.      redis_store = Rails.cache.instance_variable_get(:@data) -    redis_store.keys.each_slice(1000) do |key_slice| -      redis_store.del(*key_slice) +    cursor = [REDIS_SCAN_START_STOP, []] +    loop do +      cursor = redis_store.scan( +        cursor.first, +        match: "#{Gitlab::REDIS_CACHE_NAMESPACE}*",  +        count: CLEAR_BATCH_SIZE +      ) + +      keys = cursor.last +      redis_store.del(*keys) if keys.any? + +      break if cursor.first == REDIS_SCAN_START_STOP      end    end  end | 
