Redis 是一个开源(BSD 许可)的内存数据结构存储,可用作数据库、缓存和消息代理。它支持多种类型的数据结构,如字符串(strings)、哈希(hashes)、列表(lists)、集合(sets)、有序集合(sorted sets)等。理解并熟练使用这些数据结构及其相关指令,是高效利用 Redis 的关键。

Redis 的强大之处在于其在内存中操作这些丰富的数据结构,使得读写速度极快。掌握每个数据结构的使用场景和对应指令,是进行高性能应用开发的基础。


一、通用键指令 (Generic Commands)

这些指令适用于所有数据类型的键。

指令 描述 示例
DEL key [key ...] 删除一个或多个键。 DEL mykey mylist
EXISTS key [key ...] 检查给定键是否存在。返回存在的键的数量。 EXISTS mykey
EXPIRE key seconds 设置键的过期时间(秒)。 EXPIRE mykey 60 (60秒后过期)
TTL key 获取键的剩余过期时间(秒)。-1 表示永久,-2 表示键不存在或已过期。 TTL mykey
PERSIST key 移除键的过期时间,使其变为永久。 PERSIST mykey
TYPE key 返回键存储值的类型。 TYPE mykey (可能返回 string, list 等)
KEYS pattern 查找所有符合给定模式的键。应避免在生产环境中使用,会阻塞 Redis。 KEYS user:*
RENAME key newkey 重命名键。 RENAME oldkey newkey
SCAN cursor [MATCH pattern] [COUNT count] 用于迭代数据库中的键,避免 KEYS 的问题。 SCAN 0 MATCH user:* COUNT 100

二、字符串 (Strings)

Redis 最基本的数据类型,可以存储文本、整数、浮点数,甚至是二进制数据。最大能存储 512MB。

指令 描述 示例
SET key value [EX seconds] [PX milliseconds] [NX|XX] 设置键值对。EX:过期秒数, PX:过期毫秒数, NX:键不存在才设置, XX:键存在才设置。 SET mykey "hello"
SET mykey "world" EX 10
SET mykey "new" NX
GET key 获取键的值。 GET mykey
MSET key value [key value ...] 同时设置多个键值对。 MSET key1 v1 key2 v2
MGET key [key ...] 同时获取多个键的值。 MGET key1 key2
INCR key 将键存储的整数值加 1。如果键不存在,则初始化为 0 后再加 1。 INCR counter
DECR key 将键存储的整数值减 1。 DECR counter
INCRBY key increment 将键存储的整数值增加指定量。 INCRBY counter 10
DECRBY key decrement 将键存储的整数值减少指定量。 DECRBY counter 5
GETSET key value 设置键的新值并返回旧值。 GETSET mykey "new_value"
APPEND key value 将值追加到键的末尾。如果键不存在,则创建键并设置值。 APPEND mykey " world" (mykey 的值变为 hello world)
GETRANGE key start end 获取字符串的子字符串。 GETRANGE mykey 0 4 (返回 hello)
SETEX key seconds value 设置键值对并指定过期时间(秒)。 SETEX mykey 60 "value"

场景示例: 用户会话存储、计数器、短 URL 映射。

三、哈希 (Hashes)

哈希是字段(field)和值(value)的映射表,非常适合存储对象。一个哈希可以存储多个字段-值对。

指令 描述 示例
HSET key field value [field value ...] 设置哈希中一个或多个字段的值。 HSET user:1 name "Alice" age 30 city "New York"
HGET key field 获取哈希中指定字段的值。 HGET user:1 name
HMSET key field value [field value ...] 同时设置多个字段的值。(已被 HSET 替代,但仍兼容) HMSET user:2 name "Bob" age 25
HMGET key field [field ...] 同时获取多个字段的值。 HMGET user:1 name city
HGETALL key 获取哈希中所有字段和值。 HGETALL user:1
HDEL key field [field ...] 删除哈希中一个或多个字段。 HDEL user:1 age
HLEN key 获取哈希中字段的数量。 HLEN user:1
HEXISTS key field 检查哈希中是否存在指定字段。 HEXISTS user:1 name
HKEYS key 获取哈希中所有字段名。 HKEYS user:1
HVALS key 获取哈希中所有字段值。 HVALS user:1
HINCRBY key field increment 将哈希中指定字段的值增加指定量。字段值必须是整数。 HINCRBY user:1 visits 1
HINCRBYFLOAT key field increment 将哈希中指定字段的浮点数值增加指定量。 HINCRBYFLOAT product:1 price 1.5
HSETNX key field value 只有当字段不存在时,才设置哈希中字段的值。 HSETNX user:1 email "alice@example.com" (如果 email 字段已存在,则不会更新)

