掌握 Redis:核心命令使用教程 – wiki基地


掌握 Redis:核心命令使用教程(详尽版)

引言

Redis (Remote Dictionary Server) 是一个开源的、高性能的、基于内存的键值存储系统。它以其惊人的速度、丰富的数据结构支持以及灵活性,在现代 Web 应用架构中扮演着至关重要的角色。从简单的缓存层到复杂的消息队列、实时排行榜、会话管理,甚至是轻量级的主数据库,Redis 的应用场景极其广泛。

要充分发挥 Redis 的威力,深入理解并熟练运用其核心命令是必不可少的。本教程旨在提供一个全面而详细的指南,涵盖 Redis 最常用的数据类型及其核心操作命令,帮助开发者从入门到精通,真正掌握 Redis 的使用。

一、 准备工作:连接与基础

在开始探索命令之前,你需要确保已经安装了 Redis 服务,并且可以通过客户端进行连接。

  1. 安装 Redis: 根据你的操作系统(Linux, macOS, Windows via WSL/Docker),可以通过包管理器(apt, yum, brew)或从 Redis 官网下载源码编译安装。
  2. 启动 Redis 服务: 通常使用 redis-server 命令启动。
  3. 连接 Redis: 使用 Redis 自带的命令行客户端 redis-cli
    bash
    redis-cli

    如果 Redis 服务运行在不同的主机或端口,或者设置了密码,可以使用以下参数:
    bash
    redis-cli -h <hostname> -p <port> -a <password>
  4. 基本测试: 连接成功后,可以尝试 PING 命令,如果服务器正常,会返回 PONG
    127.0.0.1:6379> PING
    PONG

二、 Redis 核心数据类型与命令详解

Redis 之所以强大,很大程度上归功于其支持的多种数据结构。了解每种数据结构的特点和适用场景,并掌握对应的操作命令是关键。

(一) String(字符串)类型

这是 Redis 最基本的数据类型,可以存储任何形式的字符串,包括文本、序列化的 JSON、甚至是二进制数据(最大 512MB)。

  • 特点: 简单、高效,支持原子性的计数操作。
  • 应用场景: 缓存(页面片段、API 响应)、计数器(网站访问量、点赞数)、分布式锁、存储 Session 信息。

  • 核心命令:

    • SET key value [EX seconds|PX milliseconds] [NX|XX]
      • 设置指定 key 的值为 value
      • EX seconds: 设置键的过期时间(秒)。
      • PX milliseconds: 设置键的过期时间(毫秒)。
      • NX: 只在键不存在时,才对键进行设置操作。常用于实现分布式锁。
      • XX: 只在键已经存在时,才对键进行设置操作。
        127.0.0.1:6379> SET user:1:name "Alice"
        OK
        127.0.0.1:6379> SET cache:page:home "<HTML>..." EX 3600
        OK
        127.0.0.1:6379> SET lock:resource resource_id NX EX 10
        OK # 如果锁不存在,设置成功
        (nil) # 如果锁已存在,设置失败
    • GET key
      • 获取指定 key 的值。如果键不存在,返回 (nil)
        127.0.0.1:6379> GET user:1:name
        "Alice"
        127.0.0.1:6379> GET non_existent_key
        (nil)
    • SETEX key seconds value
      • 原子性地设置 key 的值为 value 并指定过期时间(秒)。等价于 SET key value EX seconds
        127.0.0.1:6379> SETEX session:xyz789 1800 "user_id=123&role=admin"
        OK
    • SETNX key value
      • 只在 key 不存在时设置 key 的值。等价于 SET key value NX。返回 1 表示设置成功,0 表示 key 已存在,设置失败。
    • MSET key value [key value ...]
      • 同时设置一个或多个 key-value 对。这是一个原子性操作。
        127.0.0.1:6379> MSET user:1:email "[email protected]" user:2:name "Bob"
        OK
    • MGET key [key ...]
      • 获取一个或多个指定 key 的值。返回一个列表,包含对应 key 的值,如果某个 key 不存在,则对应位置为 (nil)
        127.0.0.1:6379> MGET user:1:name user:2:name user:3:name
        1) "Alice"
        2) "Bob"
        3) (nil)
    • INCR key
      • key 中存储的数字值增一。如果 key 不存在,那么 key 的值会先被初始化为 0,然后再执行 INCR 操作。如果值不是整数类型,会返回错误。这是一个原子操作。
        127.0.0.1:6379> SET page_views 100
        OK
        127.0.0.1:6379> INCR page_views
        (integer) 101
        127.0.0.1:6379> GET page_views
        "101"
        127.0.0.1:6379> INCR counter # key 不存在
        (integer) 1
    • DECR key
      • key 中存储的数字值减一。原子操作。规则同 INCR
        127.0.0.1:6379> DECR page_views
        (integer) 100
    • INCRBY key increment
      • key 所存储的值加上指定的增量 increment。原子操作。
        127.0.0.1:6379> INCRBY page_views 50
        (integer) 150
    • DECRBY key decrement
      • key 所存储的值减去指定的减量 decrement。原子操作。
        127.0.0.1:6379> DECRBY page_views 20
        (integer) 130
    • APPEND key value
      • 如果 key 已经存在并且是一个字符串,APPEND 命令将指定的 value 追加到该 key 原来值(value)的末尾。如果 key 不存在,APPEND 就简单地将给定 key 设为 value,就像执行 SET key value 一样。返回追加后字符串的总长度。
        127.0.0.1:6379> SET mykey "Hello"
        OK
        127.0.0.1:6379> APPEND mykey " World"
        (integer) 11
        127.0.0.1:6379> GET mykey
        "Hello World"
    • STRLEN key
      • 返回 key 所储存的字符串值的长度。
        127.0.0.1:6379> STRLEN mykey
        (integer) 11

