Redis 数据结构和使用详解(带示例)
人民网>>社会·法治

Redis 数据结构和使用详解(带示例)

2025-06-24 12:03:33 | 来源:人民网
小字号

Redis 支持的主要数据结构及其对应操作命令的详细解释,结合具体使用场景和示例:


1. 字符串(String)

  • 用途:存储文本、数值或二进制数据,适用于缓存、计数器等。

  • 常用命令

    • SET key value:设置键值对。
    • GET key:获取键对应的值。
    • INCR key:将键的值递增1(原子操作)。
    • EXPIRE key seconds:设置键的过期时间。
  • 示例

    SET user:1001:name "Alice"# 存储用户名GET user:1001:name           # 返回 "Alice"INCR article:123:views       # 文章阅读量+1
  • 场景 1:缓存用户 Token

    # 存储 Token,有效期 1 小时SET user:1001:token "abc123"EX 3600# 返回:OK# 获取 TokenGET user:1001:token# 返回:"abc123"# 检查剩余过期时间TTL user:1001:token# 返回:3590(剩余秒数)
  • 场景 2:计数器(文章阅读量)

    # 初始化阅读量SET article:2001:views 0# 返回:OK# 阅读量 +1INCR article:2001:views# 返回:1(递增后的值)# 批量递增(+5)INCRBY article:2001:views 5# 返回:6
  • 场景 3:分布式锁

    # 尝试获取锁(有效期 10 秒)SET order:lock "process123"NX PX 10000# 返回:OK(获取成功)或 nil(失败)# 释放锁(需值匹配)EVAL "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end"1order:lock process123# 返回:1(删除成功)或 0(失败)

2. 哈希(Hash)

  • 用途:存储对象字段,适合保存用户信息、商品属性等结构化数据。

  • 常用命令

    • HSET key field value:设置哈希字段值。
    • HGET key field:获取哈希字段值。
    • HGETALL key:获取所有字段和值。
  • 示例

    HSET user:1001 age 30email "alice@example.com"# 存储用户信息HGET user:1001 age                               # 返回 "30"HGETALL user:1001                                # 返回所有字段和值
  • 场景 1:存储用户信息

    # 添加用户字段HSET user:1001 name "Alice"age 30email "alice@example.com"# 返回:3(添加的字段数)# 获取单个字段HGET user:1001 name# 返回:"Alice"# 获取所有字段HGETALL user:1001# 返回:# 1) "name"# 2) "Alice"# 3) "age"# 4) "30"# 5) "email"# 6) "alice@example.com"
  • 场景 2:商品库存管理

    # 设置商品库存HSET product:5001 stock 100price 2999# 返回:2# 扣减库存(原子操作)HINCRBY product:5001 stock -1# 返回:99# 获取价格HGET product:5001 price# 返回:"2999"
  • 场景 3:配置中心

    # 存储服务配置HSET service:config timeout5000retry 3enable_cache true# 返回:3# 修改配置HSET service:config timeout10000# 返回:0(字段已存在,仅更新)# 删除配置字段HDEL service:config retry# 返回:1

3. 列表(List)

  • 用途:实现消息队列、最新消息列表(如微博时间线)。

  • 常用命令

    • LPUSH key value:从列表左侧插入元素。
    • RPOP key:从列表右侧弹出元素。
    • LRANGE key start end:获取列表范围内的元素。
  • 示例

    LPUSH news:latest "Article 1"# 插入最新新闻LPUSH news:latest "Article 2"LRANGE news:latest 04# 获取前5条新闻
  • 场景 1:消息队列

    # 生产者推送任务LPUSH task:queue "send_email:user1""generate_report:user2"# 返回:2(队列长度)# 消费者获取任务RPOP task:queue# 返回:"send_email:user1"# 查看队列剩余任务LRANGE task:queue 0-1# 返回:1) "generate_report:user2"
  • 场景 2:最新消息列表

    # 插入最新新闻LPUSH news:latest "Article 3""Article 2""Article 1"# 返回:3# 获取前 2 条新闻LRANGE news:latest 01# 返回:# 1) "Article 1"# 2) "Article 2"
  • 场景 3:阻塞队列

    # 消费者阻塞等待任务(超时 10 秒)BRPOP task:queue 10# 返回(如果有任务):# 1) "task:queue"# 2) "generate_report:user2"