场景示例: 存储用户对象信息、商品详情、配置设置。

四、列表 (Lists)

列表是值的有序集合。你可以向列表的两端(左侧或右侧)添加元素。

指令 描述 示例
LPUSH key value [value ...] 将一个或多个值插入到列表的头部(左侧)。 LPUSH mylist "apple" "banana" (列表: banana, apple)
RPUSH key value [value ...] 将一个或多个值插入到列表的尾部(右侧)。 RPUSH mylist "cherry" (列表: banana, apple, cherry)
LPOP key 移除并返回列表的头部元素。 LPOP mylist (返回 banana, 列表: apple, cherry)
RPOP key 移除并返回列表的尾部元素。 RPOP mylist (返回 cherry, 列表: apple)
LRANGE key start stop 返回列表中指定范围内的元素。0 表示第一个元素,-1 表示最后一个元素。 LRANGE mylist 0 -1 (返回所有)
LRANGE mylist 0 0 (返回第一个)
LLEN key 获取列表的长度。 LLEN mylist
LINDEX key index 通过索引获取列表中的元素。 LINDEX mylist 0
LREM key count value 从列表中移除与指定值相等的元素。count > 0: 从头开始移除 count 个。
count < 0: 从尾开始移除 `
count
LINSERT key BEFORE|AFTER pivot value pivot 元素之前或之后插入值。 LINSERT mylist BEFORE "apple" "pear" (列表: banana, pear, apple, cherry)
TRIM key start stop 将列表修剪到指定范围,保留范围内的元素,移除范围外的元素。通常用于实现固定长度列表。 LTRIM mylist 0 99 (只保留最新的100个元素)
BLPOP key [key ...] timeout 阻塞式左弹出。如果列表为空,则阻塞直到有元素可弹出或超时。 timeout 为 0 表示永远阻塞。 BLPOP queue1 queue2 0
BRPOP key [key ...] timeout 阻塞式右弹出。 BRPOP queue1 5 (阻塞最多 5 秒)

场景示例: 消息队列、最新文章列表、关注者时间线、任务队列。

五、集合 (Sets)

集合是无序的、不重复的字符串元素集合。

指令 描述 示例
SADD key member [member ...] 将一个或多个成员添加到集合。如果成员已存在,则忽略。 SADD myset "apple" "banana"
SMEMBERS key 返回集合中的所有成员。 SMEMBERS myset (返回 apple, banana,顺序不确定)
SISMEMBER key member 判断成员是否是集合的成员。 SISMEMBER myset "apple" (返回 1)
SCARD key 获取集合的成员数量。 SCARD myset
SREM key member [member ...] 从集合中移除一个或多个成员。 SREM myset "banana"
SPOP key [count] 随机移除并返回集合中的一个或多个成员。 SPOP myset
SRANDMEMBER key [count] 随机返回集合中的一个或多个成员,但不移除。 SRANDMEMBER myset 2 (随机返回两个成员)
SINTER key [key ...] 返回所有给定集合的交集。 SADD set1 a b c
SADD set2 b c d
SINTER set1 set2 (返回 b, c)
SUNION key [key ...] 返回所有给定集合的并集。 SUNION set1 set2 (返回 a, b, c, d)
SDIFF key [key ...] 返回第一个集合与所有其他集合的差集。 SDIFF set1 set2 (返回 a)
SINTERSTORE destination key [key ...] 将交集结果存储到目标集合。 SINTERSTORE common_elements set1 set2
SUNIONSTORE destination key [key ...] 将并集结果存储到目标集合。 SUNIONSTORE all_elements set1 set2
SDIFFSTORE destination key [key ...] 将差集结果存储到目标集合。 SDIFFSTORE unique_to_set1 set1 set2

场景示例: 标签系统、共同关注、抽奖程序、用户权限管理(例如,一个用户属于哪些角色)。

六、有序集合 (Sorted Sets / ZSETS)

有序集合是集合的变种,每个成员都关联一个分数(score),集合中的成员是唯一的,但分数可以重复。元素按照分数从小到大排序。分数相同的元素,再根据成员的字典序排序。

指令 描述 示例
ZADD key [NX|XX] [GT|LT] [CH] [INCR] score member [score member ...] 将分数和成员添加到有序集合。NX: 成员不存在才添加, XX: 成员存在才更新, CH: 改变计数, INCR: 分数递增。 ZADD myzset 1 "one"
ZADD myzset 2 "two" 3 "three"
ZADD myzset INCR 1 "one" (将 “one” 的分数加 1)
ZRANGE key start stop [WITHSCORES] 返回有序集合中指定排名范围内的成员。0 是第一个元素,-1 是最后一个元素。WITHSCORES 返回分数。 ZRANGE myzset 0 -1 WITHSCORES
ZREM key member [member ...] 从有序集合中移除一个或多个成员。 ZREM myzset "one"
ZCARD key 获取有序集合的成员数量。 ZCARD myzset
ZSCORE key member 获取有序集合中指定成员的分数。 ZSCORE myzset "two"
ZRANK key member 返回有序集合中指定成员的排名(分数从小到大排,排名从 0 开始)。 ZRANK myzset "two"
ZREVRANK key member 返回有序集合中指定成员的逆序排名(分数从大到小排,排名从 0 开始)。 ZREVRANK myzset "two"
ZRANGEBYSCORE key min max [WITHSCORES] [LIMIT offset count] 返回有序集合中指定分数范围内的成员。minmax 可以是 -inf (负无穷大) 或 +inf (正无穷大)。 ZRANGEBYSCORE myzset -inf 2 WITHSCORES
ZRANGEBYSCORE myzset (1 3 (排除分数 1 和 3)
ZRANGEBYSCORE myzset 1 3 LIMIT 0 1
ZCOUNT key min max 返回有序集合中指定分数范围内的成员数量。 ZCOUNT myzset 1 3
ZINCRBY key increment member 对有序集合中指定成员的分数进行增量操作。 ZINCRBY myzset 1 "one"
ZREMRANGEBYRANK key start stop 移除有序集合中指定排名范围内的所有成员。 ZREMRANGEBYRANK myzset 0 99 (移除排名前 100 的成员)
ZREMRANGEBYSCORE key min max 移除有序集合中指定分数范围内的所有成员。 ZREMRANGEBYSCORE myzset baits 100 200
ZUNIONSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] 计算给定多个有序集合的并集,并将结果存储到目标有序集合中。可指定权重和聚合方式。 ZADD zset1 1 "a" 2 "b" ZADD zset2 3 "a" 4 "c"
ZUNIONSTORE zunion 2 zset1 zset2 AGGREGATE MAX (a:3, b:2, c:4)
ZINTERSTORE destination numkeys key [key ...] [WEIGHTS weight [weight ...]] [AGGREGATE SUM|MIN|MAX] 计算给定多个有序集合的交集,并将结果存储到目标有序集合中。 ZINTERSTORE zinter 2 zset1 zset2 AGGREGATE SUM (a:4)

场景示例: 排行榜(游戏积分榜、最热文章榜)、带有优先级的任务队列、根据分数范围筛选数据。

七、Stream (流)

Redis 5.0 引入了 Stream 数据结构,它是一个只追加的数据结构,用于处理日志流、事件流等时间序列数据。它支持多消费者组。

指令 描述 示例
XADD key ID field value [field value ...] 添加新的条目到 Stream。ID 可以是 * (自动生成),或手动指定。 XADD mystream * sensor_id 123 temperature 25.5
XADD mystream 1-0 event_type "login" user_id 456
XRANGE key start end [COUNT count] 获取 Stream 中指定 ID 范围内的条目。minmax 可以是 "-" (最小ID) 或 "+" (最大ID)。 XRANGE mystream - +
XRANGE mystream 1678881330000-0 1678881330999-999 COUNT 10
XREAD [COUNT count] [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...] 从一个或多个 Stream 中读取条目。BLOCK 实现阻塞读取。 XREAD COUNT 2 STREAMS mystream 0-0
XREAD BLOCK 0 STREAMS mystream $ (阻塞读取最新条目)
XGROUP CREATE key groupname ID [MKSTREAM] 创建消费者组。ID 指定消费者组的起始 ID(例如 $ 表示从最新开始,0 表示从头开始)。MKSTREAM:如果 Stream 不存在则自动创建。 XGROUP CREATE mystream mygroup $ MKSTREAM
XREADGROUP GROUP groupname consumername COUNT count [BLOCK milliseconds] STREAMS key [key ...] ID [ID ...] 从消费者组中读取条目。ID> 表示从未发送给当前消费者的条目开始。 XREADGROUP GROUP mygroup myconsumer COUNT 1 STREAMS mystream >
XACK key groupname ID [ID ...] 确认消费者已处理完某个条目。 XACK mystream mygroup 1678881330000-0
XPENDING key groupname [IDLE min-idle-time] [start end count] [consumer] 获取消费者组中待处理消息列表。 XPENDING mystream mygroup
XCLAIM key groupname consumername min-idle-time ID [ID ...] 夺回(claim)其他消费者已读取但长时间未确认的条目。 XCLAIM mystream mygroup newconsumer 3600000 1678881330000-0
XTRIM key MAXLEN [~] count 裁剪 Stream,保留指定数量的最新条目。~ 大约保留。 XTRIM mystream MAXLEN 1000

场景示例: 实时消息系统、事件溯源、微服务间通信、物联网数据采集。

八、HyperLogLog (HLL)

HyperLogLog 是一种概率性数据结构,用于估算集合中元素的唯一数量(即基数)。它使用的内存非常少(固定 12KB),但会存在小部分误差。

指令 描述 示例
PFADD key element [element ...] 添加一个或多个元素到 HyperLogLog。 PFADD users:20231010 "user1" "user2" "user3"
PFCOUNT key [key ...] 返回 HyperLogLog 的近似基数。 PFCOUNT users:20231010
PFMERGE destkey sourcekey [sourcekey ...] 将多个 HyperLogLog 合并到一个新的 HyperLogLog 中。 PFMERGE users:total users:20231010 users:20231011

场景示例: 网站独立访客数统计、用户日活/月活统计、热门商品访问量统计。

九、Geospatial (地理空间)

Redis 3.2 引入了地理空间索引,允许存储和查询地理空间坐标,通常用于基于位置的服务 (LBS)。

指令 描述 示例
GEOADD key longitude latitude member [longitude latitude member ...] 添加一个或多个地理空间成员(经度、纬度和名称)。 GEOADD city_locations 13.361 38.084 "Palermo" 15.087 37.502 "Catania"
GEOPOS key member [member ...] 获取指定成员的经度和纬度。 GEOPOS city_locations "Palermo"
GEODIST key member1 member2 [UNIT] 计算两个成员之间的距离。UNIT 可以是 m (米), km (千米), mi (英里), ft (英尺)。 GEODIST city_locations "Palermo" "Catania" km
GEORADIUS key longitude latitude radius IN|OUT [UNIT] [WITHCOORD] [WITHDIST] [WITHHASH] [COUNT count] [ASC|DESC] [STORE key] [STOREDIST key] 根据中心点和半径查询附近的成员。WITHCOORD 返回坐标,WITHDIST 返回距离。 GEORADIUS city_locations 15 37 100 km WITHCOORD WITHDIST COUNT 5 ASC
GEOSEARCH key [FROMMEMBER member|FROMLONLAT longitude latitude] [BYRADIUS radius unit|BYBOX width height unit] [ASC|DESC] [COUNT count [ANY]] [WITHCOORD] [WITHDIST] [WITHHASH] 更灵活的地理空间查询指令 (Redis 6.2+)。 GEOSEARCH city_locations FROMLONLAT 15 37 BYRADIUS 100 km

场景示例: 查找附近的人/店铺、地理围栏、LBS 游戏。

十、总结

Redis 凭借其丰富的数据结构和闪电般的读写速度,使其成为现代应用开发中不可或缺的工具。

  • 字符串:最简单,用于缓存、计数器、KV 存储。
  • 哈希:适合存储对象,如用户会话、商品信息。
  • 列表:实现消息队列、时间线、LIFO/FIFO 队列。
  • 集合:去重、集合运算,如标签、共同兴趣、权限管理。
  • 有序集合:排行榜、带优先级队列、范围查询。
  • Stream:处理时间序列数据、消息队列、事件日志。
  • HyperLogLog:大数据集的基数估算,节省内存。
  • Geospatial:地理位置信息存储与查询,LBS 应用。

通过理解每种数据结构的特性和适用场景,并熟练运用其相关指令,你将能够更好地设计和优化你的应用程序,充分发挥 Redis 的强大潜力。开始使用这些指令,构建你的高性能、高并发应用吧!