一 前言 从 2022 年 1 月 31 日发布了 Redis 7.0 RC1 开始,经过几个 RC 版本的快速上线。Redis 7.0.0 GA 版于 2022 年 4 月 27 日正式发布,代表 Redis7.0 进入了稳定版(Stable)时代。

本文将针对 Redis 7.0 的新特性进行展开,尝尝鲜。

二 配置项变动 2.1 多AOF文件支持 7.0 版本中一个比较大的变化就是 aof 文件由一个变成了多个,主要分为两种类型:基本文件(base files)、增量文件(incr files),请注意这些文件名称是复数形式说明每一类文件不仅仅只有一个。 在此之外还引入了一个清单文件(manifest) 用于跟踪文件以及文件的创建和应用顺序(恢复)。

redis.config 中对应的配置项:

// 几种类型文件的前缀,后跟有关序列和类型的附加信息
appendfilename "appendonly.aof"

// 新版本增加的目录配置项目
appenddirname "appendonlydir"

// 如有下的aof文件存在
1. 基本文件
	appendonly.aof.1.base.rdb 
2. 增量文件	
	appendonly.aof.1.incr.aof
	appendonly.aof.2.incr.aof
3. 清单文件	
	appendonly.aof.manifest 

2.2 config 命令增强 CONFIG SET/GET 可以在一次调用中处理多个配置,注意 CONFIG GET 响应以不确定的顺序返回。

2.3 限制客户端内存使用 增加允许限制所有客户端的总内存使用量配置项,redis.config 中对应的配置项:

// 两种配置形式:指定内存大小、基于 maxmemory 的百分比。
maxmemory-clients 1g
maxmemory-clients 10%

2.4 listpack 紧凑列表 listpack 是用来替代 ziplist 的新数据结构,在 7.0 版本已经没有 ziplist 的配置了(6.0版本仅部分数据类型作为过渡阶段在使用)。想了解 ziplist 的可以看文章《ziplist - 压缩列表》。

redis.config 中对应的配置项:

// 下面配置代表 listpack 已经替换了 ziplist 类似 hash-max-ziplist-entries 的配置了。

list-max-listpack-size -2

hash-max-listpack-entries 512
hash-max-listpack-value 64

zset-max-listpack-entries 128
zset-max-listpack-value 64

2.5 传出连接绑定 增加了传出连接(从副本到主服务器,从Sentinel到实例,集群总线等)的绑定配置项,redis.config 中对应的配置项:

bind-source-addr 10.0.0.1 1 2.6 等待副本关闭超时 在关闭期间,宽限期允许任何滞后的复制副本跟上主服务器存在之前的最新复制偏移量。这个时期可以防止数据丢失,尤其是对于没有配置磁盘备份的部署。

“关机超时”值是宽限期的持续时间(秒)。这是仅当实例有副本时适用。要禁用该功能,请设置该值为0。

shutdown-timeout 10 1 2.7 其他变动

  1. busy-reply-threshold 替换 lua-time-limit
  2. 增加集群相关配置项: cluster-port // 控制集群总线的绑定端口 cluster-announce-hostname cluster-preferred-endpoint-type cluster-allow-pubsublocal-when-down cluster-link-sendbuf-limit

三 redis-cli 工具变动 redis-cli --json, and -2 redis-cli --scan // 添加睡眠间隔选项 redis-cli --replica // 跳过 RDB 生成从而得到优化 redis-cli --functions-rdb // 仅使用函数生成 RDB redis-cli -X // 从stdin中获取任意参数 ,集群中使用:take -x

变动:

  1. 可以用Ctrl+C中止monitor和pubsub,但保持cli活动。

四 命令新增和变动 4.1 Zset (有序集合) 有序集合增加 ZMPOP、BZMPOP、ZINTERCARD 等命令 。

ZMPOP 从提供的键名列表中的第一个非空排序集中弹出一个或多个元素,它们是成员分数对。

e.g :

redis:6379> ZMPOP 1 notsuchkey MIN
(nil)
redis:6379> ZADD myzset 1 "one" 2 "two" 3 "three"
(integer) 3
redis:6379> ZMPOP 1 myzset MIN
(nil)
redis:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
redis:6379> ZMPOP 1 myzset MAX COUNT 10
(nil)
redis:6379> ZADD myzset2 4 "four" 5 "five" 6 "six"
(integer) 3
redis:6379> ZMPOP 2 myzset myzset2 MIN COUNT 10
(nil)
redis:6379> ZRANGE myzset 0 -1 WITHSCORES
1) "one"
2) "1"
3) "two"
4) "2"
5) "three"
6) "3"
redis:6379> ZMPOP 2 myzset myzset2 MAX COUNT 10
(nil)
redis:6379> ZRANGE myzset2 0 -1 WITHSCORES
1) "four"
2) "4"
3) "five"
4) "5"
5) "six"
6) "6"
redis:6379> EXISTS myzset myzset2
(integer) 2
redis:6379> 

BZMPOP 为 ZMPOP 阻塞变体。

ZINTERCARD 此命令类似于ZINTER,但它不返回结果集,而只返回结果的基数。

redis:6379> ZADD zset1 1 "one"
(integer) 1
redis:6379> ZADD zset1 2 "two"
(integer) 1
redis:6379> ZADD zset2 1 "one"
(integer) 1
redis:6379> ZADD zset2 2 "two"
(integer) 1
redis:6379> ZADD zset2 3 "three"
(integer) 1
redis:6379> ZINTER 2 zset1 zset2
(empty array)
redis:6379> ZINTERCARD 2 zset1 zset2
(integer) 0
redis:6379> ZINTERCARD 2 zset1 zset2 LIMIT 1
(integer) 0
redis:6379> 