(二) List(列表)类型

Redis 列表是简单的字符串列表,按照插入顺序排序。你可以添加一个元素到列表的头部(左边)或者尾部(右边)。底层实际是双向链表(或在元素较少且长度较小时使用优化的 ziplist),所以在列表两端插入或删除元素非常快(O(1)),即使列表包含数百万个元素。

  • 特点: 有序、可重复、两端操作高效。
  • 应用场景: 消息队列(利用 LPUSH + BRPOP)、任务队列、最新动态(如微博 Timeline)、栈、队列。

  • 核心命令:

    • LPUSH key element [element ...]
      • 将一个或多个值 element 插入到列表 key 的头部(左侧)。如果 key 不存在,会创建一个空列表并执行 LPUSH 操作。返回执行 LPUSH 命令后,列表的长度。
        127.0.0.1:6379> LPUSH tasks "task3" "task2" "task1"
        (integer) 3 # 列表现在是 ["task1", "task2", "task3"]
    • RPUSH key element [element ...]
      • 将一个或多个值 element 插入到列表 key 的尾部(右侧)。返回执行 RPUSH 命令后,列表的长度。
        127.0.0.1:6379> RPUSH tasks "task4" "task5"
        (integer) 5 # 列表现在是 ["task1", "task2", "task3", "task4", "task5"]
    • LPOP key [count]
      • 移除并获取列表 key 的第一个元素(头部)。如果 key 不存在或列表为空,返回 (nil)。可选的 count 参数(Redis 6.2+)可以一次性弹出多个元素。
        “`
        127.0.0.1:6379> LPOP tasks
        “task1”

      列表现在是 [“task2”, “task3”, “task4”, “task5”]

      “`

    • RPOP key [count]
      • 移除并获取列表 key 的最后一个元素(尾部)。规则同 LPOP
        “`
        127.0.0.1:6379> RPOP tasks
        “task5”

      列表现在是 [“task2”, “task3”, “task4”]

      “`

    • LLEN key
      • 返回列表 key 的长度。
        127.0.0.1:6379> LLEN tasks
        (integer) 3
    • LRANGE key start stop
      • 返回列表 key 中指定区间内的元素。startstop 都是基于 0 的下标。0 表示列表的第一个元素,1 表示第二个,以此类推。也可以使用负数下标,-1 表示列表的最后一个元素,-2 表示倒数第二个,以此类推。LRANGE key 0 -1 可以获取列表中的所有元素。
        127.0.0.1:6379> LRANGE tasks 0 -1
        1) "task2"
        2) "task3"
        3) "task4"
        127.0.0.1:6379> LRANGE tasks 0 1
        1) "task2"
        2) "task3"
    • LINDEX key index
      • 返回列表 key 中,下标为 index 的元素。下标规则同 LRANGE。如果 index 超出范围,返回 (nil)
        127.0.0.1:6379> LINDEX tasks 1
        "task3"
        127.0.0.1:6379> LINDEX tasks -1
        "task4"
    • LINSERT key BEFORE|AFTER pivot element
      • 将值 element 插入到列表 key 当中,位于值 pivot 之前或之后。如果 pivot 不存在,不执行任何操作。如果 key 不存在,视为一个空列表,不执行操作。
        127.0.0.1:6379> LINSERT tasks BEFORE "task3" "task2.5"
        (integer) 4 # 列表现在是 ["task2", "task2.5", "task3", "task4"]
    • LTRIM key start stop
      • 对一个列表进行修剪(trim),就是说,让列表只保留指定区间内的元素,不在指定区间之内的元素都将被删除。下标规则同 LRANGE。常用于保持列表只存储最新的 N 个元素。
        “`
        127.0.0.1:6379> RPUSH logs “log entry 1” “log entry 2” … “log entry 100”

      保留最新的 50 条日志

      127.0.0.1:6379> LTRIM logs -50 -1
      OK
      “`

    • BLPOP key [key ...] timeout

      • 阻塞式列表弹出原语。它是 LPOP 的阻塞版本,当给定列表内没有任何元素可供弹出的时候,连接将被 BLPOP 命令阻塞,直到等待 timeout 超时或发现可弹出元素为止。timeout 为 0 表示无限期阻塞。可以同时监听多个 key,按 key 出现的顺序检查,返回第一个非空列表的头部元素。常用于实现可靠的消息队列消费者。
        “`

      消费者进程执行

      127.0.0.1:6379> BLPOP new_tasks 0

      (此时会阻塞,等待 new_tasks 列表有元素)

      另一个客户端(生产者)执行

      127.0.0.1:6379> LPUSH new_tasks “urgent job”
      (integer) 1

      消费者进程会立即解除阻塞并返回

      1) “new_tasks” # 弹出元素的 key
      2) “urgent job” # 弹出的元素
      ``
      *
      BRPOP key [key …] timeout*RPOP的阻塞版本,从列表尾部弹出。规则同BLPOP`。

