Redis 字符串(String)完全攻略
String 是 Redis 最基础、最常用、最强大的数据类型
“万能型选手”:缓存、计数器、分布式锁、会话、位图、消息……全靠它!
一、String 核心特点
| 特性 | 说明 |
|---|---|
| 类型 | 二进制安全(可存图片、序列化对象) |
| 最大长度 | 512 MB |
| 原子操作 | INCR、DECR 等命令原子执行 |
| 内部编码 | int(整数)、embstr(≤44字节)、raw(>44字节) |
| 性能 | 所有操作 O(1) |
二、String 常用命令全表
| 命令 | 说明 | 示例 |
|---|---|---|
SET key value | 设置值 | SET name "张三" |
GET key | 获取值 | GET name |
MSET k1 v1 k2 v2 | 批量设置 | MSET a 1 b 2 |
MGET k1 k2 | 批量获取 | MGET a b |
INCR key | 自增 +1 | INCR views |
INCRBY key n | 自增 n | INCRBY score 10 |
DECR / DECRBY | 自减 | DECRBY likes 5 |
INCRBYFLOAT key 1.5 | 浮点数自增 | INCRBYFLOAT price 0.5 |
APPEND key "xx" | 追加字符串 | APPEND log "error\n" |
STRLEN key | 获取长度 | STRLEN name |
GETRANGE key 0 5 | 子串(含) | GETRANGE title 0 4 |
SETRANGE key 0 "xx" | 覆盖写入 | SETRANGE key 0 "hi" |
SET key value NX | 不存在才设置 | 分布式锁 |
SET key value XX | 存在才设置 | 更新 |
SET key value EX 60 | 设置 + 过期(秒) | 缓存 |
SET key value PX 30000 | 毫秒级过期 | 锁 |
GETSET key "new" | 设置并返回旧值 | 切换状态 |
DEL key | 删除 | DEL temp |
三、核心实战场景(带完整命令)
1. 缓存(最常见)
# 缓存文章内容,10分钟过期
SET cache:article:1001 "<html>..." EX 600
# 获取缓存
GET cache:article:1001
# 缓存未命中 → 查询 DB → 写入缓存
SET cache:article:1001 "{json}" EX 600
2. 分布式锁(SET NX PX) 经典!
# 获取锁(30秒自动释放)
SET lock:order:1001 "pid:1234" NX PX 30000
# 释放锁(Lua 脚本保证原子性)
EVAL "
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
" 1 lock:order:1001 "pid:1234"
Redisson 封装了更安全的锁机制
3. 计数器(文章阅读量、点赞)
INCR article:1001:views
GET article:1001:views → 10086
# 每日归零
EXPIRE article:1001:views 86400
4. 会话存储(Session)
# 存储用户信息(JSON 序列化)
SET sess:abc123 '{"uid":1001,"name":"张三"}' EX 1800
# 延长会话
EXPIRE sess:abc123 3600
5. 位图(Bitmap)—— 极致省内存!
1亿用户每天签到 → 仅 12MB 内存
# 用户1001在第0天签到(offset 从0开始)
SETBIT sign:2025:1001 0 1
SETBIT sign:2025:1001 2 1
# 查询是否签到
GETBIT sign:2025:1001 0 → 1
# 统计签到天数
BITCOUNT sign:2025:1001 → 2
# 统计某天所有用户签到数
BITCOUNT sign:2025:daily:0
6. 限流(滑动窗口)
# 每分钟最多10次请求
INCR rate:limit:user:1001:20251112
EXPIRE rate:limit:user:1001:20251112 60
GET rate:limit:user:1001:20251112 # >10 → 拒绝
7. 消息队列(轻量级)
# 生产者
RPUSH queue:msg "task1" "task2"
# 消费者
BLPOP queue:msg 0
更推荐
Stream,但 String + List 简单够用
四、String 进阶命令
| 命令 | 用途 | 示例 |
|---|---|---|
GETDEL key | 获取并删除(Redis 6.2+) | GETDEL temp:data |
LCS key1 key2 | 最长公共子序列(Redis 7.0+) | 文本相似度 |
SET key value KEEPTTL | 设置值保留原TTL | SET cache:1 "new" KEEPTTL |
五、性能与内存优化
| 优化点 | 建议 |
|---|---|
| 避免大 String | >10MB 拆分或用 Hash |
使用 embstr | ≤44字节字符串更省内存 |
| Pipeline 批量操作 | 减少 RTT |
| 压缩存储 | 存 JSON 前 gzip |
# Pipeline 示例(Python)
pipe = r.pipeline()
pipe.set('a', 1)
pipe.incr('counter')
pipe.execute()
六、内部编码解析(OBJECT ENCODING)
SET num 12345
OBJECT ENCODING num → "int"
SET short "hello redis"
OBJECT ENCODING short → "embstr"
SET long "x" * 50
OBJECT ENCODING long → "raw"
七、常见问题与解决方案
| 问题 | 原因 | 解决方案 |
|---|---|---|
| 内存暴涨 | 未设置 TTL | 所有缓存加 EX |
| 大 key 阻塞 | String > 10MB | 拆分或用 Hash |
| 计数不准 | 多实例操作 | 用 INCR 原子操作 |
| 锁被误释放 | 未校验 value | 用 Lua 脚本 |
八、一键速查表(贴墙必备)
# 基础
SET k v EX 3600 # 缓存
GET k
DEL k
# 计数
INCR views
INCRBY score 10
GET views
# 锁
SET lock:1 "ok" NX PX 30000
DEL lock:1
# 位图
SETBIT sign:1 0 1
GETBIT sign:1 0
BITCOUNT sign:1
# 批量
MSET a 1 b 2
MGET a b
九、客户端代码示例
Python (redis-py)
import redis
r = redis.Redis()
# 缓存
r.set('cache:user:1', '{"name":"张三"}', ex=3600)
# 计数
r.incr('article:1001:views')
# 分布式锁
if r.set('lock:pay', 'pid:123', nx=True, px=30000):
try:
# 业务逻辑
pass
finally:
r.delete('lock:pay')
十、String vs Hash 对比(什么时候用哪个?)
| 场景 | 推荐 |
|---|---|
| 简单值、JSON、序列化对象 | String |
| 结构化对象、频繁更新字段 | Hash |
| 内存敏感、字段多 | Hash 更省 |
需要 INCR 原子操作 | String |
完成!你已精通 Redis String!
# 一行命令体验所有核心功能
redis-cli <<EOF
SET cache:demo "hello" EX 10
INCR counter:demo
SETBIT bit:demo 0 1
GET cache:demo
GET counter:demo
GETBIT bit:demo 0
EOF
下一步推荐:
需要我送你:
- “高性能分布式锁 Lua 脚本”?
- “String + Lua 实现原子扣库存”?
- “百万级 UV 统计 Bitmap 方案”?
回复:锁 | 扣库存 | UV 即可!