0

Is it possible to create a script for Redis that flush its memory when it is above a certain value? In my specific case, I want a flush when the memory is above 90%. What is the best way, via bash script or Lua script?

octopi
  • 145
  • 3
  • 11
  • Does this answer your question? [Abuse cURL to communicate with Redis](https://stackoverflow.com/questions/33243121/abuse-curl-to-communicate-with-redis) – mikeb Feb 17 '20 at 16:45
  • this doesn't answer me. Maybe for more information, I'm using GCP Memorystore – octopi Feb 17 '20 at 16:50
  • If I use `(printf "MEMORY STATS\r\n";) | nc REDIS_IP 6379` I obtain all the values. Is there a way to see only a field? I'm looking for something like a `grep` – octopi Feb 17 '20 at 16:57
  • Maybe this command is more useful `redis-cli -h REDIS_IP -p 6379 memory stats` than the first one – octopi Feb 17 '20 at 17:21

2 Answers2

1

I would use a Lua script as it will perform faster, atomically, and it would be easy to use both from redis-cli and any application code.

Here a Lua script to get memory used and maxmemory, the percent, and an action placeholder. It uses both MEMORY STATS and INFO memory to illustrate.

MEMORY STATS brings structured information, but doesn't include maxmemory or total_system_memory, as INFO memory does. CONFIG GET is not allowed from Lua scripts.

local stats = redis.call('MEMORY', 'STATS')
local memused = 0
for i = 1,table.getn(stats),2 do
    if stats[i] == 'total.allocated' then
        memused = stats[i+1]
        break
    end
end
local meminfo = redis.call('INFO', 'memory')
local maxmemory = 0
for s in meminfo:gmatch('[^\\r\\n]+') do
    if string.sub(s,1,10) == 'maxmemory:' then
        maxmemory = tonumber(string.sub(s,11))
    end
end
local mempercent = memused/maxmemory
local action = 'No action'
if mempercent > tonumber(ARGV[1]) then
    action = 'Flush here'
end
return {memused, maxmemory, tostring(mempercent), action}

Use as:

> EVAL "local stats = redis.call('MEMORY', 'STATS') \n local memused = 0 \n for i = 1,table.getn(stats),2 do \n     if stats[i] == 'total.allocated' then \n     memused = stats[i+1] \n break \n end \n end \n local meminfo = redis.call('INFO', 'memory') \n local maxmemory = 0 \n for s in meminfo:gmatch('[^\\r\\n]+') do \n     if string.sub(s,1,10) == 'maxmemory:' then \n     maxmemory = tonumber(string.sub(s,11)) \n end \n end \n local mempercent = memused/maxmemory \n local action = 'No action' \n if mempercent > tonumber(ARGV[1]) then \n     action = 'Flush here' \n end \n return {memused, maxmemory, tostring(mempercent), action}" 0 0.9
1) (integer) 860264
2) (integer) 100000000
3) "0.00860264"
4) "No action"
LeoMurillo
  • 6,048
  • 1
  • 19
  • 34
0

That's the way to obtain the allocated memory redis-cli -h 1.2.3.4 -p 6379 memory stats | sed -n 4p. Now it's easy to create a bash script

octopi
  • 145
  • 3
  • 11