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. 你需要特别记住的几个区别
容易混淆的地方 正确理解
LPOPRPOP 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 记录写操作 尚未可靠落盘的修改

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

相关推荐
烟沙九洲1 小时前
Redis 缓存穿透、缓存击穿、缓存雪崩
数据库·redis
字节探索1 小时前
Redis 只会当缓存用?这 10 大实战场景,让你的系统快到飞起
redis·后端
于樱花森上飞舞2 小时前
【Redis】哨兵详解
java·开发语言·数据库·redis
Rain的Java大神之路13 小时前
如何快速上传10G文件
java·spring boot·redis·后端·mysql·spring cloud·面试
Wang's Blog14 小时前
Java 接入Redis: 通用命令与键管理
java·服务器·redis
Wang's Blog14 小时前
Java 接入Redis: 列表集合与有序集合操作命令
java·服务器·redis
行百里er1 天前
5 分钟跑起 Redis(Docker 版)
redis·后端·docker
福大大架构师每日一题1 天前
redis 8.10.2发布:安全修复集中落地,事务 ACL、集群总线与模块稳定性全面加固
redis
Pioneer000011 天前
我用 Redis + 网关做多模型 API 路由:缓存命中率 95%+ 的工程实践
人工智能·redis·后端·缓存·性能优化·架构