转载地址:http://www.2cto.com/database/201507/420889.html
redis的maxmemory参数用于控制redis可使用的最大内存容量。如果超过maxmemory的值,就会动用淘汰策略来处理expaire字典中的键。
关于redis的淘汰策略:
Redis提供了下面几种淘汰策略供用户选择,其中默认的策略为noeviction策略:
· noeviction:当内存使用达到阈值的时候,所有引起申请内存的命令会报错。
· allkeys-lru:在主键空间中,优先移除最近未使用的key。
· volatile-lru:在设置了过期时间的键空间中,优先移除最近未使用的key。
· allkeys-random:在主键空间中,随机移除某个key。
· volatile-random:在设置了过期时间的键空间中,随机移除某个key。
· volatile-ttl:在设置了过期时间的键空间中,具有更早过期时间的key优先移除。
PS:
关于maxmemory的设置,如果redis的应用场景是作为db使用,那不要设置这个选项,因为db是不能容忍丢失数据的。
如果作为cache使用,则可以启用这个选项(其实既然有淘汰策略,那就是cache了。。。)
但是在集群环境下(尤其是有多个slavers的情形),maxmeomory的值并不是实际redis使用的内存,这个选项值并没有包括slaver的output buffer。
redis早期版本出过一个bug,在多个slaver的情形下,设置了maxmemory值,同时设定了淘汰策略,会造成master上的数据被渐渐擦除。
antirez先生给出了这个问题的原因:
1
2
3
4
5
6
7
|
The issue happens
for
the following reason:
Redis reached the configured limit, so it tries
to
expire keys.
Evicting keys turns
into
explicit DELs sent
to
slaves, since masters control the eviction
of
slaves
for
well known reasons.
But this way if there are enough slaves, emitting the protocol
in
the
output
buffers will actually take more memory than the amount freed removing keys...
So the
key
eviction process starts
to
enter
into
an infinite loop.
Up
to
a given point the fact that there
is
a
static
buffer part
in
the
output
queue
of
every client (including slaves) mitigate this
in
certain conditions, but once Redis can't use the
output
buffer but must use the queue
of
objects the infinite loop
is
triggered.
|
简单说来,删除过期键,需要产生del命令发送给slaver,如果slaver足够多,output buffer将会占用足够多的内存,导致更多的键过期,如此往复,陷入了无线循环。
解决方案有多种,比如output buffer可以不计入maxmemory。
因此,在3.0版本的配置说明中有了以下表述:
1
2
3
4
5
6
7
8
9
10
11
12
|
# WARNING: If you have slaves attached
to
an instance
with
maxmemory
on
,
# the
size
of
the
output
buffers needed
to
feed the slaves are subtracted
#
from
the used memory
count
, so that network problems / resyncs will
#
not
trigger
a loop
where
keys are evicted,
and
in
turn the
output
# buffer
of
slaves
is
full
with
DELs
of
keys evicted triggering the deletion
#
of
more keys,
and
so forth until the
database
is
completely emptied.
#
#
In
short... if you have slaves attached it
is
suggested that you
set
a
lower
# limit
for
maxmemory so that there
is
some
free
RAM
on
the system
for
slave
#
output
buffers (but this
is
not
needed if the policy
is
'noeviction'
).
#
# maxmemory <bytes></bytes>
|
由此可见,如果有slaver的情况下,建议适当调低maxmemory,给output buffer留出一定的可用空间是合理的。