(三) Set(集合)类型

Redis 的 Set 是 String 类型的无序集合。集合成员是唯一的,这意味着集合中不能出现重复的数据。Redis 中集合是通过哈希表实现的,所以添加、删除、查找的复杂度都是 O(1)。

  • 特点: 无序、唯一、高效的成员检查和集合运算(交集、并集、差集)。
  • 应用场景: 标签系统(给用户、文章打标签)、共同好友/关注、抽奖系统(保证唯一性)、IP 地址黑名单/白名单。

  • 核心命令:

    • SADD key member [member ...]
      • 将一个或多个 member 元素加入到集合 key 当中,已经存在于集合的 member 元素将被忽略。返回被成功添加的新成员的数量,不包括被忽略的成员。
        127.0.0.1:6379> SADD tags:article:1 "redis" "database" "nosql"
        (integer) 3
        127.0.0.1:6379> SADD tags:article:1 "redis" "performance"
        (integer) 1 # "redis" 已存在,只有 "performance" 被添加
    • SMEMBERS key
      • 返回集合 key 中的所有成员。注意:对于非常大的集合,此命令可能会阻塞服务器,生产环境慎用,考虑 SSCAN
        “`
        127.0.0.1:6379> SMEMBERS tags:article:1
        1) “nosql”
        2) “performance”
        3) “redis”
        4) “database”

      (注意:顺序是不保证的)

      “`

    • SISMEMBER key member
      • 判断 member 元素是否是集合 key 的成员。是返回 1,不是或 key 不存在返回 0
        127.0.0.1:6379> SISMEMBER tags:article:1 "redis"
        (integer) 1
        127.0.0.1:6379> SISMEMBER tags:article:1 "java"
        (integer) 0
    • SCARD key
      • 返回集合 key 的基数(集合中元素的数量)。
        127.0.0.1:6379> SCARD tags:article:1
        (integer) 4
    • SREM key member [member ...]
      • 移除集合 key 中的一个或多个 member 元素,不存在的 member 元素会被忽略。返回被成功移除的元素的数量。
        127.0.0.1:6379> SREM tags:article:1 "nosql" "nonexistent"
        (integer) 1 # 只有 "nosql" 被移除
    • SPOP key [count]
      • 随机移除并返回集合 key 中的一个或多个元素。count 参数用于指定移除数量。
        127.0.0.1:6379> SPOP tags:article:1
        "database" # 随机返回一个成员并移除
        127.0.0.1:6379> SPOP tags:article:1 2
        1) "redis"
        2) "performance" # 随机返回两个成员并移除
    • SRANDMEMBER key [count]
      • 随机返回集合 key 中一个或多个元素,但不移除它们。如果 count 是正数,返回的元素不重复;如果 count 是负数,可能返回重复的元素。
        127.0.0.1:6379> SADD myset a b c d e
        (integer) 5
        127.0.0.1:6379> SRANDMEMBER myset 2
        1) "c"
        2) "a" # 随机返回两个,不移除
        127.0.0.1:6379> SRANDMEMBER myset -5 # 可能重复
        1) "e"
        2) "a"
        3) "c"
        4) "a"
        5) "d"
    • 集合运算命令:
      • SUNION key [key ...]
        • 返回给定所有集合的并集。
          127.0.0.1:6379> SADD groupA "user1" "user2" "user3"
          (integer) 3
          127.0.0.1:6379> SADD groupB "user2" "user3" "user4"
          (integer) 3
          127.0.0.1:6379> SUNION groupA groupB
          1) "user1"
          2) "user2"
          3) "user3"
          4) "user4"
      • SINTER key [key ...]
        • 返回给定所有集合的交集。
          127.0.0.1:6379> SINTER groupA groupB
          1) "user2"
          2) "user3"
      • SDIFF key [key ...]
        • 返回第一个集合与其他集合的差集(在第一个集合中但不在其他集合中的元素)。
          127.0.0.1:6379> SDIFF groupA groupB
          1) "user1"
          127.0.0.1:6379> SDIFF groupB groupA
          1) "user4"
      • SUNIONSTORE destination key [key ...]
      • SINTERSTORE destination key [key ...]
      • SDIFFSTORE destination key [key ...]
        • 这些命令与上面的运算命令类似,但它们不是直接返回结果,而是将结果存储在 destination 集合中。如果 destination 集合已存在,会被覆盖。

