Redis 键空间 & 五大类型

目录

环境与工具

[Redis 键空间 & 五大类型](#Redis 键空间 & 五大类型)

什么是键空间(Keyspace)

[1. String(字符串)](#1. String(字符串))

[2. List(链表,双端队列)](#2. List(链表,双端队列))

[3. Hash(哈希)](#3. Hash(哈希))

[4. Set(无序集合,去重)](#4. Set(无序集合,去重))

[5. ZSet(有序集合,排行榜)](#5. ZSet(有序集合,排行榜))

[6. 键空间运维](#6. 键空间运维)

[Spring Boot 集成 Redis(五大类型练习)](#Spring Boot 集成 Redis(五大类型练习))


环境与工具

在 WSL2 中用 Docker 拉起 redis:latest,映射 6379 和数据卷。

用 redis-cli 连上本地 Redis,完成 PING → PONG。

新建 Spring Boot 空项目,加入 spring-boot-starter-data-redis 依赖,跑通最简单的 StringRedisTemplate 读写。

具体实现:

一、环境准备

  1. 确认 WSL2 + Docker 安装

Windows 开启 WSL2,并安装 Ubuntu。

安装 Docker Desktop,设置后台引擎为 WSL2 集成。

在 WSL2 里输入:

bash 复制代码
docker --version

确认能用

二、Docker 拉起 Redis

  1. 拉取官方镜像:
bash 复制代码
docker pull redis:latest
  1. 启动容器(映射 6379 端口 & 挂载数据卷):
bash 复制代码
docker run -d \
  --name myredis \
  -p 6379:6379 \
  -v ~/redis-data:/data \
  redis:latest \
  redis-server --appendonly yes

-p 6379:6379 → 把容器端口映射到宿主机

-v ~/redis-data:/data → 把持久化数据挂载到宿主机

redis-server --appendonly yes → 开启 AOF 持久化

  1. 查看运行情况:
bash 复制代码
docker ps

三、使用 redis-cli 测试

  1. 进入容器内运行 redis-cli:
bash 复制代码
docker exec -it myredis redis-cli
  1. 测试连接:
bash 复制代码
127.0.0.1:6379> PING
PONG

说明 Redis 已经启动成功。

Redis 键空间 & 五大类型

什么是键空间(Keyspace)

在 Redis 里,所有数据都是以键值对 (key-value) 的形式存储的。

键(key)= 唯一的名字(字符串)

值(value)= 可以是任意一种数据结构

Redis 内部就像有一个 巨大的字典(hash table),里面装满了这些 key-value

这个全局字典就叫做键空间

简单理解:

MySQL 有很多数据库,每个数据库里有很多表,每张表里有行。

Redis 有一个键空间,所有的 key 都放在这里,每个 key 指向一种数据类型的值

所以键空间意思就是所有键的存放空间

1. String(字符串)

bash 复制代码
SET name "alice"         # O(1)
GET name                 # "alice"

INCR counter             # 自增(不存在时会设为 0 再 +1)
INCR counter             # 再加 1 → counter = 2

EXPIRE counter 10        # 设置 10 秒过期
TTL counter              # 查看剩余寿命

GETRANGE name 0 2        # 截取子串 → "ali"

MSET a 100 b 200         # 一次设置多个键
MGET a b                 # 一次获取多个键

INCR全称 INCRement,含义自增

EXPIRE 全称 EXPIRE(动词,过期),含义为某个键设置生存时间(TTL)

语义是告诉 Redis 这个键在 N 秒后过期

TTL全称是 Time To Live(生存时间),含义是返回某个键剩余还能活多久(单位秒)

GETRANGE 全称是GET RANGE,含义是获取字符串值的指定范围子串

参数:起始下标、结束下标(包含)

MSET: Multi SET(一次设置多个键值对)
MGET: Multi GET(一次获取多个键值)

前缀 M 表示批量操作

2. List(链表,双端队列)

bash 复制代码
LPUSH nums 1 2 3         # 左插入 → nums = [3,2,1]
RPUSH nums 4 5           # 右插入 → nums = [3,2,1,4,5]

LRANGE nums 0 -1         # 遍历 → ["3","2","1","4","5"]

LPOP nums                # 从左取一个 → "3"
BLPOP nums 5             # 阻塞式取(等待 5 秒)

LPUSH

L = Left(左边) PUSH = 入栈 / 插入

含义是从 左边(头部)插入一个或多个元素到列表。

LPUSH nums 1 2 3 把 1,2,3 依次插入左边,结果是 3,2,1

RPUSH

R = Right(右边)

PUSH = 插入

含义是从 右边(尾部)插入一个或多个元素

RPUSH nums 4 5 在右边插入,结果是 3,2,1,4,5

LRANGE

L = List

RANGE = 范围

含义是获取列表中指定范围的元素

参数是起始索引和结束索引,支持负数索引(-1 表示最后一个)

LRANGE nums 0 -1 → 取出整个列表

LPOP

L = Left(左边)

POP = 出栈 / 移除并返回

含义是从左边弹出一个元素,并返回该值

LPOP nums → 返回 "3",列表变成 2,1,4,5

BLPOP

B = Blocking(阻塞式)

LPOP = 左出栈

含义是从左边弹出一个元素,如果列表为空,就阻塞等待一段时间(直到有元素被插入,或超时)

BLPOP nums 5 → 如果 5 秒内有人 LPUSH 新值,就会立即返回,否则超时

3. Hash(哈希)

bash 复制代码
HSET user:1 name "alice" age 20
HGET user:1 name
HGETALL user:1

HINCRBY user:1 age 1     # 年龄 +1 → age=21
HEXISTS user:1 email     # 检查 email 是否存在

HSET

H = Hash

SET = 设置

含义是往哈希表里设置某个字段的值

HGET

H = Hash

GET = 获取

含义是获取哈希表里某个字段的值

HGETALL

ALL = 全部

含义是一次性取出哈希表里的所有字段和值

HINCRBY

INCRBY = increase by(增加多少)

含义是让某个字段的数值加上指定增量

HEXISTS

EXISTS = 是否存在

含义是检查某个字段是否存在

4. Set(无序集合,去重)

bash 复制代码
SADD tags redis nosql cache
SMEMBERS tags            # 查看所有成员
SISMEMBER tags redis     # 是否存在 → 1

SADD tags2 redis db
SINTER tags tags2        # 交集 → redis

SCARD tags               # 集合大小

SADD

S = Set

ADD = 添加

含义是向集合中添加一个或多个元素(自动去重)

SADD tags redis nosql cache = 向 tags 集合里加入 3 个元素

SMEMBERS

S = Set

MEMBERS = 成员们

含义是返回集合里的所有成员

SMEMBERS tags = 列出集合 tags 的全部元素

SISMEMBER

S = Set

ISMEMBER = 是否是成员

含义是判断某个值是不是集合中的元素(返回 1 表示存在,0 表示不存在)

SISMEMBER tags redis = 检查 redis 是否在集合里

SINTER

S = Set

INTER = Intersection(交集)

含义是返回多个集合的交集

SINTER tags tags2 = tags ∩ tags2

SCARD

S = Set

CARD = Cardinality(集合基数 = 元素个数)

含义是返回集合里元素的数量

SCARD tags 集合里有多少元素

5. ZSet(有序集合,排行榜)

bash 复制代码
ZADD scores 100 "Alice" 200 "Bob" 150 "Cindy"
ZRANGE scores 0 -1 WITHSCORES      # 按分数升序
ZREVRANGE scores 0 -1 WITHSCORES   # 按分数降序(排行榜)

ZINCRBY scores 10 "Alice"          # Alice 分数+10
ZREMRANGEBYRANK scores 0 0         # 删除排名最末 1 个

Redis 的 ZADD 命令要求严格按照 score member(分数在前,成员在后) 的顺序成对传入参数

ZADD

Z = ZSet (Sorted Set)

ADD = 添加

含义是往有序集合里添加一个或多个元素,并指定分数(score)

ZADD scores 100 "Alice" → 插入 "Alice",分数 = 100

ZRANGE

Z = ZSet

RANGE = 范围

含义是按分数升序,取指定下标范围的成员

ZRANGE scores 0 -1 → 获取所有元素,按分数从小到大排序

ZREVRANGE

Z = ZSet

REV = Reverse(反向)

RANGE = 范围

含义是按分数降序,取指定下标范围的成员

ZREVRANGE scores 0 -1 → 排行榜模式,从高分到低分

WITHSCORES 用于同时返回成员的分数

ZINCRBY

Z = ZSet

INCRBY = Increase by(增加多少)

含义是给某个成员的分数加上指定值

ZINCRBY scores 10 "Alice" → "Alice" 的分数 +10

ZREMRANGEBYRANK

Z = ZSet

REM = Remove(删除)

RANGE = 范围

BYRANK = 根据排名

含义是删除按排名排序后处于某个范围的元素

ZREMRANGEBYRANK scores 0 0 → 删除分数最低的 1 个

要删除分数最高的 3 个的成员,可以这样写:

bash 复制代码
ZREMRANGEBYRANK key 0 2  # 错误:这会删除分数最低的3个

# 正确做法(删除分数最高的3个):
ZREMRANGEBYRANK key -3 -1

支持负数索引(-1 表示分数最高的成员)

6. 键空间运维

bash 复制代码
SCAN 0 MATCH "user:*" COUNT 10   # 分批扫描键
DEL name                         # 删除
UNLINK nums                      # 异步删除(避免阻塞)

1. SCAN 0 MATCH "user:*" COUNT 10

作用:扫描键空间,分批返回 key,避免一次性返回太多阻塞 Redis。

参数:

0 → 游标位置,初始必须从 0 开始。返回结果里会带一个新的游标,下次继续扫描时用。直到返回 0 说明扫描完了。

MATCH "user:*" → 匹配模式,这里就是扫描所有以 user: 开头的键。
COUNT 10 → 建议每次返回 10 个 key

这个 COUNT 10 的意思是:我建议 Redis 每次最多返回 10 个 key

但 Redis 不会严格保证一定就是 10 个。可能返回 3 个、也可能 15 个

为什么要用 SCAN 而不是 KEYS *?

KEYS * 会一次性返回所有 key,可能导致 Redis 阻塞(特别是 key 很多时)

SCAN 是 渐进式迭代,对性能更安全。

2. DEL name

DEL = delete

作用:立即删除 key name 以及对应的 value。

特点:

同步删除(马上执行)

如果 value 特别大(比如一个包含百万条元素的 List),会阻塞 Redis 一段时间

3. UNLINK nums

UNLINK = unlink(断开链接)

作用:把 key nums 标记为删除,但实际释放内存的操作交给后台线程异步执行。

好处:不会阻塞主线程,适合删除大对象。

区别:

DEL → 立即释放内存(同步,可能卡顿)

UNLINK → 异步释放内存(更安全)

总结

SCAN:安全地扫描所有 key(代替 KEYS)

DEL:立即删除 key(小对象可用)

UNLINK:异步删除 key(大对象推荐)

Spring Boot 集成 Redis(五大类型练习)

  1. Spring Initializr(https://start.spring.io/) 创建项目:

Project: Maven / Gradle

Language: Java

Spring Boot: 最新稳定版

Dependencies: Spring Web, Spring Data Redis

  1. Maven 依赖(pom.xml):
XML 复制代码
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
  1. 配置 Redis 连接

在 application.yml 中写:

XML 复制代码
spring:
  data:
    redis:
      port: 6379
      host: localhost

注入 StringRedisTemplate 和 RedisTemplate

java 复制代码
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.*;

import java.util.List;
import java.util.Map;
import java.util.Set;

@RestController
@RequestMapping("/redis")
public class RedisDemoController {

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    // String 示例
    @GetMapping("/string")
    public String stringOps() {
        stringRedisTemplate.opsForValue().set("name", "alice");
        return stringRedisTemplate.opsForValue().get("name");
    }

    // List 示例
    @GetMapping("/list")
    public List<String> listOps() {
        stringRedisTemplate.opsForList().leftPushAll("nums", "1", "2", "3");
        return stringRedisTemplate.opsForList().range("nums", 0, -1);
    }

    // Hash 示例
    @GetMapping("/hash")
    public Map<Object, Object> hashOps() {
        stringRedisTemplate.opsForHash().put("user:1", "name", "bob");
        stringRedisTemplate.opsForHash().put("user:1", "age", "20");
        return stringRedisTemplate.opsForHash().entries("user:1");
    }

    // Set 示例
    @GetMapping("/set")
    public Set<String> setOps() {
        stringRedisTemplate.opsForSet().add("tags", "redis", "nosql", "cache");
        return stringRedisTemplate.opsForSet().members("tags");
    }

    // ZSet 示例
    @GetMapping("/zset")
    public Set<String> zsetOps() {
        stringRedisTemplate.opsForZSet().add("scores", "Alice", 100);
        stringRedisTemplate.opsForZSet().add("scores", "Bob", 200);
        return stringRedisTemplate.opsForZSet().reverseRange("scores", 0, -1);
    }
}

启动项目 & 测试接口

Spring Boot 项目跑在 http://localhost:8080

GET http://localhost:8080/redis/string → "alice"

GET http://localhost:8080/redis/list"3","2","1"

GET http://localhost:8080/redis/hash → {"name":"bob","age":"20"}

GET http://localhost:8080/redis/set"redis","nosql","cache"

GET http://localhost:8080/redis/zset"Bob","Alice"

Template = Spring 的操作模板工具类,封装常用 API,简化操作,类似 JdbcTemplate、RestTemplate

String = 说明 key 和 value 都用字符串序列化,存进去/取出来都是明文

所以 StringRedisTemplate = 专门操作字符串类型的 Redis 工具类模板
ops = operations(操作入口)

value = Redis 的 String 类型(键值对里的值)

opsForValue() = 获取操作 String 类型数据的工具
ops = operations(操作入口)

List = Redis 的 List 类型(链表)

opsForList() = 获取操作 Redis List 的工具
leftPushAll对应 Redis 的 LPUSH 命令,往列表左边批量插入多个元素

range对应 Redis 的 LRANGE 命令,按下标区间获取列表元素
put 对应 Redis 的 HSET 命令

entries 对应 Redis 的 HGETALL 命令

相关推荐
咩咩啃树皮8 小时前
第40篇:Vue3组件化开发精讲——组件拆分、复用、父子通信、工程化架构
java·前端·架构
鱟鲥鳚8 小时前
Spring Boot 集成 LangChain4j:从模型调用到 Tool Calling(Demo版)
java·spring boot
大模型码小白10 小时前
【Python零基础教程】继承、多态与魔法函数:面向对象编程三大核心特性详解
java·大数据·开发语言·人工智能·python·ai编程
腾渊信息科技公司10 小时前
Spring Boot对接MES实战:视觉检测数据自动同步方案
java·人工智能·spring boot·后端·计算机视觉·ai·软件需求
爱笑的源码基地11 小时前
高并发 Redis 缓存门诊HIS系统源码,含财务统计药房进销存
java·程序·门诊系统·诊所系统·云诊所源码
wuqingshun31415911 小时前
TCP超时重传机制是为了解决什么问题?
java
二宝哥12 小时前
CentOS 7.9 系统下 Redis 5.0.4 单机安装与源码编译安装指南
redis·centos
莫逸风14 小时前
【AgentScope 2.0】 0. 学习指南
java·llm·agent·agentscope
生活爱好者!14 小时前
我把NAS当作下载机,docker一键部署qb
运维·docker·容器
z1234567898614 小时前
2026最新两款AI编程工具深度对比实测
java·数据库·ai编程