Redis命令使用指南 – wiki基地


Redis 命令使用指南:从入门到实践

引言

Redis (Remote Dictionary Server) 是一个开源的、高性能的、基于内存的键值存储系统。它以其闪电般的速度、丰富的数据结构支持以及多样的应用场景(如缓存、消息队列、会话存储、排行榜、计数器等)而广受欢迎。要有效地利用 Redis 的强大功能,熟练掌握其命令是至关重要的。本指南旨在全面、详细地介绍 Redis 的常用命令,覆盖核心数据结构、键管理、服务器管理、事务、发布/订阅等多个方面,帮助开发者从入门到熟练运用 Redis。

一、连接与基础

1. 连接 Redis 服务器

通常使用 redis-cli 命令行工具连接到 Redis 服务器。

“`bash

连接本地默认端口 (6379)

redis-cli

连接指定主机和端口

redis-cli -h -p

连接需要密码认证的服务器

redis-cli -h -p -a “`

连接成功后,命令提示符会变为 hostname:port>127.0.0.1:6379>

2. 基本概念

  • 键 (Key): Redis 是键值存储,每个数据项都有一个唯一的键,键是字符串类型。良好的键命名规范对于维护大型 Redis 实例至关重要(例如:object-type:id:field -> user:1001:profile)。
  • 值 (Value): Redis 的值可以是多种数据类型,包括字符串、列表、哈希、集合和有序集合。
  • 数据库 (Database): Redis 默认支持 16 个数据库 (0-15)。可以使用 SELECT <db_index> 命令切换数据库。默认使用数据库 0。不同数据库之间的键空间是隔离的。

3. 常用服务器命令

  • PING: 测试服务器是否仍在运行。如果服务器正常,返回 PONG
    127.0.0.1:6379> PING
    PONG
  • ECHO <message>: 回显指定的消息。
    127.0.0.1:6379> ECHO "Hello Redis"
    "Hello Redis"
  • SELECT <index>: 切换到指定的数据库。
    127.0.0.1:6379> SELECT 1
    OK
    127.0.0.1:6379[1]> # 提示符显示当前数据库索引
  • QUIT: 关闭当前连接。
  • AUTH <password>: 如果服务器设置了密码,使用此命令进行认证。
  • INFO [section]: 获取 Redis 服务器的详细信息和统计数据。可以指定 section(如 server, clients, memory, persistence, stats, replication, cpu, commandstats, cluster, keyspace)获取特定部分的信息。
    127.0.0.1:6379> INFO memory
    # Memory
    used_memory:1040496
    used_memory_human:1016.11K
    ...

二、键 (Key) 管理命令