(四) Sorted Set(有序集合 / ZSet)类型

Redis 有序集合和集合一样,也是 String 类型元素的集合,且不允许重复的成员。不同的是,每个元素都会关联一个 double 类型的分数(score)。Redis 正是通过分数来为集合中的成员进行从小到大的排序。有序集合的成员是唯一的,但分数(score)却可以重复。

  • 特点: 有序(根据 score)、唯一成员、高效的按 score 或成员查找、范围查询。
  • 应用场景: 排行榜(游戏积分榜、热门商品榜)、带权重的任务队列、范围查找(如查找指定分数区间的用户)。

  • 核心命令:

    • ZADD key [NX|XX] [CH] [INCR] score member [score member ...]
      • 将一个或多个 member 元素及其 score 值加入到有序集合 key 中。如果某个 member 已经是有序集的成员,那么更新这个 memberscore 值。
      • NX: 只添加新成员,不更新已存在的成员。
      • XX: 只更新已存在的成员,不添加新成员。
      • CH: 返回本次操作改变的元素数量(新增和更新的)。默认只返回新增数量。
      • INCR: 当指定此选项时,ZADD 的行为类似 ZINCRBY,对指定 memberscore 值进行增加,如果 member 不存在则添加。
        127.0.0.1:6379> ZADD leaderboard 100 "player1" 95 "player2" 110 "player3"
        (integer) 3
        127.0.0.1:6379> ZADD leaderboard 105 "player1" # 更新 player1 的分数
        (integer) 0 # 默认返回新增数量
        127.0.0.1:6379> ZADD leaderboard CH 108 "player1" 80 "player4"
        (integer) 2 # CH 返回了更新和新增的总数
    • ZRANGE key start stop [WITHSCORES]
      • 返回有序集合 key 中,指定排名区间内的成员。成员按 score 值递增(从小到大)排序。startstop 都是基于 0 的下标。WITHSCORES 选项让成员和它的 score 值一并返回。
        “`

      假设 leaderboard 现在是: player2(95), player1(108), player3(110), player4(80) -> 排序后: player4(80), player2(95), player1(108), player3(110)

      127.0.0.1:6379> ZRANGE leaderboard 0 -1 # 获取所有成员,按分数升序
      1) “player4”
      2) “player2”
      3) “player1”
      4) “player3”
      127.0.0.1:6379> ZRANGE leaderboard 0 1 WITHSCORES # 获取排名前2的成员及分数
      1) “player4”
      2) “80”
      3) “player2”
      4) “95”
      “`

    • ZREVRANGE key start stop [WITHSCORES]
      • 返回有序集合 key 中,指定排名区间内的成员。成员按 score 值递减(从大到小)排序。
        127.0.0.1:6379> ZREVRANGE leaderboard 0 1 WITHSCORES # 获取分数最高的2名
        1) "player3"
        2) "110"
        3) "player1"
        4) "108"
    • ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count]
      • 返回有序集合 key 中,所有 score 值介于 minmax 之间(包括等于 minmax)的成员。成员按 score 递增排序。
      • minmax 可以是 -inf+inf
      • 可以使用 ( 符号表示开区间,如 (95 表示大于 95。
      • LIMIT 用于分页。
        127.0.0.1:6379> ZRANGEBYSCORE leaderboard 100 110 WITHSCORES
        1) "player1"
        2) "108"
        3) "player3"
        4) "110"
        127.0.0.1:6379> ZRANGEBYSCORE leaderboard (95 +inf LIMIT 0 2 WITHSCORES # 分数大于95,取前2个
        1) "player1"
        2) "108"
        3) "player3"
        4) "110"
    • ZREVRANGEBYSCORE key max min [WITHSCORES] [LIMIT offset count]
      • 类似 ZRANGEBYSCORE,但按 score 递减排序。注意 maxmin 的位置。
    • ZCARD key
      • 返回有序集合 key 的基数(成员数量)。
        127.0.0.1:6379> ZCARD leaderboard
        (integer) 4
    • ZSCORE key member
      • 返回有序集合 key 中,成员 memberscore 值。如果 member 不存在,返回 (nil)
        127.0.0.1:6379> ZSCORE leaderboard "player1"
        "108"
    • ZCOUNT key min max
      • 返回有序集合 key 中,score 值在 minmax 之间(包括边界)的成员数量。区间表示同 ZRANGEBYSCORE
        127.0.0.1:6379> ZCOUNT leaderboard 100 110
        (integer) 2
    • ZINCRBY key increment member
      • 为有序集合 key 的成员 memberscore 值加上增量 increment。如果 member 不存在,则添加该成员,其初始 scoreincrement。返回 member 的新 score 值。原子操作。
        127.0.0.1:6379> ZINCRBY leaderboard 5 "player2" # player2 原来是 95
        "100" # 返回新的分数
    • ZREM key member [member ...]
      • 移除有序集合 key 中的一个或多个成员,不存在的成员将被忽略。返回被成功移除的成员的数量。
        127.0.0.1:6379> ZREM leaderboard "player4" "nonexistent"
        (integer) 1
    • ZRANK key member
      • 返回有序集合 key 中成员 member 的排名(按 score 升序,排名从 0 开始)。
        “`

      当前升序排名: player2(100), player1(108), player3(110)

      127.0.0.1:6379> ZRANK leaderboard “player1”
      (integer) 1
      “`

    • ZREVRANK key member
      • 返回有序集合 key 中成员 member 的排名(按 score 降序,排名从 0 开始)。
        “`

      当前降序排名: player3(110), player1(108), player2(100)

      127.0.0.1:6379> ZREVRANK leaderboard “player1”
      (integer) 1
      “`

    • ZREMRANGEBYRANK key start stop
      • 移除有序集合 key 中,指定排名区间内的所有成员(按 score 升序排名)。
    • ZREMRANGEBYSCORE key min max
      • 移除有序集合 key 中,所有 score 值介于 minmax 之间(包括边界)的成员。

