redis惰性删除与异步删除
文档
官方文档
下载地址
说明
- 版本选择:
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,https://redis.io/docs/latest/commands/UNLINK/语法
UNLINK key [key ...]自版本起可用:
- Redis 开源版 4.0.0
命令说明
这个命令与 DEL 非常相似:都会删除指定的键。
和 DEL 一样,如果键不存在则会被忽略。
但是,UNLINK 会在不同的线程中执行实际的内存回收,因此它是非阻塞的,而 DEL 是阻塞的。
命令名称的含义也来源于此:该命令只是把键从键空间(keyspace)中“解除链接”(unlink),真正的删除和内存回收会在之后异步地完成。
-
flushdb,https://redis.io/docs/latest/commands/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生成
- 如有不对,欢迎指正!!!

2971

被折叠的 条评论
为什么被折叠?