4. 集合(Set)

  • 用途:存储唯一元素,支持交集、并集操作(如共同好友、标签系统)。

  • 常用命令

    • SADD key member:添加元素到集合。
    • SMEMBERS key:获取集合所有元素。
    • SINTER key1 key2:计算多个集合的交集。
  • 示例

    SADD user:1001:follows 20012002# 用户1001关注2001和2002SADD user:1002:follows 20012003SINTER user:1001:follows user:1002:follows  # 返回共同关注用户2001
  • 场景 1:标签系统

    # 添加文章标签SADD article:3001:tags "tech""redis""database"# 返回:3# 查找共同标签SINTER article:3001:tags article:3002:tags# 返回(假设 article:3002 有 "tech" 和 "cloud"):# 1) "tech"
  • 场景 2:抽奖活动

    # 添加参与者SADD lottery:2023 "user100""user200""user300"# 返回:3# 随机抽取 1 名中奖者SRANDMEMBER lottery:2023# 返回:"user200"(随机结果)# 移除并返回中奖者SPOP lottery:2023# 返回:"user100"
  • 场景 3:黑白名单

    # 添加黑名单用户SADD blacklist:ip "192.168.1.1""192.168.1.2"# 返回:2# 检查 IP 是否在黑名单SISMEMBER blacklist:ip "192.168.1.1"# 返回:1(存在)

5. 有序集合(Sorted Set)

  • 用途:排行榜、优先级队列(按分数排序)。

  • 常用命令

    • ZADD key score member:添加带分数的成员。
    • ZRANGE key start end [WITHSCORES]:按分数升序返回成员。
    • ZREVRANGE key start end:按分数降序返回成员。
  • 示例

    ZADD game:leaderboard 1500"PlayerA"# 添加玩家分数ZADD game:leaderboard 2000"PlayerB"ZREVRANGE game:leaderboard 09WITHSCORES  # 返回前10名玩家
  • 场景 1:游戏排行榜

    # 添加玩家分数ZADD game:leaderboard 1500"PlayerA"2000"PlayerB"1800"PlayerC"# 返回:3# 获取前 3 名(降序)ZREVRANGE game:leaderboard 02WITHSCORES# 返回:# 1) "PlayerB"# 2) "2000"# 3) "PlayerC"# 4) "1800"# 5) "PlayerA"# 6) "1500"
  • 场景 2:延时任务

    # 添加任务(时间戳为分数)ZADD tasks:delayed 1672531200"task1"1672617600"task2"# 返回:2# 获取当前需处理的任务(分数 <= 当前时间戳)ZRANGEBYSCORE tasks:delayed -inf1672531200# 返回:1) "task1"
  • 场景 3:热搜榜单

    # 更新关键词热度ZINCRBY hot:keywords 1"redis"# 返回:"1"(当前分数)ZINCRBY hot:keywords 1"java"# 返回:"1"# 获取 Top 10 热搜词ZREVRANGE hot:keywords 09WITHSCORES# 返回:# 1) "redis"# 2) "1"# 3) "java"# 4) "1"

6. 地理位置(GEO)

  • 用途:存储和查询地理位置(附近的人、商家)。

  • 常用命令

    • GEOADD key longitude latitude member:添加地理坐标。
    • GEODIST key member1 member2 [unit]:计算两地距离。
    • GEORADIUS key longitude latitude radius unit:查找范围内的成员。
  • 示例

    GEOADD restaurants 116.40426939.913818"RestaurantA"# 添加餐厅坐标GEORADIUS restaurants 116.40539.9142km WITHDIST      # 查找2公里内的餐厅
  • 场景 1:附近餐厅查询

    # 添加餐厅坐标GEOADD restaurants 116.40426939.913818"RestaurantA"116.40753139.915264"RestaurantB"# 返回:2# 查找 1 公里内的餐厅GEORADIUS restaurants 116.40528539.9129871km WITHDIST# 返回:# 1) 1) "RestaurantA"#    2) "0.8923"
  • 场景 2:计算距离

    # 计算两餐厅距离GEODIST restaurants "RestaurantA""RestaurantB"km# 返回:"0.312"(公里)
  • 场景 3:获取坐标

    # 获取餐厅坐标GEOPOS restaurants "RestaurantA"# 返回:# 1) 1) "116.404269"#    2) "39.913818"