这些命令用于管理 Redis 中的键,与值的类型无关。

  • KEYS <pattern>: 查找所有符合给定模式 pattern 的键。注意:KEYS 命令会遍历所有键,在生产环境中的大型数据库上使用可能会阻塞服务器,应谨慎使用或使用 SCAN 替代。
    • *: 匹配任意数量的任意字符 (e.g., KEYS user:*)
    • ?: 匹配单个任意字符 (e.g., KEYS u?er:1)
    • []: 匹配方括号内的任意一个字符 (e.g., KEYS user:[12]00)
      127.0.0.1:6379> SET user:1 "Alice"
      OK
      127.0.0.1:6379> SET user:2 "Bob"
      OK
      127.0.0.1:6379> KEYS user:*
      1) "user:1"
      2) "user:2"
  • SCAN <cursor> [MATCH <pattern>] [COUNT <count>]: 增量迭代当前数据库中的键集合。它返回一个游标和一批键。每次调用使用上次返回的游标作为参数,直到游标返回 0 表示迭代完成。MATCH 用于过滤键名,COUNT 提示每次迭代返回的元素数量(但不保证精确)。这是在生产环境中替代 KEYS 的推荐方式。
    127.0.0.1:6379> SCAN 0 MATCH user:* COUNT 1
    1) "12" # 新的游标
    2) 1) "user:1"
    127.0.0.1:6379> SCAN 12 MATCH user:* COUNT 1
    1) "0" # 游标为 0,迭代结束
    2) 1) "user:2"
  • EXISTS <key> [key ...] : 检查一个或多个键是否存在。返回存在的键的数量。
    127.0.0.1:6379> EXISTS user:1 non_existing_key
    (integer) 1
  • DEL <key> [key ...] : 删除一个或多个键。返回成功删除的键的数量。
    127.0.0.1:6379> DEL user:1 user:2
    (integer) 2
  • UNLINK <key> [key ...] : 异步删除键。它仅将键从键空间中移除,实际的内存回收在后台线程中进行。对于删除大型键(如包含数百万元素的列表或哈希)很有用,可以避免阻塞服务器。返回值与 DEL 相同。
  • TYPE <key>: 返回键所存储的值的数据类型 (string, list, set, zset, hash, stream) 或 none (键不存在)。
    127.0.0.1:6379> SET mykey "value"
    OK
    127.0.0.1:6379> TYPE mykey
    string
  • RENAME <key> <newkey>: 将键 key 重命名为 newkey。如果 newkey 已存在,其值将被覆盖。如果 key 不存在,则返回错误。
  • RENAMENX <key> <newkey>: 仅当 newkey 不存在时,将 key 重命名为 newkey。成功返回 1,如果 newkey 已存在则返回 0。
  • EXPIRE <key> <seconds>: 为键设置生存时间(秒)。到期后键会被自动删除。
    127.0.0.1:6379> SET cache:page "<html>...</html>"
    OK
    127.0.0.1:6379> EXPIRE cache:page 60
    (integer) 1 # 设置成功
  • PEXPIRE <key> <milliseconds>: 为键设置生存时间(毫秒)。
  • EXPIREAT <key> <timestamp>: 为键设置绝对过期时间(Unix 时间戳,秒)。
  • PEXPIREAT <key> <milliseconds-timestamp>: 为键设置绝对过期时间(Unix 时间戳,毫秒)。
  • TTL <key>: 以秒为单位,返回键的剩余生存时间。返回 -1 表示键永不过期,返回 -2 表示键不存在。
    127.0.0.1:6379> TTL cache:page
    (integer) 55 # 剩余 55 秒
  • PTTL <key>: 以毫秒为单位,返回键的剩余生存时间。
  • PERSIST <key>: 移除键的过期时间,使其永不过期。如果成功移除返回 1,如果键不存在或没有设置过期时间返回 0。
  • RANDOMKEY: 从当前数据库中随机返回一个键名。如果数据库为空,返回 nil
  • MOVE <key> <db>: 将当前数据库的 key 移动到指定的数据库 db

三、字符串 (String) 类型命令

