Redis基础

1. Redis 是什么

Redis 是主要基于内存的键值型数据库,数据以 key → value 的形式保存。

复制代码
user:1:name → 张三
  • key 是数据的名字,value 是保存的内容。
  • user:1:name 中的冒号是命名约定,不是真正的文件夹。
  • Redis 常用于缓存、验证码、计数、排行榜等。
  • Redis 支持持久化,可以把数据保存到磁盘。
  • Redis 属于 NoSQL,但不能把所有 NoSQL 都理解成内存数据库。
2. 五种常用数据类型
类型 特点 常见用途
String 保存一个字符串,也能保存数字文本 验证码、JSON 缓存、计数
Hash 一个 key 内保存多个字段和值 用户资料
List 按位置排列,允许重复,可从两端操作 列表、简单队列
Set 成员不重复,不保证排列顺序 好友集合、去重
ZSet 成员不重复,每个成员带分数,按分数排序 排行榜
3. 常用命令
类型 命令示例 含义
String SET name "张三" 写入,已有 key 时覆盖
String GET name 读取
String INCR views 整数值加 1
String INCRBY views 5 整数值加 5
String SETNX name "李四" 仅当 key 不存在时写入
Hash HSET user:1 name "张三" age 20 设置字段
Hash HGET user:1 name 读取一个字段
Hash HGETALL user:1 读取全部字段和值
Hash HINCRBY user:1 age 2 数字字段加 2
List LPUSH names "张三" 从左端放入
List RPUSH names "李四" 从右端放入
List LPOP names / RPOP names 从左端/右端移除并返回
List LRANGE names 0 -1 查看整个列表
Set SADD friends "张三" "李四" 添加成员,自动去重
Set SCARD friends 查询成员数量
Set SMEMBERS friends 查询所有成员
Set SINTER A B 交集:双方都有
Set SUNION A B 并集:合并并去重
Set SDIFF A B 差集:A 有、B 没有
ZSet ZADD scores 85 "张三" 设置成员及其分数
ZSet ZSCORE scores "张三" 查询分数
ZSet ZINCRBY scores 10 "张三" 分数增加 10
ZSet ZREVRANGE scores 0 2 WITHSCORES 查询分数从高到低的前三名及分数

特别注意:

复制代码
ZADD scores 85 "张三" 92 "李四" 78 "王五"

添加的是 3 个成员。参数按"分数、成员"配对,分数是成员的属性。

4. 通用命令与有效期
命令 含义
EXISTS key 判断 key 是否存在
DEL key 删除整个 key
TYPE key 查看 value 的类型
EXPIRE key 60 设置 60 秒有效期
TTL key 查看剩余有效期

TTL 返回值:

  • 大于等于 0:剩余秒数,0 表示不足一秒。
  • 1:key 存在,但没有有效期。
  • 2:key 不存在。

可以在写入时一起设置有效期:

复制代码
SET code "583921" EX 60

仅在不存在时写入,并设置有效期:

复制代码
SET code "583921" NX EX 60

普通 SET 覆盖数据时,会清除原有有效期。

5. 你需要特别记住的几个区别
容易混淆的地方 正确理解
LPOP 与 RPOP L 是左,R 是右
SADD 的返回值 本次新增了几个成员
SCARD 的返回值 集合总共有几个成员
Hash 的 key 与 field user:1 是 key,name 是内部字段
GET 的用途 只能读取 String,不能读取所有类型
同名 key 的类型 同一数据库内,一个 key 同时只能对应一种类型
SET 覆盖 Hash 会替换整个 Hash,原字段消失
类型不匹配 通常报 WRONGTYPE
6. Java 怎样操作 Redis
  • redis-server:服务端,存储数据、执行命令。
  • redis-cli:命令行客户端。
  • Jedis、Lettuce:Java 客户端库。
  • Spring Data Redis:封装客户端,方便 Spring 项目使用。

StringRedisTemplate 的操作入口:

类型 Java 方法
String opsForValue()
Hash opsForHash()
List opsForList()
Set opsForSet()
ZSet opsForZSet()

