redis

1) 过期时间意外丢失

SET 除了可以设置 key-value 之外,还可以设置 key 的过期时间

127.0.0.1:6379> SET testkey val1 EX 60
OK
127.0.0.1:6379> TTL testkey
(integer) 59

此时如果想修改 key 的值,但只是单纯地使用 SET 命令,而没有加上「过期时间」的参数,那这个 key 的过期时间将会被「擦除」。

==================>SET 命令如果不设置过期时间,那么 Redis 会自动「擦除」这个 key 的过期时间。

2) DEL 竟然也会阻塞 Redis

删除一个 key 的耗时,与这个 key 的类型有关。

  • key 是 String 类型,DEL 时间复杂度是 O(1)
  • key 是 List/Hash/Set/ZSet 类型,DEL 时间复杂度是 O(M),M 为元素数量

也就是说,如果你要删除的是一个非 String 类型的 key,这个 key 的元素越多,那么在执行 DEL 时耗时就越久!

原因在于,删除这种 key 时,Redis 需要依次释放每个元素的内存,元素越多,这个过程就会越耗时。

而这么长的操作耗时,势必会阻塞整个 Redis 实例,影响 Redis 的性能。

在删除 List/Hash/Set/ZSet 类型的 key 时,一定要格外注意,不能无脑执行 DEL,而是应该用以下方式删除:

  1. 查询元素数量:执行 LLEN/HLEN/SCARD/ZCARD 命令
  2. 判断元素数量:如果元素数量较少,可直接执行 DEL 删除,否则分批删除
  3. 分批删除:执行 LRANGE/HSCAN/SSCAN/ZSCAN + LPOP/RPOP/HDEL/SREM/ZREM 删除

3) RANDOMKEY 也会阻塞 Redis

 Redis 清理过期 key,是采用定时清理 + 懒惰清理 2 种方式结合来做的。

而 RANDOMKEY 在随机拿出一个 key 后,首先会先检查这个 key 是否已过期。

如果该 key 已经过期,那么 Redis 会删除它,这个过程就是懒惰清理

清理完了还不能结束,Redis 还要找出一个「不过期」的 key,返回给客户端。

此时,Redis 则会继续随机拿出一个 key,然后再判断是它否过期,直到找出一个未过期的 key 返回给客户端。

整个流程就是这样的:

  1. master 随机取出一个 key,判断是否已过期
  2. 如果 key 已过期,删除它,继续随机取 key
  3. 以此循环往复,直到找到一个不过期的 key,返回

Redis 中,有大量 key 已经过期,但还未来得及被清理掉,那这个循环就会持续很久才能结束,而且,这个耗时都花费在了清理过期 key + 寻找不过期 key 上。

数据持久化

Redis 的数据持久化,分为 RDB 和 AOF 两种方式。

其中,RDB 是数据快照,而 AOF 会记录每一个写命令到日志文件中。

原文地址:https://www.cnblogs.com/KL2016/p/15633359.html