字符串是 Redis 最基本的数据类型,可以存储文本、序列化对象或二进制数据,最大可达 512MB。

  • SET <key> <value> [EX seconds] [PX milliseconds] [NX|XX]
    • 设置键 key 的值为 value
    • EX seconds: 设置键的过期时间(秒)。等同于 SET + EXPIRE
    • PX milliseconds: 设置键的过期时间(毫秒)。等同于 SET + PEXPIRE
    • NX: 只在键不存在时才设置。用于实现锁或创建新记录。
    • XX: 只在键已存在时才设置。用于更新现有记录。
      127.0.0.1:6379> SET user:100:name "Alice"
      OK
      127.0.0.1:6379> SET session:xyz "data" EX 3600 NX
      OK # 如果 session:xyz 不存在,则设置成功并设置 1 小时过期
  • GET <key>: 获取键 key 的值。如果键不存在,返回 nil
    127.0.0.1:6379> GET user:100:name
    "Alice"
  • GETSET <key> <value>: 设置键 key 的新值 value,并返回键的旧值。如果键不存在,返回 nil
  • MSET <key> <value> [key value ...] : 同时设置一个或多个键值对。原子操作。
    127.0.0.1:6379> MSET product:1:name "Laptop" product:1:price 1200
    OK
  • MGET <key> [key ...] : 获取一个或多个键的值。返回一个包含所有值的列表,对于不存在的键,对应位置返回 nil
    127.0.0.1:6379> MGET product:1:name product:1:price product:2:name
    1) "Laptop"
    2) "1200"
    3) (nil)
  • APPEND <key> <value>: 如果键 key 存在并且是字符串类型,将 value 追加到其末尾。如果键不存在,则创建该键并设置其值,等同于 SET。返回追加后字符串的总长度。
    127.0.0.1:6379> SET mylog "Event: "
    OK
    127.0.0.1:6379> APPEND mylog "User logged in. "
    (integer) 26
    127.0.0.1:6379> GET mylog
    "Event: User logged in. "
  • STRLEN <key>: 返回键 key 存储的字符串值的长度。如果键不存在,返回 0。
  • INCR <key>: 将键 key 存储的数字值(必须是整数)加 1。如果键不存在,先初始化为 0 再执行加 1。返回加 1 后的值。原子操作,常用于计数器。
    127.0.0.1:6379> SET counter 10
    OK
    127.0.0.1:6379> INCR counter
    (integer) 11
    127.0.0.1:6379> INCR non_exist_counter
    (integer) 1
  • INCRBY <key> <increment>: 将键 key 存储的数字值加上指定的增量 increment。返回增加后的值。
  • DECR <key>: 将键 key 存储的数字值减 1。返回减 1 后的值。
  • DECRBY <key> <decrement>: 将键 key 存储的数字值减去指定的减量 decrement。返回减少后的值。
  • INCRBYFLOAT <key> <increment>: 将键 key 存储的数字值(可以是浮点数)加上指定的浮点数增量 increment。返回增加后的值(字符串形式)。
  • SETRANGE <key> <offset> <value>: 用 value 覆盖键 key 存储的字符串值,从偏移量 offset 开始。返回修改后字符串的长度。
  • GETRANGE <key> <start> <end>: 获取键 key 存储的字符串值的子字符串,由 startend 偏移量(都包含)决定。支持负数偏移量(-1 表示最后一个字符)。

四、列表 (List) 类型命令

Redis 列表是简单的字符串列表,按照插入顺序排序。可以在列表的头部 (left) 或尾部 (right) 添加元素。列表底层实现是双向链表或压缩列表 (ziplist),插入和删除操作非常快。适合实现消息队列、最新动态等。

  • LPUSH <key> <element> [element ...] : 将一个或多个元素插入到列表 key 的头部(左侧)。返回插入后列表的长度。
    127.0.0.1:6379> LPUSH mylist "world"
    (integer) 1
    127.0.0.1:6379> LPUSH mylist "hello"
    (integer) 2
    # 列表现在是 ["hello", "world"]
  • RPUSH <key> <element> [element ...] : 将一个或多个元素插入到列表 key 的尾部(右侧)。返回插入后列表的长度。
    127.0.0.1:6379> RPUSH mylist "!"
    (integer) 3
    # 列表现在是 ["hello", "world", "!"]
  • LPOP <key>: 移除并返回列表 key 的头部(左侧)元素。如果列表为空或键不存在,返回 nil
    127.0.0.1:6379> LPOP mylist
    "hello"
  • RPOP <key>: 移除并返回列表 key 的尾部(右侧)元素。如果列表为空或键不存在,返回 nil
  • LLEN <key>: 返回列表 key 的长度。如果键不存在,返回 0。
  • LRANGE <key> <start> <stop>: 返回列表 key 中指定区间内的元素。startstop 是基于 0 的下标。0 表示第一个元素,1 表示第二个,-1 表示最后一个,-2 表示倒数第二个。LRANGE mylist 0 -1 返回整个列表。
    127.0.0.1:6379> RPUSH tasks "task1" "task2" "task3"
    (integer) 3
    127.0.0.1:6379> LRANGE tasks 0 1
    1) "task1"
    2) "task2"
    127.0.0.1:6379> LRANGE tasks 0 -1
    1) "task1"
    2) "task2"
    3) "task3"
  • LINDEX <key> <index>: 返回列表 key 中下标为 index 的元素。如果 index 超出范围,返回 nil
  • LSET <key> <index> <element>: 将列表 key 下标为 index 的元素的值设置为 element。如果 index 超出范围,返回错误。
  • LINSERT <key> BEFORE|AFTER <pivot> <element>: 将元素 element 插入到列表 key 中,位于值 pivot 的之前 (BEFORE) 或之后 (AFTER)。如果 pivot 不存在,不执行操作。返回插入后列表的长度,或 -1 (pivot 未找到),或 0 (key 不存在)。
  • LTRIM <key> <start> <stop>: 对列表进行修剪,只保留指定区间内的元素,区间之外的元素都将被删除。常用于保持列表只存储最新的 N 个元素。
    # 只保留最新的 5 个日志条目
    127.0.0.1:6379> LPUSH logs "log entry N"
    (integer) ...
    127.0.0.1:6379> LTRIM logs 0 4
    OK
  • RPOPLPUSH <source> <destination>: 原子地从列表 source 的尾部移除一个元素,并将该元素添加到列表 destination 的头部,最后返回被移除的元素。常用于实现可靠的消息队列(一个备份列表)。
  • BRPOP <key> [key ...] <timeout>: RPOP 的阻塞版本。如果所有给定列表都为空,连接将阻塞 timeout 秒(0 表示无限期阻塞),直到有元素可用或超时。返回一个包含键名和弹出元素的二元组,超时返回 nil
  • BLPOP <key> [key ...] <timeout>: LPOP 的阻塞版本。行为与 BRPOP 类似,但从列表头部弹出。