(五) Hash(哈希)类型

Redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象。相对于将对象的每个属性都单独存储为 String 类型,使用 Hash 在内存占用和访问效率上通常更有优势,尤其是在对象属性较多时。

  • 特点: 键值对集合,适合存储对象结构。
  • 应用场景: 存储用户信息(如 user:id -> {name: "Alice", age: 30, email: "..."})、商品信息、配置项。

  • 核心命令:

    • HSET key field value [field value ...]
      • 将哈希表 key 中的字段 field 的值设为 value。如果 key 不存在,一个新的哈希表被创建并进行 HSET 操作。如果字段 field 已经存在于哈希表中,旧值将被覆盖。在 Redis 4.0.0 之前,HSET 一次只能设置一个字段。之后可以设置多个。返回被成功设置的字段数量(不包括更新的字段)。
        127.0.0.1:6379> HSET user:1 name "Alice" age 30 email "[email protected]"
        (integer) 3
        127.0.0.1:6379> HSET user:1 age 31 city "New York"
        (integer) 1 # age 是更新,city 是新增,返回新增数量 1
    • HGET key field
      • 获取存储在哈希表 key 中指定字段 field 的值。如果 keyfield 不存在,返回 (nil)
        127.0.0.1:6379> HGET user:1 name
        "Alice"
        127.0.0.1:6379> HGET user:1 country
        (nil)
    • HMSET key field value [field value ...]
      • (已不推荐,建议使用 HSET 代替) 同时将多个 field-value 对设置到哈希表 key 中。此命令会覆盖已经存在的字段。
    • HMGET key field [field ...]
      • 获取哈希表 key 中,一个或多个给定字段的值。返回一个列表,值按请求字段的顺序排列。如果字段不存在,对应位置为 (nil)
        127.0.0.1:6379> HMGET user:1 name age country
        1) "Alice"
        2) "31"
        3) (nil)
    • HGETALL key
      • 返回哈希表 key 中,所有的字段和值。返回的是一个包含字段和值的列表,字段和值交替出现。注意:对于包含大量字段的哈希表,此命令可能会阻塞服务器,生产环境考虑 HSCAN
        127.0.0.1:6379> HGETALL user:1
        1) "name"
        2) "Alice"
        3) "age"
        4) "31"
        5) "email"
        6) "[email protected]"
        7) "city"
        8) "New York"
    • HDEL key field [field ...]
      • 删除哈希表 key 中的一个或多个指定字段,不存在的字段将被忽略。返回被成功删除的字段的数量。
        127.0.0.1:6379> HDEL user:1 email non_existent_field
        (integer) 1
    • HLEN key
      • 返回哈希表 key 中字段的数量。
        127.0.0.1:6379> HLEN user:1
        (integer) 3 # name, age, city
    • HEXISTS key field
      • 查看哈希表 key 中,给定字段 field 是否存在。存在返回 1,不存在返回 0
        127.0.0.1:6379> HEXISTS user:1 age
        (integer) 1
        127.0.0.1:6379> HEXISTS user:1 email
        (integer) 0
    • HKEYS key
      • 返回哈希表 key 中的所有字段。
        127.0.0.1:6379> HKEYS user:1
        1) "name"
        2) "age"
        3) "city"
    • HVALS key
      • 返回哈希表 key 中的所有值。
        127.0.0.1:6379> HVALS user:1
        1) "Alice"
        2) "31"
        3) "New York"
    • HINCRBY key field increment
      • 为哈希表 key 中的字段 field 的值加上增量 increment。如果 key 不存在,会创建一个新的哈希表。如果 field 不存在,会先创建 field 并设值为 0。如果 field 的值不是整数,会返回错误。原子操作。返回执行命令之后 field 的值。
        127.0.0.1:6379> HINCRBY user:1 age 1
        (integer) 32
        127.0.0.1:6379> HINCRBY user:1 login_count 1 # field 不存在
        (integer) 1
    • HINCRBYFLOAT key field increment
      • 类似 HINCRBY,但可以处理浮点数增量。