7. 位图(Bitmap)

  • 用途:位操作(如用户签到、活跃统计)。

  • 常用命令

    • SETBIT key offset value:设置位的值(0或1)。
    • GETBIT key offset:获取位的值。
    • BITCOUNT key:统计值为1的位数。
  • 示例

    SETBIT user:1001:sign:202310 51# 用户1001在10月6日签到BITCOUNT user:1001:sign:202310    # 统计本月签到天数
  • 场景 1:用户签到

    # 用户 1001 在 10 月 1 日签到(偏移量 0)SETBIT user:1001:sign:202310 01# 返回:0(之前位的值)# 检查 10 月 1 日是否签到GETBIT user:1001:sign:202310 0# 返回:1
  • 场景 2:活跃用户统计

    # 统计 10 月累计签到天数BITCOUNT user:1001:sign:202310# 返回:3(假设签到 3 天)
  • 场景 3:权限控制

    # 设置权限位(位 0: 读,位 1: 写)SETBIT user:1001:permissions 01SETBIT user:1001:permissions 10# 检查写权限GETBIT user:1001:permissions 1# 返回:0(无权限)

8. HyperLogLog

  • 用途:近似去重计数(如统计UV)。

  • 常用命令

    • PFADD key element:添加元素。
    • PFCOUNT key:统计唯一元素数量。
  • 示例

    PFADD daily_uv:20231001 "user1""user2"# 记录当日访问用户PFCOUNT daily_uv:20231001                # 返回近似UV数
  • 场景 1:UV 统计

    # 记录用户访问PFADD daily_uv:20231001 "user1""user2""user1"# 返回:1(新增唯一用户数)# 获取当日 UVPFCOUNT daily_uv:20231001# 返回:2
  • 场景 2:合并多日 UV

    # 合并 10 月 1 日和 2 日的 UVPFMERGE weekly_uv:20231001-07 daily_uv:20231001 daily_uv:20231002# 返回:OK# 获取周 UVPFCOUNT weekly_uv:20231001-07# 返回:5(假设两日共有 5 个唯一用户)

9. 流(Stream)

  • 用途:消息队列(支持消费者组、消息持久化)。

  • 常用命令

    • XADD key * field1 value1:添加消息。
    • XREAD COUNT num STREAMS key $:读取消息。
    • XGROUP CREATE key groupname $:创建消费者组。
  • 示例

    XADD order:stream * user "Alice"product "Phone"# 发布订单消息XREAD COUNT 10STREAMS order:stream 0# 读取消息
  • 场景 1:订单消息队列

    # 发布订单消息XADD orders:* user_id 1001product_id 2001status "created"# 返回:"1672531200000-0"(消息 ID)# 读取最新消息XREAD COUNT 1STREAMS orders:*# 返回:# 1) 1) "orders:*"#    2) 1) 1) "1672531200000-0"#          2) 1) "user_id"#             2) "1001"#             3) "product_id"#             4) "2001"#             5) "status"#             6) "created"
  • 场景 2:消费者组

    # 创建消费者组XGROUP CREATE orders:stream order_group $# 返回:OK# 消费者读取消息XREADGROUP GROUP order_group consumer1 COUNT 1STREAMS orders:stream ># 返回:同上消息内容

10. 发布/订阅(Pub/Sub)

  • 用途:消息广播(如实时通知、聊天室)。

  • 常用命令

    • PUBLISH channel message:发布消息到频道。
    • SUBSCRIBE channel:订阅频道。
  • 示例

    SUBSCRIBE news_updates     # 订阅新闻频道PUBLISH news_updates "Redis 7.0 released!"# 发布新闻
  • 场景 1:实时通知

    # 订阅新闻频道SUBSCRIBE news# 返回:# 1) "subscribe"# 2) "news"# 3) (integer) 1# 发布新闻PUBLISH news "Redis 7.0 released!"# 订阅者接收:# 1) "message"# 2) "news"# 3) "Redis 7.0 released!"
  • 场景 2:多频道订阅

    # 订阅多个频道PSUBSCRIBE news.*# 发布到 news.techPUBLISH news.tech "New Redis features"# 订阅者接收:# 1) "pmessage"# 2) "news.*"# 3) "news.tech"# 4) "New Redis features"

总结

通过以上示例,可以得出如下总结:

数据结构典型场景核心命令
String缓存、计数器SET, GET, INCR
Hash对象存储HSET, HGET, HGETALL
List消息队列、最新列表LPUSH, RPOP, LRANGE
Set标签、共同好友SADD, SMEMBERS, SINTER
Sorted Set排行榜、优先级任务ZADD, ZRANGE, ZREVRANGE
GEO地理位置查询GEOADD, GEORADIUS
Bitmap用户签到、布尔统计SETBIT, GETBIT, BITCOUNT
HyperLogLog大数据去重计数PFADD, PFCOUNT
Stream消息队列(支持消费者组)XADD, XREAD, XGROUP
Pub/Sub实时消息广播PUBLISH, SUBSCRIBE

通过合理选择数据结构和命令,可以高效解决缓存、实时统计、消息通信等多样化需求。

(责编:人民网)

分享让更多人看到