前言
这个笔记是《黑马程序员Redis入门到实战教程》视频的笔记。
1.认识Redis
Redis诞生于2009年全称是Remote Dictionary Server,远程词典服务器,是一个基于内存的键值型NoSQL数据库。
特征:
- 键值(key-value)型,value支持多种不同数据结构,功能丰富
- 单线程,每个命令具备原子性
- 低延迟,速度快(基于内存、IO多路复用、良好的编码)。
- 支持数据持久化
- 支持主从集群、分片集群
- 支持多语言客户端
2.安装并配置Redis环境(基于WSL2)
sudo apt update
sudo apt install -y redis-server
在配置服务时直接访问127.0.0.1:6379
即可从windows访问到wsl里面的redis。
3.Redis数据结构
数据结构 | 示例(图中) | 典型用途 / 场景 | 使用注意点 / 设计建议 |
---|---|---|---|
String | hello world | 缓存单一值(如配置、token、序列号)、计数器、分布式锁(配合SET NX PX )、简单对象序列化后的 JSON | 体量大对象可分片或压缩;计数用INCR 避免并发丢失;做锁需设置过期并注意原子性与续租 |
Hash | {name: "Jack", age: 21} | 存储结构化对象(用户信息、商品属性)、局部字段更新、配置集合 | 字段数量巨大时可能退化为普通 dict 造成内存开销;避免频繁HGETALL ,改用指定字段;字段过多可拆分 |
List | [A -> B -> C -> C] | 消息队列(简单)、任务队列、时间顺序日志、分页(小规模) | 作为队列时避免阻塞/丢失可引入 ACK 机制或用 Stream;列表很长LRANGE 成本线性;大批量左进右出更适合 |
Set | {A, B, C} | 去重集合(标签、关注集合、黑名单)、集合运算(共同好友)、抽奖随机(SRANDMEMBER ) | 成员多时集合运算要注意成本;需要顺序/评分时改用 Sorted Set;避免滥用SMEMBERS 大集合全量拉取 |
Sorted Set (ZSet) | {A:1, B:2, C:3} | 排行榜、延时任务(score=时间戳)、优先级队列、滑动窗口统计(基于 score 时间) | 更新频繁+大量成员注意内存与重排成本;延时任务需轮询或使用定时拉取;分段大排行榜可局部缓存 |
GEO | {A:(120.3,30.5)} | 地理位置存储、附近的人/门店搜索、范围匹配 | GEO 基于 ZSet,精度有限;查询半径大性能下降;需持续更新位置可结合 TTL 或主动清理 |
BitMap | 0110110101110101011 | 布尔状态标记(签到、活跃/留存)、大规模用户行为统计、特征位图 | 适合稠密或可控范围的位;跨天/分段可用 key 分隔;统计基于位操作高效但不适合复杂查询 |
HyperLogLog | 0110110101110101011 (示意) | 大规模去重统计 UV(独立访客)、事件去重计数、快速近似基数估算 | 只提供近似结果(标准误差约 0.81%);不能列出元素;频繁合并会产生额外内存;不适合精确计费场景 |
(补充) Stream | (图片未列出) | 可靠消息队列、消费分组、事件溯源、日志管道 | 消费组需处理 pending;定期修剪XTRIM 控制长度;与 List 相比支持消费确认 |
(补充) TTL 机制 | 适用于任意键 | 缓存过期、限流窗口、临时锁、验证码 | 统一过期分布防止缓存雪崩;热点 key 续期防击穿;批量过期可加随机抖动 |
简要选择建议:
- 只存一个简单值或计数 -> String
- 需要对象字段读写且字段可独立更新 -> Hash
- 顺序、队列、时间追加 -> List / Stream(要 ACK/消费者组)
- 无序去重集合 + 集合运算 -> Set
- 排序、排名、按权重/时间范围扫描 -> Sorted Set
- 位置与附近查询 -> GEO
- 大规模布尔/打点统计 -> BitMap
- 大规模去重近似计数 -> HyperLogLog
- 可靠多消费者消息 -> Stream
4.Redis命令
4.1 通用命令
通用指令是部分数据类型的,都可以使用的指令,常见的有:
KEYS:查看符合模板的所有key,不建议在生产环境设备上使用
DEL:删除一个指定的key
EXISTS:判断key是否存在
EXPIRE:给一个key设置有效期,有效期到期时该key会被自动删除
TTL:查看一个KEY的剩余有效期
4.2 String命令
- SET
添加或修改一个 String 键值对
示例:
127.0.0.1:6379> SET msg "hello world"
OK
127.0.0.1:6379> GET msg
"hello world"
# 覆盖
127.0.0.1:6379> SET msg "hi"
OK
127.0.0.1:6379> GET msg
"hi"
常用附加参数:
SET key value EX 60
设定过期秒数SET key value PX 1500
毫秒过期SET key value NX
仅当 key 不存在SET key value XX
仅当 key 已存在SET key value EX 30 NX
原子创建 + 过期(常用于分布式锁)
示例(原子加锁):
127.0.0.1:6379> SET lock:order:123 "uuid-abc" EX 10 NX
OK # 返回 OK 表示获取到锁
- GET
根据 key 获取值
127.0.0.1:6379> GET not_exists
(nil)
127.0.0.1:6379> SET lang "Go"
OK
127.0.0.1:6379> GET lang
"Go"
- MSET
批量设置多个键值
127.0.0.1:6379> MSET a 1 b 2 c 3
OK
127.0.0.1:6379> GET b
"2"
注意:MSET 是原子操作,要么全部成功,要么都失败。
- MGET
批量获取多个 key 的值(顺序与传入一致)
127.0.0.1:6379> MGET a b z
1) "1"
2) "2"
3) (nil) # z 不存在
- INCR
让一个整型的 key 自增 1;不存在时按 0 先创建,再自增为 1
127.0.0.1:6379> DEL counter
(integer) 1
127.0.0.1:6379> INCR counter
(integer) 1 # 新建并得到 1
127.0.0.1:6379> INCR counter
(integer) 2
127.0.0.1:6379> GET counter
"2"
如果 value 不是整数形式会报错:
127.0.0.1:6379> SET counter "abc"
OK
127.0.0.1:6379> INCR counter
(error) ERR value is not an integer or out of range
- INCRBY
按指定步长自增(更正用法:INCRBY key increment
,不是 incrby num2
)
127.0.0.1:6379> SET score 10
OK
127.0.0.1:6379> INCRBY score 5
(integer) 15
127.0.0.1:6379> INCRBY score 20
(integer) 35
- INCRBYFLOAT
对浮点数字符串进行加法(注意存储形式仍为字符串)
127.0.0.1:6379> SET price 19.99
OK
127.0.0.1:6379> INCRBYFLOAT price 0.01
"20.00"
127.0.0.1:6379> INCRBYFLOAT price -5.5
"14.50"
可能出现二进制浮点表示的精度表现,例如 "14.499999999"
,需要客户端层做格式化。
- SETNX
仅当 key 不存在时设置,返回 1 表示成功,0 表示未设置
127.0.0.1:6379> DEL once
(integer) 1
127.0.0.1:6379> SETNX once "first"
(integer) 1
127.0.0.1:6379> SETNX once "second"
(integer) 0
127.0.0.1:6379> GET once
"first"
应用:初始化配置、简单分布式锁(需配合过期或用 SET NX EX)。
- SETEX
设置键并附带过期时间(秒)
127.0.0.1:6379> SETEX temp:code 30 "834512"
OK
127.0.0.1:6379> TTL temp:code
(integer) 29
127.0.0.1:6379> GET temp:code
"834512"
# 30 秒后:
127.0.0.1:6379> GET temp:code
(nil)
与 SET key value EX 30
功能等价;后者更灵活(还能加 NX/XX)。
综合小示例:生成一次性验证码并限制重复请求
# 1. 若验证码未存在则生成并设置 60 秒过期
127.0.0.1:6379> SET user:123:captcha "A7KD" NX EX 60
OK
# 2. 第二次在 60 秒内请求 -> 不再重建
127.0.0.1:6379> SET user:123:captcha "NEW1" NX EX 60
(nil)
127.0.0.1:6379> GET user:123:captcha
"A7KD"
常见设计注意
- 自增类统计最好使用独立 key,避免与其他含义混用。
- 分布式锁推荐:
SET lock:res "unique-uuid" NX PX 10000
,使用EVAL
脚本或GET
比对 +DEL
保证释放原子性。 - 浮点计算结果若用于金额,建议在应用层使用“以分为单位的整数”+
INCRBY
,避免浮点精度问题。 - 大批量
MSET
/MGET
比循环单条命令更高效;更大批量可考虑管道(pipeline)。