三、 通用键(Key)管理命令

这些命令不特定于某种数据类型,而是用于管理 Redis 中的键。

  • KEYS pattern
    • 查找所有符合给定模式 patternkey* 匹配任意数量字符,? 匹配单个字符,[] 匹配括号内任一字符。
    • 警告: KEYS 命令会遍历所有键,在生产环境中对大量键使用会严重阻塞服务器,应极力避免!请使用 SCAN 命令代替。
      127.0.0.1:6379> KEYS user:*
      1) "user:1"
      2) "user:2"
      (生产环境禁用!)
  • SCAN cursor [MATCH pattern] [COUNT count] [TYPE type]
    • 基于游标的迭代器,用于增量迭代键空间。它每次调用只返回少量元素,因此可以安全地在生产环境中使用,不会阻塞服务器。
    • 需要多次调用,每次使用上次返回的游标作为下次调用的 cursor 参数,直到返回的游标为 0 表示迭代完成。
    • MATCH pattern: 只返回匹配模式的键。
    • COUNT count: 每次迭代返回的元素数量的提示(不保证精确)。
    • TYPE type: (Redis 6.0+) 只返回指定类型的键。
      “`

    第一次调用

    127.0.0.1:6379> SCAN 0 MATCH user:* COUNT 10
    1) “17” # 下一次迭代的游标
    2) 1) “user:1”
    2) “user:2”
    … (最多 10 个左右)

    后续调用

    127.0.0.1:6379> SCAN 17 MATCH user:* COUNT 10
    1) “0” # 游标为 0,迭代结束
    2) 1) “user:100”

    ``
    * 类似地,还有用于迭代 Hash 字段的
    HSCAN,迭代 Set 成员的SSCAN,迭代 Zset 成员及分数的ZSCAN`。

  • EXISTS key [key ...]
    • 检查给定的一个或多个 key 是否存在。返回存在的 key 的数量。
      127.0.0.1:6379> EXISTS user:1 non_existent_key
      (integer) 1
  • DEL key [key ...]
    • 删除给定的一个或多个 key。不存在的 key 会被忽略。返回被成功删除的 key 的数量。
      127.0.0.1:6379> DEL user:1 tasks
      (integer) 2
  • TYPE key
    • 返回 key 所储存的值的类型。可能是 string, list, set, zset, hash, streamnone (当 key 不存在时)。
      127.0.0.1:6379> SET my_string "hello"
      OK
      127.0.0.1:6379> TYPE my_string
      string
      127.0.0.1:6379> TYPE non_existent_key
      none
  • RENAME key newkey
    • key 改名为 newkey。如果 newkey 已经存在,它将被覆盖。如果 key 不存在,则返回错误。这是一个原子操作。
  • RENAMENX key newkey
    • newkey 不存在时,将 key 改名为 newkey。如果 newkey 已存在,则操作失败。原子操作。
  • EXPIRE key seconds
    • 为给定 key 设置生存时间(秒)。当 key 过期时,它会被自动删除。返回 1 表示成功设置,0 表示 key 不存在或设置失败。
      127.0.0.1:6379> SET temp_data "important info"
      OK
      127.0.0.1:6379> EXPIRE temp_data 60 # 60 秒后自动删除
      (integer) 1
  • PEXPIRE key milliseconds
    • 类似 EXPIRE,但单位是毫秒。
  • TTL key
    • 以秒为单位,返回给定 key 的剩余生存时间。
    • 返回 -1 表示 key 存在但没有设置过期时间(永久)。
    • 返回 -2 表示 key 不存在。
      127.0.0.1:6379> TTL temp_data
      (integer) 58 # (过了几秒后查询)
  • PTTL key
    • 类似 TTL,但单位是毫秒。
  • PERSIST key
    • 移除给定 key 的生存时间,将这个 key 从『易失的』(带生存时间 key) 转换为『持久的』(一个不带生存时间、永不过期的 key)。成功返回 1,如果 key 不存在或本身就是持久的,返回 0
      127.0.0.1:6379> PERSIST temp_data
      (integer) 1
      127.0.0.1:6379> TTL temp_data
      (integer) -1 # 变为永久

