Redis字符串
字符串(String)是Redis最基础的数据类型,可以存储任意形式的文本、数字或二进制数据。
结构概述
基本特点
Bash
- 最基本的数据类型
- 可存储文本、数字、二进制
- 最大长度512MB
- 所有key的类型都是字符串
存储内容
Bash
文本:用户名、配置信息、JSON数据
数字:计数器、分数、ID
二进制:图片、文件内容、序列化对象
内部编码
三种编码方式
Bash
int:整数编码,存储整数
embstr:嵌入式字符串,短字符串(≤44字节)
raw:原生字符串,长字符串(>44字节)
编码转换规则
Bash
存储整数 → int编码
存储字符串 ≤44字节 → embstr编码
存储字符串 >44字节 → raw编码
int转字符串 → raw编码(超过44字节)
查看编码
C
OBJECT ENCODING mykey
# 返回: "int", "embstr", "raw"
编码详解
int编码
Bash
当值是整数时使用
直接存储为long类型
节省内存空间
支持高效的数值操作
Bash
SET counter 100
OBJECT ENCODING counter
# 返回: "int"
embstr编码
Bash
短字符串(≤44字节)使用
SDS(Simple Dynamic String)结构
一次内存分配,紧凑存储
字符串和对象在同一块内存
Bash
SET name "Redis"
OBJECT ENCODING name
# 返回: "embstr"
raw编码
Bash
长字符串(>44字节)使用
SDS结构
两次内存分配
对象和字符串分开存储
Bash
SET longtext "This is a very long string that exceeds 44 bytes limit..."
OBJECT ENCODING longtext
# 返回: "raw"
SDS结构
SDS定义
Bash
struct sdshdr {
int len; // 已使用长度
int free; // 未使用长度(预留空间)
char buf[]; // 数据缓冲区
};
SDS优势
text
1. 获取长度O(1):len字段记录长度
2. 防止溢出:自动扩容
3. 二进制安全:可以存储任意数据
4. 兼容C函数:buf以\0结尾
5. 预留空间:减少内存分配次数
应用场景
1. 缓存
text
# 缓存用户信息
SET user:1000 '{"name":"Alice","age":25}'
GET user:1000
# 缓存页面
SET page:home "<html>...</html>"
2. 计数器
text
# 访问计数
INCR page:views
# 点赞数
INCR post:1000:likes
# 减少计数
DECR stock:product:count
3. 分布式锁
text
# 加锁(NX仅不存在时设置)
SET lock:resource "uuid" NX EX 30
# 释放锁(Lua脚本保证原子)
EVAL "if redis.call('GET', KEYS[1]) == ARGV[1] then return redis.call('DEL', KEYS[1]) else return 0 end" 1 lock:resource uuid
4. Session存储
text
# 存储会话
SET session:token123 "user_data" EX 1800
# 获取会话
GET session:token123
5. 限速
text
# 接口限速
SET rate:user:1000 0 EX 60
INCR rate:user:1000
GET rate:user:1000
# 超过阈值则拒绝
内存优化
编码优化
text
# 使用整数而非字符串
SET counter 100 # int编码,内存小
SET counter "100" # embstr编码,内存大
# 保持短字符串
# 避免不必要的长字符串
预分配优化
text
SDS预留空间策略:
- 长度<1MB:分配同样大小的预留空间
- 长度≥1MB:分配1MB预留空间
- 预留空间减少内存重分配次数
操作特点
O(1)操作
text
SET/GET:设置和获取
STRLEN:获取长度
APPEND:追加(实际复杂度与追加长度有关)
O(N)操作
text
GETRANGE:获取子串
SETRANGE:设置子串
# N为字符串长度
数值操作
text
INCR/DECR:自增自减
INCRBY/DECRBY:指定增减
INCRBYFLOAT:浮点增减
# 都是原子操作,O(1)
注意事项
内存限制
text
单个字符串最大512MB
大字符串占用内存
避免存储超大字符串
编码转换
text
SET counter 100 # int编码
APPEND counter "abc" # 变为raw编码
# 转换后内存增加
数值范围
text
INCR/DECR范围:
- 有符号64位整数
- 范围:-2^63 到 2^63-1
- 超出范围会报错
编码对比
| 编码 | 条件 | 内存效率 | 适用场景 |
|---|---|---|---|
| int | 整数值 | 最高 | 计数器、ID |
| embstr | ≤44字节字符串 | 高 | 短文本、状态 |
| raw | >44字节字符串 | 中 | 长文本、大数据 |
要点总结
- 字符串是Redis最基础类型,可存储文本、数字、二进制
- 最大长度512MB,所有key都是字符串类型
- 三种编码:int(整数)、embstr(≤44字节)、raw(>44字节)
- SDS结构优势:O(1)获取长度、自动扩容、二进制安全
- 应用场景:缓存、计数器、分布式锁、Session、限速
- 使用整数而非字符串数字可节省内存
- 数值操作(INCR/DECR)是原子操作
- 避免存储超大字符串,控制内存占用
📝 发现内容有误?点击此处直接编辑