4.2 Set (集合) 增加 SINTERCARD 命令,似于SINTER(返回由所有给定集合的交集产生的集合成员),但它不返回结果集,而只返回结果的基数。返回由所有给定集合的交集产生的集合的基数。

redis:6379> SADD key1 "a"
(integer) 1
redis:6379> SADD key1 "b"
(integer) 1
redis:6379> SADD key1 "c"
(integer) 1
redis:6379> SADD key1 "d"
(integer) 1
redis:6379> SADD key2 "c"
(integer) 1
redis:6379> SADD key2 "d"
(integer) 1
redis:6379> SADD key2 "e"
(integer) 1
redis:6379> SINTER key1 key2
1) "c"
2) "d"
redis:6379> SINTERCARD 2 key1 key2
(integer) 0
redis:6379> SINTERCARD 2 key1 key2 LIMIT 1
(integer) 0
redis:6379> 

4.3 LIST (列表) 增加 LMPOP、BLMPOP ,从提供的键名列表中的第一个非空列表键中弹出一个或多个元素。

4.4 有效期设置变动 增加 PEXPIRETIME 、EXPIRETIME,EXPIRE 命令组支持 NX/XX/GT/LT 选项。

EXPIRETIME 返回给定密钥将过期的绝对 Unix 时间戳。 -1 如果密钥存在但没有关联的过期时间,则该命令返回。 -2 如果密钥不存在,该命令将返回。

e.g :

redis:6379> SET mykey "Hello" "OK" redis:6379> EXPIREAT mykey 33177117420 (integer) 1 redis:6379> EXPIRETIME mykey (integer) 33177117420 redis:6379>

PEXPIRETIME 与EXPIRETIME相似,不过是以毫秒返回。

EXPIRE NX-- 只有当 key 没有过期时才设置过期 XX-- 仅当 key 已过期时才设置过期 GT-- 仅当新的到期时间大于当前到期时间时才设置到期时间 LT-- 仅在新到期时间小于当前到期时设置到期

4.5 SET 2.6.12 开始:添加了、EX和PX选项。 6.0.0 开始:添加了该KEEPTTL选项。 6.2.0 开始:添加了GET,EXAT和PXAT选项。 7.0.0 开始:允许 NX 和 GET 选项一起使用。

EX seconds -- 设置指定的过期时间,以秒为单位。 PX 毫秒——设置指定的过期时间,以毫秒为单位。 EXAT timestamp-seconds -- 设置密钥过期的指定 Unix 时间,以秒为单位。 PXAT timestamp-milliseconds -- 设置密钥过期的指定 Unix 时间,以毫秒为单位。 NX-- 仅当密钥不存在时才设置它。 XX-- 仅当密钥已存在时才设置它。 KEEPTTL-- 保留与密钥关联的生存时间。 GET-- 返回存储在 key 中的旧字符串,如果 key 不存在,则返回 nil。SET如果存储在 key 的值不是字符串,则返回并中止错误。 1 2 3 4 5 6 7 8 由于SET命令选项可以替换SETNX, SETEX, PSETEX, GETSET,因此在未来的 Redis 版本中,这些命令可能会被弃用并最终被删除。

五 INFO 命令信息调整 INFO stats: 增加 aof_rewrites 和 rdb_snapshots 统计 INFO stats: 增加 reply_buffer_shrinks 和 reply_buffer_expends INFO modules: 增加 no-implicit-signal-modified 模块 INFO: latencystats 调整 INFO: total_active_defrag_time and current_active_defrag_time INFO: total_eviction_exceeded_time and current_eviction_exceeded_time INFO: evicted_clients INFO: mem_cluster_links, total_cluster_links_buffer_limit_exceeded INFO: current_cow_peak INFO: 删除 aof_rewrite_buffer_length MEMORY STATS: 在集群模式中报告插槽到键的映射大小。 INFO MEMORY: 更改了函数和EVAL的单独内存使用。 INFO MEMORY: 增加 mem_total_replication_buffers, 改变 mem_clients_slaves 的含义。

六 性能资源利用率、安全、等改进 这些是整理更新得到的部分优化改动。

  1. 在集群模式下显着节省内存和延迟改进 。
  2. 在许多散列或 zset 键的情况下显着节省内存。
  3. 复制积压和副本使用一个全局共享复制缓冲。
  4. 显着减少写时复制内存开。
  5. 释放集群发送缓冲区中未使用的容。
  6. 内存效率,充分利用用于回复缓冲区的客户端结构内存 。
  7. 将 ziplist 替换为 Hash、List、Zset 中的 listpack。
  8. 添加对列表类型的支持以存储大于 4GB 的元素 。
  9. 重用模块阻塞客户端的临时客户端对象 。
  10. 删除命令参数计数限制,动态增加 argv 缓冲区 。
  11. 优化列表类型操作以从最近端查找 。
  12. 改进 fsync 以避免大量写入到磁盘。
  13. BITSET 和 BITFIELD SET 仅在值实际更改时传播 。
  14. 当客户端被模块计时器解除阻塞时改善延迟。
  15. 当 redis 从空启动时始终创建一个基本 AOF 文件。
  16. 本在 repl-diskless-load 期间继续提供数据= swapdb 以提高可用性 。
  17. Redis 7 对 RDB 文件使用了新的 10 版本格式,改版本与旧版本不兼容。
  18. 加载较旧的 RDB 格式时将 ziplist 编码的密钥动态转换为 listpacks 。转换适用于从磁盘加载文件或从 Redis 主服务器复制,并且会稍微增加加载时间。

// 安全性改进 19. redis-cli:敏感命令绕过历史文件。 20. 敏感配置和命令默认被阻止。

七 总结 本文从配置项改动、redis-cli工具、命令变动、INFO命令等方面对 Redis7.0 的改动进行了一个较为详细的讲解。