四、 进阶概念与相关命令(简介)

除了上述核心数据结构和键管理命令,Redis 还有一些重要的机制和相关命令值得了解:

  • 事务 (Transactions):
    • Redis 事务允许将一组命令打包,然后一次性、按顺序地执行。
    • 核心命令: MULTI (开启事务), EXEC (执行事务), DISCARD (取消事务), WATCH key [key ...] (乐观锁)。
    • Redis 事务不保证原子性(如果事务中的某个命令执行出错,其他命令仍会执行),但能保证隔离性(事务执行期间不会被其他客户端命令打断)。WATCH 提供了检查与设置(Check-and-Set)的机制,用于处理并发冲突。
  • 发布/订阅 (Publish/Subscribe):
    • 一种消息通信模式,发送者(publisher)发送消息到频道(channel),订阅者(subscriber)接收它们感兴趣的频道的消息。
    • 核心命令: SUBSCRIBE channel [channel ...], UNSUBSCRIBE [channel [channel ...]], PUBLISH channel message, PSUBSCRIBE pattern [pattern ...], PUNSUBSCRIBE [pattern [pattern ...]]
    • Pub/Sub 是“即发即弃”的,不保证消息的持久化。
  • 持久化 (Persistence):
    • 为了防止服务器宕机导致内存数据丢失,Redis 提供了两种持久化方式:
      • RDB (Redis Database Backup): 在指定的时间间隔内生成数据集的时间点快照(snapshot)。适合备份,恢复速度快,但可能丢失最后一次快照后的数据。
      • AOF (Append Only File): 记录服务器接收到的所有写操作命令,并在服务器启动时重新执行这些命令来恢复数据。数据安全性更高,但文件可能较大,恢复速度相对较慢。
    • 可以通过配置文件 (redis.conf) 或 CONFIG SET 命令进行设置。相关命令如 SAVE (同步 RDB), BGSAVE (后台异步 RDB), BGREWRITEAOF (重写 AOF 文件)。
  • Lua 脚本 (Lua Scripting):
    • 允许用户在 Redis 服务器端执行 Lua 脚本,可以实现复杂的原子操作,减少网络开销。
    • 核心命令: EVAL script numkeys key [key ...] arg [arg ...], EVALSHA sha1 numkeys key [key ...] arg [arg ...], SCRIPT LOAD script, SCRIPT EXISTS sha1 [sha1 ...], SCRIPT FLUSH, SCRIPT KILL

