Đây có thể là câu hỏi dễ nhưng tôi đang gặp khó khăn trong việc tìm câu trả lời. Redis 2.0 xử lý như thế nào khi hết bộ nhớ được cấp phát tối đa? Làm thế nào nó quyết định dữ liệu nào cần xóa hoặc dữ liệu nào sẽ giữ trong bộ nhớ?
Đây có thể là câu hỏi dễ nhưng tôi đang gặp khó khăn trong việc tìm câu trả lời. Redis 2.0 xử lý như thế nào khi hết bộ nhớ được cấp phát tối đa? Làm thế nào nó quyết định dữ liệu nào cần xóa hoặc dữ liệu nào sẽ giữ trong bộ nhớ?
Câu trả lời:
Nếu bạn đã bật chức năng bộ nhớ ảo (tôi nghĩ là mới trong phiên bản 2.0 hoặc 2.2), thì Redis sẽ bắt đầu lưu trữ dữ liệu "không thường xuyên được sử dụng" vào đĩa khi bộ nhớ hết.
Nếu bộ nhớ ảo trong Redis bị vô hiệu hóa, có vẻ như bộ nhớ ảo của hệ điều hành bắt đầu bị sử dụng hết (tức là hoán đổi) và hiệu suất giảm đáng kể.
Bây giờ, bạn cũng có thể định cấu hình Redis với tham số maxmemory, điều này ngăn Redis sử dụng thêm bất kỳ bộ nhớ nào (mặc định).
Các phiên bản Redis mới hơn có nhiều chính sách khác nhau khi đạt đến maxmemory:
Nếu bạn chọn một chính sách chỉ xóa các khóa với bộ EXPIRE, thì khi Redis hết bộ nhớ, có vẻ như chương trình vừa hủy bỏ thao tác malloc (). Có nghĩa là, nếu bạn cố gắng lưu trữ nhiều dữ liệu hơn, hoạt động chỉ thất bại thảm hại.
Một số liên kết để biết thêm thông tin (vì bạn không nên chỉ nghe lời tôi):
Từ redis.conf , phiên bản 2.8
# Don't use more memory than the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys
# according to the eviction policy selected (see maxmemory-policy).
#
# If Redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', Redis will start to reply with errors to commands
# that would use more memory, like SET, LPUSH, and so on, and will continue
# to reply to read-only commands like GET.
#
# This option is usually useful when using Redis as an LRU cache, or to set
# a hard memory limit for an instance (using the 'noeviction' policy).
#
# 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>
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
#
# volatile-lru -> remove the key with an expire set using an LRU algorithm
# allkeys-lru -> remove any key according to the LRU algorithm
# volatile-random -> remove a random key with an expire set
# allkeys-random -> remove a random key, any key
# volatile-ttl -> remove the key with the nearest expire time (minor TTL)
# noeviction -> don't expire at all, just return an error on write operations
#
# Note: with any of the above policies, Redis will return an error on write
# operations, when there are no suitable keys for eviction.
#
# At the date of writing these commands are: set setnx setex append
# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
# getset mset msetnx exec sort
#
# The default is:
#
# maxmemory-policy volatile-lru
maxmemory-policy
trong Redis 3.2 tại là noeviction
: raw.githubusercontent.com/antirez/redis/3.2/redis.conf
Cập nhật redis 4.0
127.0.0.1:6379> MEMORY HELP
1) "MEMORY DOCTOR - Outputs memory problems report"
2) "MEMORY USAGE <key> [SAMPLES <count>] - Estimate memory usage of key"
3) "MEMORY STATS - Show memory usage details"
4) "MEMORY PURGE - Ask the allocator to release memory"
5) "MEMORY MALLOC-STATS - Show allocator internal stats"
/usr/local/etc/redis.conf
############################## MEMORY MANAGEMENT ################################
# Set a memory usage limit to the specified amount of bytes.
# When the memory limit is reached Redis will try to remove keys
# according to the eviction policy selected (see maxmemory-policy).
#
# If Redis can't remove keys according to the policy, or if the policy is
# set to 'noeviction', Redis will start to reply with errors to commands
# that would use more memory, like SET, LPUSH, and so on, and will continue
# to reply to read-only commands like GET.
#
# This option is usually useful when using Redis as an LRU or LFU cache, or to
# set a hard memory limit for an instance (using the 'noeviction' policy).
#
# 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>
# MAXMEMORY POLICY: how Redis will select what to remove when maxmemory
# is reached. You can select among five behaviors:
#
# volatile-lru -> Evict using approximated LRU among the keys with an expire set.
# allkeys-lru -> Evict any key using approximated LRU.
# volatile-lfu -> Evict using approximated LFU among the keys with an expire set.
# allkeys-lfu -> Evict any key using approximated LFU.
# volatile-random -> Remove a random key among the ones with an expire set.
# allkeys-random -> Remove a random key, any key.
# volatile-ttl -> Remove the key with the nearest expire time (minor TTL)
# noeviction -> Don't evict anything, just return an error on write operations.
#
# LRU means Least Recently Used
# LFU means Least Frequently Used
#
# Both LRU, LFU and volatile-ttl are implemented using approximated
# randomized algorithms.
#
# Note: with any of the above policies, Redis will return an error on write
# operations, when there are no suitable keys for eviction.
#
# At the date of writing these commands are: set setnx setex append
# incr decr rpush lpush rpushx lpushx linsert lset rpoplpush sadd
# sinter sinterstore sunion sunionstore sdiff sdiffstore zadd zincrby
# zunionstore zinterstore hset hsetnx hmset hincrby incrby decrby
# getset mset msetnx exec sort
#
# The default is:
#
# maxmemory-policy noeviction
# LRU, LFU and minimal TTL algorithms are not precise algorithms but approximated
# algorithms (in order to save memory), so you can tune it for speed or
# accuracy. For default Redis will check five keys and pick the one that was
# used less recently, you can change the sample size using the following
# configuration directive.
#
# The default of 5 produces good enough results. 10 Approximates very closely
# true LRU but costs more CPU. 3 is faster but not very accurate.
#
# maxmemory-samples 5
Tôi chỉ mới bắt đầu đọc về Redis, vì vậy tôi không tích cực. Nhưng, tôi đã xem qua một vài mẩu tin có thể hữu ích.
Đây là đoạn trích từ http://antirez.com/post/redis-as-LRU-cache.html :
Một cách khác để sử dụng Redis làm bộ nhớ đệm là chỉ thị maxmemory, một tính năng cho phép chỉ định lượng bộ nhớ tối đa để sử dụng. Khi dữ liệu mới được thêm vào máy chủ và đã đạt đến giới hạn bộ nhớ, máy chủ sẽ xóa một số dữ liệu cũ xóa một khóa biến động, nghĩa là khóa có bộ EXPIRE (thời gian chờ), ngay cả khi khóa vẫn còn xa tự động hết hạn.
Ngoài ra, Redis 2.0 có chế độ VM trong đó tất cả các khóa phải vừa trong bộ nhớ, nhưng giá trị cho các khóa hiếm khi được sử dụng có thể nằm trên đĩa:
Nếu bạn tự hỏi những gì Redis (2.8) thực sự phản hồi khi nó đạt đến mức tối đa được xác định bởi cấu hình của nó, nó sẽ giống như sau:
$ redis-cli
127.0.0.1:6379> GET 5
"bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb"
127.0.0.1:6379> SET 5 a
(error) OOM command not allowed when used memory > 'maxmemory'.
Gần đây tôi đã gặp phải tình trạng không có bộ nhớ trống và ứng dụng của tôi bị dừng lại (ghi không thể, đọc có thể), việc chạy các tập lệnh PHP bị dừng giữa chừng và phải chạy kill -9
theo cách thủ công (ngay cả khi bộ nhớ đã làm sẵn).
Tôi cho rằng đã xảy ra mất dữ liệu (hoặc không nhất quán dữ liệu) nên tôi đã thực hiện flushdb
và khôi phục từ các bản sao lưu. Bài học kinh nghiệm? Sao lưu là bạn của bạn.
Redis không phải là bộ nhớ đệm như memcached, theo mặc định (trong đó maxmemory-policy
tham số được đặt thành noeviction
) tất cả dữ liệu bạn đưa vào redis sẽ không bị xóa, ngoại lệ duy nhất là sử dụng EXPIRE.