redis 記憶體設定及淘汰策略
轉載地址: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留出一定的可用空間是合理的。