五、 最佳实践与建议

  1. Key 命名: 使用有意义且结构化的 Key 名,如 object-type:id:field(例如 user:1001:profile)。这有助于管理和调试。
  2. 设置过期时间: 对缓存类数据、Session 等临时数据,务必使用 EXPIRESETEX 设置合理的过期时间,防止内存无限增长。
  3. 避免使用耗时命令: 在生产环境中,避免使用如 KEYS, SMEMBERS, HGETALL, LRANGE 0 -1(对超大列表)等可能阻塞服务器的操作。优先使用 SCAN 系列命令进行迭代。
  4. 内存管理: 监控 Redis 内存使用情况 (INFO memory)。选择合适的数据结构(例如,用 Hash 存储对象比多个 String 更节省内存)。考虑使用 Redis 的内存淘汰策略(如 LRU, LFU)。
  5. 安全: 绑定 Redis 到内网 IP (bind 127.0.0.1 或内网地址),设置强密码 (requirepass),考虑使用 Redis 6.0+ 的 ACL(访问控制列表)进行更细粒度的权限管理。

结语

Redis 是一个功能强大且灵活的工具。掌握其核心数据结构和命令是有效利用 Redis 的第一步,也是最重要的一步。本教程覆盖了最常用的命令和概念,但这仅仅是冰山一角。随着你对 Redis 的深入使用,还会接触到 Stream 数据类型、地理空间索引、HyperLogLog、Bitmap、Redis Modules 等更多高级特性。

理论学习固然重要,但更关键的是动手实践。尝试在你的项目中使用 Redis 解决实际问题,比如实现缓存、构建排行榜、或者设计一个简单的消息队列。通过不断的实践和探索,你将能够更加深刻地理解 Redis 的精髓,并将其威力发挥到极致。祝你在 Redis 的世界里探索愉快!


发表评论

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

滚动至顶部