redis惰性刪除與異步刪除
redis單機安裝
redis集羣模式 -集羣搭建
redis大key問題-生成大key-生成100萬條測試數據
官方文檔
- 官網操作命令指南頁面:https://redis.io/docs/latest/commands/?name=get&group=string
- Redis cluster specification
下載地址
- 官網:https://redis.io/
- 下載列表頁面:https://download.redis.io/releases/
説明
- 版本選擇:
redis-7.0.0.tar.gz - 下載地址:https://download.redis.io/releases/redis-7.0.0.tar.gz
redis惰性刪除與異步刪除
安裝redis
- 以單機版redis為例,安裝redis參考文檔:redis單機安裝
辨析惰性刪除與異步刪除
- 刪除操作,
del命令是同步刪除,unlink命令是異步刪除 - 異步刪除準確來説,應該是異步釋放,以
unlink命令為例,執行命令時已經做了邏輯刪除,只是用異步釋放內存 - 過期的key不會立即刪除,等訪問的時候才會刪除,這樣的操作稱之為惰性刪除。
lazyfree-lazy-expire配置控制的是過期鍵刪除時內存釋放是同步還是異步,不是要不要惰性刪除。 lazyfree-lazy-user-del等配置,在redis.conf中的LAZY FREEING【應該翻譯為:惰性(異步)釋放內存】部分,這裏的配置大多是控制同步刪除或異步刪除- lazyfree表示異步釋放內存,並沒有過多強調lazy
- 惰性刪除是redis檢查帶有過期時間的key的一種行為,默認就有,無法關閉
惰性(異步)釋放內存
- 在
redis.conf中,找到LAZY FREEING相關的配置 - 官方文檔
############################# LAZY FREEING ####################################
# Redis has two primitives to delete keys. One is called DEL and is a blocking
# deletion of the object. It means that the server stops processing new commands
# in order to reclaim all the memory associated with an object in a synchronous
# way. If the key deleted is associated with a small object, the time needed
# in order to execute the DEL command is very small and comparable to most other
# O(1) or O(log_N) commands in Redis. However if the key is associated with an
# aggregated value containing millions of elements, the server can block for
# a long time (even seconds) in order to complete the operation.
#
# For the above reasons Redis also offers non blocking deletion primitives
# such as UNLINK (non blocking DEL) and the ASYNC option of FLUSHALL and
# FLUSHDB commands, in order to reclaim memory in background. Those commands
# are executed in constant time. Another thread will incrementally free the
# object in the background as fast as possible.
#
# DEL, UNLINK and ASYNC option of FLUSHALL and FLUSHDB are user-controlled.
# It's up to the design of the application to understand when it is a good
# idea to use one or the other. However the Redis server sometimes has to
# delete keys or flush the whole database as a side effect of other operations.
# Specifically Redis deletes objects independently of a user call in the
# following scenarios:
#
# 1) On eviction, because of the maxmemory and maxmemory policy configurations,
# in order to make room for new data, without going over the specified
# memory limit.
# 2) Because of expire: when a key with an associated time to live (see the
# EXPIRE command) must be deleted from memory.
# 3) Because of a side effect of a command that stores data on a key that may
# already exist. For example the RENAME command may delete the old key
# content when it is replaced with another one. Similarly SUNIONSTORE
# or SORT with STORE option may delete existing keys. The SET command
# itself removes any old content of the specified key in order to replace
# it with the specified string.
# 4) During replication, when a replica performs a full resynchronization with
# its master, the content of the whole database is removed in order to
# load the RDB file just transferred.
#
# In all the above cases the default is to delete objects in a blocking way,
# like if DEL was called. However you can configure each case specifically
# in order to instead release memory in a non-blocking way like if UNLINK
# was called, using the following configuration directives.
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
# It is also possible, for the case when to replace the user code DEL calls
# with UNLINK calls is not easy, to modify the default behavior of the DEL
# command to act exactly like UNLINK, using the following configuration
# directive:
lazyfree-lazy-user-del no
# FLUSHDB, FLUSHALL, SCRIPT FLUSH and FUNCTION FLUSH support both asynchronous and synchronous
# deletion, which can be controlled by passing the [SYNC|ASYNC] flags into the
# commands. When neither flag is passed, this directive will be used to determine
# if the data should be deleted asynchronously.
lazyfree-lazy-user-flush no
- 中文翻譯
############################# LAZY FREEING ####################################
# Redis 有兩種刪除鍵的原語。一種叫 DEL,它是阻塞式刪除對象。
# 這意味着服務器會停止處理新的命令,以同步的方式回收與該對象相關的所有內存。
# 如果被刪除的鍵對應的是一個很小的對象,那麼執行 DEL 命令所需的時間非常短,
# 可以和 Redis 中大多數其他 O(1) 或 O(log_N) 命令相媲美。
# 然而,如果這個鍵對應的是一個包含數百萬元素的聚合值,
# 那麼為了完成這個操作,服務器可能會阻塞很長時間(甚至幾秒)。
#
# 基於以上原因,Redis 也提供了非阻塞的刪除原語,
# 例如 UNLINK(非阻塞版 DEL)以及 FLUSHALL 和 FLUSHDB 命令的 ASYNC 選項,
# 用來在後台回收內存。這些命令在常數時間內執行。
# 另一個線程會在後台儘可能快地逐步釋放這個對象。
#
# DEL、UNLINK 以及 FLUSHALL 和 FLUSHDB 的 ASYNC 選項都是由用户控制的。
# 由應用的設計者來決定在什麼情況下使用哪一種方式更合適。
# 然而,Redis 服務器有時必須在沒有用户顯式調用的情況下刪除鍵或清空整個數據庫,
# 作為其他操作的副作用。
# 具體來説,Redis 在以下場景下會獨立於用户調用而刪除對象:
#
# 1)淘汰(eviction):由於 maxmemory 和 maxmemory policy 配置,
# 為了給新數據騰出空間並不超過指定的內存上限。
# 2)過期(expire):當一個帶有存活時間(TTL,參見 EXPIRE 命令)的鍵需要
# 從內存中刪除時。
# 3)作為某些命令的副作用,當一個命令在某個可能已存在的鍵上存儲數據時。
# 比如,RENAME 命令在用另一個鍵替換原來的鍵時,可能會刪除舊鍵的內容。
# 同樣地,SUNIONSTORE 或帶有 STORE 選項的 SORT 可能會刪除已有的鍵。
# SET 命令本身也會移除指定鍵的任何舊內容,以便用指定的字符串替換它。
# 4)在複製期間,當一個從節點對主節點執行全量重同步時,
# 為了加載剛剛傳輸過來的 RDB 文件,會刪除整個數據庫的內容。
#
# 在以上所有場景中,默認都是以阻塞的方式刪除對象,
# 就好像調用了 DEL 一樣。
# 然而,你可以通過如下配置項,為每一種情況單獨配置,
# 使其改為以非阻塞的方式釋放內存,就像調用 UNLINK 一樣。
lazyfree-lazy-eviction no
lazyfree-lazy-expire no
lazyfree-lazy-server-del no
replica-lazy-flush no
# 另外一種情況是,當你很難在用户代碼中把 DEL 調用全部替換為 UNLINK 調用時,
# 可以修改 DEL 命令的默認行為,讓它的行為與 UNLINK 完全一致,
# 使用下面這個配置項即可:
lazyfree-lazy-user-del no
# FLUSHDB、FLUSHALL、SCRIPT FLUSH 和 FUNCTION FLUSH 都同時支持異步和同步刪除,
# 可以通過給命令傳入 [SYNC|ASYNC] 標誌來控制。
# 當既沒有傳 SYNC,也沒有傳 ASYNC 時,會使用下面這個配置項來決定
# 是否以異步方式刪除數據。
lazyfree-lazy-user-flush no
- 相關配置的解釋
# 是否在鍵被淘汰(eviction)時異步釋放內存(而不是阻塞式刪除),yes 為異步,no 為同步
lazyfree-lazy-eviction no
# 是否在鍵過期(expire)刪除時異步釋放內存(而不是阻塞式刪除),yes 為異步,no 為同步
lazyfree-lazy-expire no
# 是否對由服務器內部觸發的刪除(如 SET 覆蓋、RENAME 替換等)採用異步釋放內存,yes 為異步,no 為同步
lazyfree-lazy-server-del no
# 從節點在全量同步時清空數據(flush)是否使用異步方式,yes 為異步清空,no 為同步清空
replica-lazy-flush no
# 是否將用户執行的 DEL 命令改為與 UNLINK 一樣的異步釋放內存行為,yes 為將 DEL 視作 UNLINK,no 為保持傳統同步 DEL
lazyfree-lazy-user-del no
# 當 FLUSHDB / FLUSHALL / SCRIPT FLUSH / FUNCTION FLUSH 未顯式指定 [SYNC|ASYNC] 時,
# 是否默認使用異步方式刪除數據,yes 為默認異步,no 為默認同步
lazyfree-lazy-user-flush no
- 常見生產推薦配置
# 淘汰鍵時異步釋放(強烈推薦打開)
lazyfree-lazy-eviction yes
# 過期鍵刪除時異步釋放(推薦打開)
lazyfree-lazy-expire yes
# 服務器內部觸發的刪除(如覆蓋、重命名等)異步釋放(推薦打開)
lazyfree-lazy-server-del yes
# 從庫在全量同步時清空數據是否異步(推薦打開)
replica-lazy-flush yes
# 是否把用户的 DEL 當成 UNLINK(可按業務情況選擇)
# - 有大 key、刪鍵較頻繁:建議 yes
# - 沒啥大 key 或非常在意“刪除後立刻釋放內存量”的精確性:可以保持 no
lazyfree-lazy-user-del yes
# FLUSHDB / FLUSHALL / SCRIPT FLUSH / FUNCTION FLUSH 默認是否異步
# - 線上極少用同步 flush,推薦默認異步
lazyfree-lazy-user-flush yes
列舉一些同步命令與異步命令
unlink
語法
UNLINK key [key ...]
自版本起可用:
- Redis 開源版 4.0.0
命令説明
這個命令與 DEL 非常相似:都會刪除指定的鍵。
和 DEL 一樣,如果鍵不存在則會被忽略。
但是,UNLINK 會在不同的線程中執行實際的內存回收,因此它是非阻塞的,而 DEL 是阻塞的。
命令名稱的含義也來源於此:該命令只是把鍵從鍵空間(keyspace)中“解除鏈接”(unlink),真正的刪除和內存回收會在之後異步地完成。
flushdb
語法
FLUSHDB [ASYNC | SYNC]
自版本起可用:
- Redis 開源版 1.0.0
命令説明
刪除當前所選數據庫中的所有鍵。該命令永遠不會執行失敗。
默認情況下,FLUSHDB 會同步地清空數據庫中的所有鍵。
從 Redis 6.2 開始,如果將配置項 lazyfree-lazy-user-flush 設置為 “yes”,則會把默認行為改為異步清空。
可以使用以下修飾符之一顯式指定清空模式:
- ASYNC:以異步方式清空數據庫
- SYNC:以同步方式清空數據庫
注意事項
- 一次異步的 FLUSHDB 命令,只會刪除在命令執行那一刻已經存在的鍵。在異步清空過程中新創建的鍵不會受到影響。
- 該命令不會刪除函數(functions)。
- 在使用 Redis Cluster 時,由於集羣模式只支持一個 ID 為 0 的數據庫,此命令的行為與 FLUSHALL 相同。
行為變更歷史
- 自 6.2.0 及以上版本:
默認的清空行為可以通過配置項 lazyfree-lazy-user-flush 來進行配置。
其它還需要説明的內容
- 內存淘汰策略
- 定期刪除。惰性刪除表示,訪問 key 時才檢查是否過期,如果過期則刪除。定期刪除表示,後台定時任務主動掃一批帶 TTL 的 key ,如果過期則刪除
注意事項
- 部分內容由AI生成
- 如有不對,歡迎指正!!!