DEV Community


[Redis] How To: Remove Redis Keys without TTL (in Ruby)

I am lazy. I seldom feel the need to write a blog post.
・1 min read


Going to update our caching Redis Server config
to have maxmemory-policy become volatile-ttl

Since we use allkeys-lru before and have keys without TTL set (TTL key would return -1)

Those keys are required to be removed or they will never be evicted after config update


::Rails.application.config.cache_store.redis.with do |c|
  cursor = "0"
  count = 0
  # Fetch keys in batches using SCAN to avoid blocking the Redis server.
    cursor, keys = c.scan(cursor, count: 1000)
    all_key_count = c.dbsize

    puts("cursor: #{cursor}")
    puts("#{count}/#{all_key_count} keys scanned")

    keys_del = keys.each_with_object([]) do |key, keys_to_be_del|
      # Won't expire
      if !key.match?("sprockets|sidekiq|sessions") && c.ttl(key) == -1
        puts("to be deleted: <#{key}>")
    c.del(*keys_del) unless keys_del.empty?

    count += keys.size
    puts("#{count} keys scanned")
  end until cursor == "0"

Enter fullscreen mode Exit fullscreen mode

cursor, keys = c.scan(cursor, count: 1000)
SCAN is good, KEYS is bad

This is due to I am testing my code in development and the Redis server is used for sprockets caching, (rack?) sessions, sidekiq and caching
Feel free to remove it if you want

puts("to be deleted: <#{key}>")
Just another debugging code
I actually commented this code when running on production

c.del(*keys_del) unless keys_del.empty?
Time complexity: O(N)
You can choose to collect all keys then remove the keys in batches

Discussion (0)

Forem Open with the Forem app