Redis 常见数据类型
一、基本全局命令详解与实操
1. KEYS 命令
功能:按模式匹配返回所有符合条件的键(生产环境慎用,可能导致阻塞)。
语法:
KEYS pattern
模式规则:
h?llo
:匹配hello
,hallo
(?
表示单个字符)。h*llo
:匹配hllo
,heeeello
(*
表示任意字符)。h[ae]llo
:匹配hello
,hallo
([]
内为可选字符)。h[^e]llo
:排除h
后第二个字符为e
的键(如hxllo
)。
示例:
127.0.0.1:6379> MSET user:1:name Alice user:2:name Bob
OK
127.0.0.1:6379> KEYS user:*:name
1) "user:1:name"
2) "user:2:name"
警告:
- 在数据量大的数据库中执行
KEYS *
可能导致服务卡顿,建议用SCAN
代替。
2. EXISTS 命令
功能:检查一个或多个键是否存在。
语法:
EXISTS key [key ...]
返回值:存在的键数量(0~N)。
示例:
127.0.0.1:6379> SET key1 "value"
OK
127.0.0.1:6379> EXISTS key1 key2
(integer) 1 # 只有 key1 存在
3. DEL 命令
功能:删除一个或多个键(无视数据类型)。
语法:
DEL key [key ...]
返回值:成功删除的键数。
示例:
127.0.0.1:6379> SET key1 "v1"
OK
127.0.0.1:6379> DEL key1 key2
(integer) 1 # key2 不存在,仅删除 key1
4. EXPIRE / TTL 命令
功能:设置键的过期时间(秒) / 查看剩余存活时间。
语法:
EXPIRE key seconds # 设置过期时间
TTL key # 查看剩余时间
返回值:
EXPIRE
:1(成功),0(键不存在或设置失败)。TTL
:剩余秒数,-1(无过期时间),-2(键不存在)。
示例:
127.0.0.1:6379> SET session:123 "data"
OK
127.0.0.1:6379> EXPIRE session:123 300 # 5分钟后过期
(integer) 1
127.0.0.1:6379> TTL session:123
(integer) 297 # 剩余297秒
扩展操作:
PEXPIRE
:以毫秒为单位设置过期时间。PERSIST
:移除键的过期时间,使其永久有效。
5. TYPE 命令
功能:返回键对应的数据类型。
语法:
TYPE key
返回值:string
, hash
, list
, set
, zset
, stream
, none
(键不存在)。
示例:
127.0.0.1:6379> LPUSH mylist "a" "b"
(integer) 2
127.0.0.1:6379> TYPE mylist
list
二、数据结构与内部编码深度解析
1. 查看内部编码
命令:OBJECT ENCODING key
示例:
127.0.0.1:6379> SET num 100
OK
127.0.0.1:6379> OBJECT ENCODING num
"int" # 存储为整数 127.0.0.1:6379> SET long_str "A very long string..."
OK
127.0.0.1:6379> OBJECT ENCODING long_str
"raw" # 存储为普通字符串
2. 各数据结构的内部编码规则
数据结构 | 默认编码 | 触发条件(可配置) |
---|---|---|
string | int (整数) | 值可表示为64位有符号整数。 |
embstr (短字符串) | 字符串长度 ≤ 39字节(Redis 5.0+)。 | |
raw (长字符串) | 字符串长度 > 39字节。 | |
hash | ziplist | 字段数 ≤ hash-max-ziplist-entries (默认512),且字段值长度 ≤ hash-max-ziplist-value (默认64字节)。 |
hashtable | 超出上述阈值时自动转换。 | |
list | ziplist | 元素数 ≤ list-max-ziplist-entries (默认512),且元素值长度 ≤ list-max-ziplist-value (默认64字节)。 |
linkedlist | 超出阈值时转换。 |
配置调整示例(修改 redis.conf
):
hash-max-ziplist-entries 1024 # 哈希字段数超过1024时转hashtable
list-max-ziplist-size -2 # 列表元素大小动态调整(默认值)
三、单线程架构原理与优化
1. 单线程模型核心机制
- 纯内存操作:数据全在内存中,无需磁盘I/O。
- I/O多路复用:
- 使用
epoll
(Linux)监听多个客户端连接。 - 事件驱动模型,将连接、读写事件转换为队列任务。
- 使用
- 无锁设计:所有命令串行执行,避免竞态条件。
2. 性能瓶颈与规避方法
- 长耗时命令:
- 避免使用
KEYS *
、FLUSHALL
、复杂 Lua 脚本。 - 使用
SCAN
代替KEYS
,分批次遍历键。
- 避免使用
- 大Key问题:
- 拆分大哈希/列表(如将
user:1000:friends
拆分为多个键)。 - 使用
UNLINK
(异步删除)代替DEL
。
- 拆分大哈希/列表(如将
3. 监控与调优命令
- 查看命令执行时间:
SLOWLOG GET 5 # 获取最近5条慢查询日志
- 内存分析:
MEMORY USAGE key # 查看键的内存占用(单位字节)
四、操作验证实验
实验1:观察字符串编码变化
- 设置不同长度的字符串:
127.0.0.1:6379> SET small "abc" OK 127.0.0.1:6379> OBJECT ENCODING small "embstr" 127.0.0.1:6379> SET large "This is a very long string..." # 长度超过39字节 OK 127.0.0.1:6379> OBJECT ENCODING large "raw"
实验2:哈希编码转换测试
- 创建小哈希:
127.0.0.1:6379> HMSET user:1000 name "Alice" age 30 OK 127.0.0.1:6379> OBJECT ENCODING user:1000 "ziplist"
- 添加大字段触发转换:
127.0.0.1:6379> HSET user:1000 bio "A very long biography..." # 字段值超过64字节 (integer) 1 127.0.0.1:6379> OBJECT ENCODING user:1000 "hashtable"
总结
- 全局命令:需注意
KEYS
的性能风险,优先使用SCAN
。 - 内部编码:通过
OBJECT ENCODING
和配置文件优化内存与性能。 - 单线程优化:避免长耗时操作,合理设计数据结构和命令。