例如:

复制代码
stringRedisTemplate.opsForValue().set("name", "张三");
String name = stringRedisTemplate.opsForValue().get("name");

ZSet 的参数顺序要注意:

复制代码
Redis:ZADD key 分数 成员
Java: add(key, 成员, 分数)
7. 序列化与连接池

序列化解决"Java 对象怎样保存"的问题:

复制代码
Java 对象 → 序列化 → JSON 字符串 → Redis
Java 对象 ← 反序列化 ← JSON 字符串 ← Redis

String 保存 JSON,通常整体读写;Hash 分字段保存,可以直接修改单个字段。

连接池解决"连接怎样重复使用"的问题:

复制代码
借连接 → 执行命令 → 归还连接
  • 普通 Jedis 实例不应由多个线程同时随意使用。
  • 从连接池借出的 Jedis,正常情况下调用 close() 是归还连接。
  • 使用 StringRedisTemplate 的常规操作时,不需要自己手动借还 Jedis 连接。
8. 缓存的基本流程
复制代码
请求查询用户
    ↓
先查 Redis
    ├─ 命中 → 返回
    └─ 未命中 → 查询 MySQL
                    ↓
                写入 Redis
                    ↓
                  返回

用户信息更新后,一种常见基础做法是:先成功更新并提交数据库,再删除对应缓存,下次查询重新加载。复杂并发场景还需要进一步处理一致性。

有效期不会让缓存随数据库修改而立即更新。

9. 原子性

"先 GET、程序加一、再 SET"是多个步骤,并发时可能丢失计数。

复制代码
INCR views

把加一交给 Redis 一次完成,可以避免这种问题。

同样:

复制代码
SET code "583921" EX 60

能避免分两条命令时,写入成功却没来得及设置有效期。

单个原子操作,不代表多条命令组合起来也具有原子性。

10. 过期、淘汰与持久化
机制 解决什么问题
过期 数据什么时候失效
内存淘汰 内存达到上限时,哪些数据需要腾出空间
持久化 重启后怎样恢复数据

过期数据通过访问时检查和周期性清理来删除,不一定在到期瞬间立即释放内存。

典型内存策略:

  • noeviction:不淘汰,无法满足的写入报错。
  • allkeys-lru:优先淘汰最近较少使用的数据。
  • allkeys-lfu:优先淘汰使用频率较低的数据。

两种主要持久化方式:

方式 核心思路 可能丢失的数据
RDB 保存某个时刻的数据快照 最近快照之后的修改
AOF 记录写操作 尚未可靠落盘的修改

持久化不等于历史备份,误删除也可能被持久化。

相关推荐
行百里er8 小时前
Redis 模块——JSON、向量搜索与时序
redis·后端
蓝胖的四次元口袋8 小时前
Redis知识梳理(1)
数据库·redis·缓存
wefg19 小时前
【Redis】C++ 自定义客户端
数据库·redis·缓存
一个有温度的技术博主12 小时前
两级缓存一致性实战:Redis + 本地缓存,如何不让数据“分裂”?
redis·spring·缓存
码途行者13 小时前
缓存一致性难题:Redis 和数据库如何做到数据一致?
数据库·redis
linweidong15 小时前
Redis 集群故障排查与修复实战:从 Connection refused 到内存打满的七个现场
运维·数据库·redis·缓存·redis集群·运维面经·实施面经
用户62228840481915 小时前
Redis 内存管理与过期淘汰策略:从 maxmemory 到 LRU / LFU,一篇讲透
java·redis
Sand(ContextGate)17 小时前
从零搭建电商智能导购 Agent:LangGraph 编排 + 三层记忆 + 熔断降级 + 生产部署全链路实战
redis·agent·fastapi·电商·chromadb·langgraph·智能导购
bksczm18 小时前
Redis基础篇之初识分布式
数据库·redis·分布式
jyOverQ18 小时前
Redis 主从复制、Sentinel 和 Cluster 到底有什么区别?
java·redis·sentinel