五、哈希 (Hash) 类型命令

Redis 哈希是一个字符串字段 (field) 和字符串值 (value) 之间的映射。它特别适合存储对象。

  • HSET <key> <field> <value> [field value ...] : 将哈希表 key 中的一个或多个字段 field 的值设为 value。如果字段已存在,则覆盖。如果键不存在,则创建。返回新创建的字段数量。
    127.0.0.1:6379> HSET user:100 name "Alice" email "[email protected]" age 30
    (integer) 3
  • HGET <key> <field>: 获取哈希表 key 中给定字段 field 的值。如果字段或键不存在,返回 nil
    127.0.0.1:6379> HGET user:100 name
    "Alice"
  • HMSET <key> <field> <value> [field value ...] : (已废弃,推荐使用 HSET) 同时将多个 field-value 对设置到哈希表 key 中。总是返回 OK
  • HMGET <key> <field> [field ...] : 获取哈希表 key 中一个或多个给定字段的值。返回值的列表,顺序与请求字段相同,不存在的字段返回 nil
    127.0.0.1:6379> HMGET user:100 name age city
    1) "Alice"
    2) "30"
    3) (nil)
  • HGETALL <key>: 获取哈希表 key 中所有的字段和值。返回一个包含字段和值的列表(字段后跟其值)。如果键不存在,返回空列表。
    127.0.0.1:6379> HGETALL user:100
    1) "name"
    2) "Alice"
    3) "email"
    4) "[email protected]"
    5) "age"
    6) "30"
  • HDEL <key> <field> [field ...] : 删除哈希表 key 中的一个或多个指定字段。返回成功删除的字段数量。
  • HLEN <key>: 返回哈希表 key 中字段的数量。
  • HEXISTS <key> <field>: 检查哈希表 key 中是否存在指定的字段 field。存在返回 1,不存在返回 0。
  • HKEYS <key>: 获取哈希表 key 中所有的字段名。
  • HVALS <key>: 获取哈希表 key 中所有的值。
  • HINCRBY <key> <field> <increment>: 为哈希表 key 中字段 field 的值(必须是整数)加上增量 increment。返回增加后的值。如果字段不存在,先创建并设为 0 再增加。
    127.0.0.1:6379> HINCRBY user:100 age 1
    (integer) 31
  • HINCRBYFLOAT <key> <field> <increment>: 为哈希表 key 中字段 field 的值(可以是浮点数)加上浮点数增量 increment。返回增加后的值(字符串形式)。
  • HSETNX <key> <field> <value>: 只在字段 field 不存在时,设置哈希表 key 中该字段的值。如果字段已存在,不执行任何操作。设置成功返回 1,字段已存在返回 0。
  • HSCAN <key> <cursor> [MATCH <pattern>] [COUNT <count>]: 增量迭代哈希表 key 中的字段和值。用法类似 SCAN

