Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

why does the redis memory usage not reduce when del half of keys

Redis is used to save data but it costs a lot of memory, and its memory usage up to 52.5%. I deleted half of the keys in redis, and the return code of the delete operation is ok, but its memory usage doesn't reduce.

What's the reason? Thanks in Advance.

My operation code is as below:

// save data
m_pReply = (redisReply *)redisCommand(m_pCntxt, "set %b %b", mykey.data(), mykey.size(), &myval, sizeof(myval));
// del data
m_pReply = (redisReply *)redisCommand(m_pCntxt, "del %b", mykey.data(), mykey.size());

The redis info:

redis 127.0.0.1:6979> info
redis_version:2.4.8
redis_git_sha1:00000000
redis_git_dirty:0
arch_bits:64
multiplexing_api:epoll
gcc_version:4.4.6
process_id:28799
uptime_in_seconds:1289592
uptime_in_days:14
lru_clock:127925
used_cpu_sys:148455.30
used_cpu_user:38023.92
used_cpu_sys_children:23187.60
used_cpu_user_children:123989.72
connected_clients:22
connected_slaves:0
client_longest_output_list:0
client_biggest_input_buf:0
blocked_clients:0
used_memory:31903334872
used_memory_human:29.71G
used_memory_rss:34414981120
used_memory_peak:34015653264
used_memory_peak_human:31.68G
mem_fragmentation_ratio:1.08
mem_allocator:jemalloc-2.2.5
loading:0
aof_enabled:0
changes_since_last_save:177467
bgsave_in_progress:0
last_save_time:1343456339
bgrewriteaof_in_progress:0
total_connections_received:820
total_commands_processed:2412759064
expired_keys:0
evicted_keys:0
keyspace_hits:994257907
keyspace_misses:32760132
pubsub_channels:0
pubsub_patterns:0
latest_fork_usec:11672476
vm_enabled:0
role:slave
master_host:192.168.252.103
master_port:6479
master_link_status:up
master_last_io_seconds_ago:0
master_sync_in_progress:0
db0:keys=66372158,expires=0
like image 211
hupantingxue Avatar asked Jul 28 '12 06:07

hupantingxue


People also ask

What happens to data if in-memory is wiped off in Redis?

If virtual memory in Redis is disabled (the default) and the maxmemory parameter is set (the default), Redis will not use any more memory than maxmemory allows. If you turn maxmemory off, Redis will start using virtual memory (i.e. swap), and performance will drop tremendously.

Why is Redis using so much memory?

To that end, Redis is most often used as a cache, holding only the most active data with high read/write throughput requirements (think scoreboards and real-time chat messages). Hence, the main culprit for excessive memory usage with Redis is application behaviour.

How does Redis calculate memory usage?

Redis Key Memory Info You can use two main commands if you want to view the keys in a Redis datastore. Dbsize – The Redis dbsize command shows the total number of valid keys in a specific database. Info keyspace – This command shows the keys in each database available in the Redis cluster.

Does Redis keep everything memory?

All Redis data resides in memory, which enables low latency and high throughput data access. Unlike traditional databases, In-memory data stores don't require a trip to disk, reducing engine latency to microseconds.


3 Answers

Please refer to Memory allocation section on the following link:

http://redis.io/topics/memory-optimization

I quoted it here:

Redis will not always free up (return) memory to the OS when keys are removed. This is not something special about Redis, but it is how most malloc() implementations work. For example if you fill an instance with 5GB worth of data, and then remove the equivalent of 2GB of data, the Resident Set Size (also known as the RSS, which is the number of memory pages consumed by the process) will probably still be around 5GB, even if Redis will claim that the user memory is around 3GB. This happens because the underlying allocator can't easily release the memory. For example often most of the removed keys were allocated in the same pages as the other keys that still exist.

like image 108
Wei Zhong Avatar answered Sep 22 '22 11:09

Wei Zhong


Since Redis 4.0.0 there's a command for this:

MEMORY PURGE 

Should do the trick: https://redis.io/commands/memory-purge

Note however that command docs state:

This command is currently implemented only when using jemalloc as an allocator, and evaluates to a benign NOOP for all others.

And the README reminds us that:

Redis is compiled and linked against libc malloc by default, with the exception of jemalloc being the default on Linux systems. This default was picked because jemalloc has proven to have fewer fragmentation problems than libc malloc.

like image 25
mlissner Avatar answered Sep 18 '22 11:09

mlissner


A good starting point is to use the Redis CLI command: MEMORY DOCTOR.
It can give you very valuable information and point you to the potential issue.

some useful links:
MEMORY DOCTOR command docs
What is defragmentation and what are the Redis defragmentation configs

example:

  • Peak memory: In the past this instance used more than 150% the memory that is currently using. The allocator is normally not able to release memory after a peak, so you can expect to see a big fragmentation ratio, however this is actually harmless and is only due to the memory peak, and if the Redis instance Resident Set Size (RSS) is currently bigger than expected, the memory will be used as soon as you fill the Redis instance with more data. If the memory peak was only occasional and you want to try to reclaim memory, please try the MEMORY PURGE command, otherwise the only other option is to shutdown and restart the instance.
  • High total RSS: This instance has a memory fragmentation and RSS overhead greater than 1.4 (this means that the Resident Set Size of the Redis process is much larger than the sum of the logical allocations Redis performed). This problem is usually due either to a large peak memory (check if there is a peak memory entry above in the report) or may result from a workload that causes the allocator to fragment memory a lot. If the problem is a large peak memory, then there is no issue. Otherwise, make sure you are using the Jemalloc allocator and not the default libc malloc. Note: The currently used allocator is "jemalloc-5.1.0".
  • High allocator fragmentation: This instance has an allocator external fragmentation greater than 1.1. This problem is usually due either to a large peak memory (check if there is a peak memory entry above in the report) or may result from a workload that causes the allocator to fragment memory a lot. You can try enabling 'activedefrag' config option.
like image 31
magiccrafter Avatar answered Sep 19 '22 11:09

magiccrafter