六、集合 (Set) 类型命令

Redis 集合是字符串类型的无序集合。集合中不允许有重复的元素。添加、删除、查找的时间复杂度都是 O(1)。适合存储标签、共同好友等。

  • SADD <key> <member> [member ...] : 向集合 key 中添加一个或多个成员 member。忽略已存在的成员。返回成功添加的新成员数量。
    127.0.0.1:6379> SADD tags:post:1 "redis" "database" "nosql"
    (integer) 3
    127.0.0.1:6379> SADD tags:post:1 "redis" "cache"
    (integer) 1 # "redis" 已存在,只有 "cache" 被添加
  • SMEMBERS <key>: 返回集合 key 中的所有成员。成员是无序的。
    127.0.0.1:6379> SMEMBERS tags:post:1
    1) "nosql"
    2) "database"
    3) "redis"
    4) "cache"
  • SISMEMBER <key> <member>: 判断成员 member 是否是集合 key 的成员。是返回 1,不是或键不存在返回 0。
  • SCARD <key>: 返回集合 key 的基数(成员数量)。
  • SREM <key> <member> [member ...] : 从集合 key 中移除一个或多个成员。返回成功移除的成员数量。
  • SPOP <key> [count] : 随机移除并返回集合 key 中的一个或多个成员。count 指定移除数量。
  • SRANDMEMBER <key> [count] : 随机返回集合 key 中的一个或多个成员,但不移除它们。count 正数表示返回不重复成员,负数表示可能返回重复成员。
  • 集合运算:
    • SINTER <key> [key ...] : 返回给定所有集合的交集。
    • SINTERSTORE <destination> <key> [key ...] : 将给定所有集合的交集存储在 destination 集合中。
    • SUNION <key> [key ...] : 返回给定所有集合的并集。
    • SUNIONSTORE <destination> <key> [key ...] : 将给定所有集合的并集存储在 destination 集合中。
    • SDIFF <key> [key ...] : 返回第一个集合与其他集合的差集(属于第一个集合但不属于其他集合的成员)。
    • SDIFFSTORE <destination> <key> [key ...] : 将第一个集合与其他集合的差集存储在 destination 集合中。
      127.0.0.1:6379> SADD set1 "a" "b" "c"
      (integer) 3
      127.0.0.1:6379> SADD set2 "c" "d" "e"
      (integer) 3
      127.0.0.1:6379> SINTER set1 set2
      1) "c"
      127.0.0.1:6379> SUNION set1 set2
      1) "a"
      2) "b"
      3) "c"
      4) "d"
      5) "e"
      127.0.0.1:6379> SDIFF set1 set2
      1) "a"
      2) "b"
  • SSCAN <key> <cursor> [MATCH <pattern>] [COUNT <count>]: 增量迭代集合 key 中的成员。用法类似 SCAN

七、有序集合 (Sorted Set / ZSet) 类型命令

Redis 有序集合与集合类似,也是字符串成员的集合,不允许重复。但每个成员都会关联一个 double 类型的分数 (score)。Redis 正是通过分数来为集合中的成员进行排序。成员是唯一的,但分数可以重复。适合实现排行榜、范围查询等。

  • ZADD <key> [NX|XX] [CH] [INCR] <score> <member> [<score> <member> ...] : 向有序集合 key 添加一个或多个成员,或者更新已存在成员的分数。
    • NX: 只添加新成员,不更新已存在成员。
    • XX: 只更新已存在成员,不添加新成员。
    • CH: 返回值修改的成员数(包括更新分数和新添加的)。默认只返回新添加成员数。
    • INCR: 将成员的分数加上指定的分数(此时只能指定一个 score-member 对)。类似 ZINCRBY
      127.0.0.1:6379> ZADD leaderboard 100 "player1" 95 "player2" 110 "player3"
      (integer) 3
      127.0.0.1:6379> ZADD leaderboard XX CH 105 "player1" # 更新 player1 分数
      (integer) 1 # CH 使得更新也计数
  • ZRANGE <key> <start> <stop> [WITHSCORES] : 按分数从小到大排序,返回有序集合 key 中指定区间内的成员。startstop 是基于 0 的排名下标。WITHSCORES 选项会同时返回成员和分数。
    127.0.0.1:6379> ZRANGE leaderboard 0 -1 WITHSCORES # 获取所有成员和分数,升序
    1) "player2"
    2) "95"
    3) "player1"
    4) "105"
    5) "player3"
    6) "110"
  • ZREVRANGE <key> <start> <stop> [WITHSCORES] : 按分数从大到小排序,返回指定区间内的成员。用法同 ZRANGE。常用于获取 Top N 排行榜。
    127.0.0.1:6379> ZREVRANGE leaderboard 0 0 WITHSCORES # 获取排名第一的玩家和分数
    1) "player3"
    2) "110"
  • ZRANGEBYSCORE <key> <min> <max> [WITHSCORES] [LIMIT offset count] : 按分数从小到大排序,返回有序集合 key 中分数在 minmax 之间(包含边界)的成员。
    • minmax 可以是 -inf+inf 表示负无穷和正无穷。
    • 可以使用 ( 前缀表示不包含边界,如 (95 表示大于 95。
    • LIMIT 用于分页。
      127.0.0.1:6379> ZRANGEBYSCORE leaderboard 100 110 WITHSCORES
      1) "player1"
      2) "105"
      3) "player3"
      4) "110"
  • ZREVRANGEBYSCORE <key> <max> <min> [WITHSCORES] [LIMIT offset count] : 同 ZRANGEBYSCORE,但按分数从大到小排序。注意 maxmin 的位置。
  • ZCARD <key>: 返回有序集合 key 的基数(成员数量)。
  • ZCOUNT <key> <min> <max>: 返回有序集合 key 中,分数在 minmax 之间(包含边界)的成员数量。
  • ZRANK <key> <member>: 返回有序集合 key 中成员 member 的排名(按分数从小到大,排名从 0 开始)。如果成员不存在,返回 nil
  • ZREVRANK <key> <member>: 返回有序集合 key 中成员 member 的排名(按分数从大到小,排名从 0 开始)。
  • ZSCORE <key> <member>: 返回有序集合 key 中成员 member 的分数。如果成员不存在,返回 nil
  • ZREM <key> <member> [member ...] : 移除有序集合 key 中的一个或多个成员。返回成功移除的成员数量。
  • ZREMRANGEBYRANK <key> <start> <stop>: 移除有序集合 key 中指定排名区间(从小到大)的所有成员。
  • ZREMRANGEBYSCORE <key> <min> <max>: 移除有序集合 key 中指定分数区间的所有成员。
  • ZINCRBY <key> <increment> <member>: 为有序集合 key 中成员 member 的分数加上增量 increment。返回增加后的新分数。如果成员不存在,则添加该成员,分数初始为 increment
  • ZSCAN <key> <cursor> [MATCH <pattern>] [COUNT <count>]: 增量迭代有序集合 key 中的成员和分数。用法类似 SCAN
  • 有序集合运算 (较复杂,需要注意聚合方式):
    • ZUNIONSTORE <destination> <numkeys> <key> [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] : 计算多个有序集合的并集,并将结果存入 destination。可以指定权重 WEIGHTS 和分数聚合方式 AGGREGATE (默认为 SUM)。
    • ZINTERSTORE <destination> <numkeys> <key> [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] : 计算多个有序集合的交集,并将结果存入 destination

八、发布/订阅 (Pub/Sub)

Redis 的发布/订阅功能允许客户端订阅一个或多个频道 (channel),并接收发布到这些频道的消息。

  • SUBSCRIBE <channel> [channel ...] : 订阅一个或多个频道。执行此命令后,客户端会进入订阅模式,只能接收消息或执行 SUBSCRIBE, UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PING, QUIT 命令。
    bash
    # 客户端 A
    127.0.0.1:6379> SUBSCRIBE news. Mytopic alerts
    Reading messages... (press Ctrl-C to quit)
    1) "subscribe"
    2) "news. Mytopic"
    3) (integer) 1
    1) "subscribe"
    2) "alerts"
    3) (integer) 2
  • PUBLISH <channel> <message> : 向指定频道 channel 发布一条消息 message。返回接收到消息的订阅者数量。
    bash
    # 客户端 B
    127.0.0.1:6379> PUBLISH news. Mytopic "Redis 7.0 is released!"
    (integer) 1 # 假设只有一个客户端 A 订阅了

    客户端 A 会收到:
    1) "message"
    2) "news. Mytopic"
    3) "Redis 7.0 is released!"
  • UNSUBSCRIBE [channel [channel ...]] : 退订一个或多个频道。如果不指定频道,则退订所有频道。
  • PSUBSCRIBE <pattern> [pattern ...] : 订阅一个或多个模式。客户端将接收到与模式匹配的所有频道的消息。例如 PSUBSCRIBE news.* 会收到 news. Mytopic, news. Tech 等频道的消息。
  • PUNSUBSCRIBE [pattern [pattern ...]] : 退订一个或多个模式。如果不指定模式,则退订所有模式。

九、事务 (Transaction)

Redis 事务提供了一种将多个命令打包执行的机制。事务中的命令会按顺序、原子地执行,执行期间不会被其他客户端的命令打断。Redis 事务不保证回滚(如果某个命令失败,其他已执行命令不会撤销),但能保证原子性(要么全部执行,要么全部不执行——在 EXEC 前出错的情况)。

  • MULTI: 标记事务块的开始。后续命令会被放入队列,而不是立即执行。返回 OK
  • EXEC: 执行所有在 MULTI 之后入队的命令。返回一个包含所有命令执行结果的列表。如果在 MULTIEXEC 之间有命令入队失败(例如语法错误),EXEC 会拒绝执行事务,并返回错误。如果在 EXEC 执行期间某个命令失败(例如对 String 执行 List 操作),其他命令仍会执行,EXEC 返回的结果列表中对应位置会是错误信息。
  • DISCARD: 取消事务,清空事务队列。返回 OK
  • WATCH <key> [key ...] : 监视一个或多个键。如果在 WATCH 执行之后,EXEC 执行之前,有任意被监视的键被其他客户端修改了,那么当前事务将被取消 (EXEC 返回 nil)。这提供了一种乐观锁机制。WATCH 必须在 MULTI 之前执行。
  • UNWATCH: 取消 WATCH 命令对所有键的监视。如果在执行 EXECDISCARD 后,监视会自动取消。

“`
127.0.0.1:6379> WATCH mycounter
OK
127.0.0.1:6379> GET mycounter
“10”
127.0.0.1:6379> MULTI
OK
127.0.0.1:6379> INCR mycounter
QUEUED
127.0.0.1:6379> SET anotherkey “value”
QUEUED

此时,如果另一个客户端执行了 SET mycounter 20

127.0.0.1:6379> EXEC
(nil) # 事务失败,因为被 WATCH 的 mycounter 被修改了

如果没有被修改

127.0.0.1:6379> EXEC
1) (integer) 11 # INCR mycounter 的结果
2) OK # SET anotherkey 的结果
“`

十、脚本 (Scripting) – Lua

Redis 支持使用 Lua 脚本来执行原子性的复杂操作。脚本在服务器端执行,减少了网络延迟,并保证了原子性。

  • EVAL <script> <numkeys> <key> [key ...] <arg> [arg ...] : 执行 Lua 脚本 scriptnumkeys 指定后面有多少个参数是键名 (key),剩下的参数是附加参数 (arg)。脚本中可以通过 KEYS[i] 访问键名,ARGV[i] 访问附加参数。
    lua
    -- Lua script: 原子性地获取并增加计数器,如果不存在则设为 1
    local current_val = redis.call('GET', KEYS[1])
    local new_val
    if current_val == false then
    new_val = 1
    else
    new_val = tonumber(current_val) + tonumber(ARGV[1])
    end
    redis.call('SET', KEYS[1], new_val)
    return new_val

    127.0.0.1:6379> EVAL "local current_val = redis.call('GET', KEYS[1]) \n local new_val \n if current_val == false then \n new_val = 1 \n else \n new_val = tonumber(current_val) + tonumber(ARGV[1]) \n end \n redis.call('SET', KEYS[1], new_val) \n return new_val" 1 mycounter 5
    (integer) 6 # 假设 mycounter 不存在,设为 1,然后加 5?不,这里是直接加 5,脚本逻辑需要调整,假设是加 ARGV[1]
    # 正确的脚本逻辑,假设目标是 + ARGV[1]
    # EVAL "..." 1 my_incr_counter 5
  • EVALSHA <sha1> <numkeys> <key> [key ...] <arg> [arg ...] : 通过脚本的 SHA1 校验和来执行脚本。脚本需要先用 SCRIPT LOAD 加载到服务器缓存中。这样可以避免每次都传输整个脚本。
  • SCRIPT LOAD <script>: 将脚本加载到服务器的脚本缓存中,返回脚本的 SHA1 校验和。
  • SCRIPT EXISTS <sha1> [sha1 ...] : 检查一个或多个 SHA1 校验和对应的脚本是否存在于缓存中。返回一个包含 0 或 1 的列表。
  • SCRIPT FLUSH: 清空服务器的 Lua 脚本缓存。
  • SCRIPT KILL: 尝试终止当前正在运行的、且没有执行过写操作的 Lua 脚本。

十一、持久化与其他

  • SAVE: 同步执行一次数据库快照(RDB 持久化),会阻塞服务器。
  • BGSAVE: 异步执行一次数据库快照,由子进程完成,服务器主进程继续处理请求。
  • LASTSAVE: 返回最后一次成功执行快照的 Unix 时间戳。
  • SHUTDOWN [NOSAVE|SAVE]: 关闭 Redis 服务器。NOSAVE 表示不执行快照直接关闭(可能丢失上次快照后的数据),SAVE 表示执行快照后再关闭(如果开启了 AOF,也会处理 AOF)。默认行为取决于配置。
  • FLUSHDB: 删除当前数据库的所有键。危险操作!
  • FLUSHALL: 删除所有数据库的所有键。极度危险操作!
  • CONFIG GET <parameter>: 获取服务器配置参数的值。
  • CONFIG SET <parameter> <value>: 动态修改服务器配置参数。并非所有参数都支持动态修改。
  • CLIENT LIST: 列出所有连接到服务器的客户端信息。
  • CLIENT KILL <ip:port>CLIENT KILL ID <client-id>: 关闭指定的客户端连接。

结语

本指南详细介绍了 Redis 的核心命令及其用法,涵盖了从基础连接、键管理到各种数据结构的操作,以及事务、发布订阅和 Lua 脚本等高级功能。熟练掌握这些命令是高效使用 Redis 的基础。然而,Redis 的世界远不止于此,还有集群 (Cluster)、哨兵 (Sentinel)、流 (Stream) 等更高级的主题值得深入探索。

在实际应用中,除了掌握命令本身,还需要理解各种数据结构的适用场景,设计合理的键名,关注性能(例如避免慢查询如 KEYS),并根据业务需求配置好持久化和高可用方案。希望本指南能为您在 Redis 的学习和实践道路上提供有力的支持。


发表评论

您的邮箱地址不会被公开。 必填项已用 * 标注

滚动至顶部