Redis基础命令手册:从开箱到上手
前篇,小编简单介绍了什么是Redis,那么此时小编继续介绍关于Redis一些基础命令
通用命令
在 Redis 中,KEYS 是一个常用的通用命令(Generic Command),用于查找匹配给定模式的所有键。下面为你详细介绍 KEYS 命令及其相关指令和注意事项:
🔹 1. KEYS 命令语法
KEYS pattern功能:返回所有匹配指定模式(pattern)的 key。
时间复杂度:O(N),其中 N 是数据库中 key 的总数。不建议在生产环境中使用,因为它会阻塞 Redis 主线程。
模式匹配规则(通配符):
*:匹配任意数量的字符(包括零个)?:匹配单个任意字符[abc]:匹配括号内的任意一个字符(如 a、b 或 c)[^a]或[!a]:匹配不是 a 的任意字符(部分版本支持)
示例:
# 列出所有 key
KEYS *
# 列出以 "user:" 开头的 key
KEYS user:*
# 列出长度为5、以 "sess" 开头的 key(如 sess1, sessA)
KEYS sess?🔹 2. 替代方案:SCAN(推荐用于生产环境)
由于 KEYS 会阻塞服务器,Redis 提供了非阻塞的迭代命令 SCAN:
SCAN cursor [MATCH pattern] [COUNT count]cursor:游标,初始为 0,返回结果包含下一次的游标(0 表示结束)
MATCH:指定模式(类似 KEYS)
COUNT:提示每次返回多少元素(非精确值)
示例:
# 从游标 0 开始,匹配 user:*,每次返回约 10 个
SCAN 0 MATCH user:* COUNT 10
SCAN是增量式、非阻塞的,适合在大型数据库中安全使用。
🔹 3. 其他常用通用命令(与 keys 相关)
🔹4.通用命令exists
🔹 功能
检查一个或多个 key 是否存在于当前 Redis 数据库中。
如果 key 存在,返回
1如果 key 不存在,返回
0支持同时检查多个 key,此时返回存在的 key 的数量
🔹 语法
EXISTS key [key ...]可以传入 1 个或多个 key
返回值是整数(integer reply)
🔹 示例
# 设置一个 key
> SET name "Alice"
OK
# 检查单个 key 是否存在
> EXISTS name
(integer) 1
# 检查不存在的 key
> EXISTS age
(integer) 0
# 同时检查多个 key
> EXISTS name age city
(integer) 1 # 只有 "name" 存在,所以返回 1
# 再设置 age
> SET age "30"
OK
> EXISTS name age city
(integer) 2 # name 和 age 存在,city 不存在 → 返回 2🔹 使用场景
避免重复写入(虽然通常用
SETNX更合适)条件逻辑判断:在脚本或程序中先判断 key 是否存在再决定下一步操作
调试/排查:快速确认某个 key 是否在数据库中
🔹 注意事项
EXISTS不会修改 key 的 TTL(不像GET会触发 lazy expiration,但EXISTS也会触发过期 key 的清理)对于已过期但尚未被删除的 key,
EXISTS会返回0(Redis 会在访问时自动清理过期 key)时间复杂度:O(1)(每个 key),非常高效
🔹 在 Ubuntu 中使用示例(终端)
# 进入 Redis CLI
redis-cli
# 测试
127.0.0.1:6379> SET token abc123
OK
127.0.0.1:6379> EXISTS token
(integer) 1
127.0.0.1:6379> EXISTS invalid_key
(integer) 0🔹5.通用命令ttl和expire
🔹 1. EXPIRE 命令
功能
为一个已存在的 key 设置过期时间(单位:秒)。当时间到达后,Redis 会自动删除该 key。
注意:
EXPIRE只能对已经存在的 key生效。如果 key 不存在,返回0。
语法
EXPIRE key secondskey:要设置过期时间的键seconds:过期时间,单位为秒(整数)
返回值
1:成功设置了过期时间0:key 不存在,或设置失败
示例
# 设置一个 key
> SET temp_token "abc123"
OK
# 设置 10 秒后过期
> EXPIRE temp_token 10
(integer) 1
# 等待几秒后再查
> GET temp_token
"abc123" # 还没过期
# 10 秒后再次查询
> GET temp_token
(nil) # 已自动删除其他相关命令
PEXPIRE key milliseconds:以毫秒为单位设置过期时间EXPIREAT key timestamp:设置 key 在指定的 Unix 时间戳(秒) 过期PEXPIREAT key millisecond-timestamp:毫秒级时间戳过期
🔹 2. TTL 命令
功能
查看某个 key 的剩余生存时间(Time To Live),单位为秒。
语法
TTL key返回值
正整数:剩余秒数(例如
8表示还有 8 秒过期)-1:key 存在,但没有设置过期时间(永不过期)-2:key 不存在
示例
> SET session_id "xyz789"
OK
> TTL session_id
(integer) -1 # 没有设置过期时间
> EXPIRE session_id 60
(integer) 1
> TTL session_id
(integer) 57 # 假设刚过了 3 秒,还剩 57 秒相关命令
PTTL key:以毫秒为单位返回剩余时间(更精确)
对比总结
实际应用场景(Ubuntu + Redis CLI)
# 启动 Redis CLI
redis-cli
# 创建临时验证码
> SET verify_code_138 "9527"
OK
# 设置 5 分钟(300 秒)后过期
> EXPIRE verify_code_138 300
(integer) 1
# 查看剩余时间
> TTL verify_code_138
(integer) 295
# 如果想取消过期(变成永久 key)
> PERSIST verify_code_138
(integer) 1
> TTL verify_code_138
(integer) -1 # 现在永不过期了
PERSIST命令可以移除 key 的过期时间,使其变为持久化 key。
注意事项
EXPIRE对不存在的 key无效(返回 0)修改 key 的值(如
SET)会移除原有的过期时间(除非使用SET key value EX 60这种方式同时设置值和过期)Redis 的过期是“惰性删除 + 定期随机清理”机制,所以 key 可能在过期后短暂时间内仍存在(但
GET会返回nil)
String命令
当然可以!String(字符串)是 Redis 最基本、最常用的数据类型,也是其他高级数据结构的基础。下面为你系统介绍 String 类型的特点 和 常用命令,适合你在 Ubuntu 上通过 redis-cli 实践学习。
🔹 一、String 类型简介
基本特性
二进制安全:可以存储任意数据,如文本、JSON、图片序列化数据、甚至二进制内容(最大 512MB)。
动态字符串:底层使用 SDS(Simple Dynamic String) 实现,支持高效拼接、长度获取等操作。
自动编码优化:
整数值 → 用
int编码(节省内存)短字符串(≤44 字节)→ 用
embstr编码长字符串 → 用
raw编码(SDS)
所有 Redis 键(key)本身也是字符串!
🔹 二、String 常用命令分类详解
1. 基础读写
示例:
> SET name "Alice"
OK
> GET name
"Alice"
> MSET user:1:name Alice user:1:age 25
OK
> MGET user:1:name user:1:age
1) "Alice"
2) "25"2. 原子计数器(整数操作)
要求 value 是整数格式字符串(如
"100"),Redis 会自动识别为整数并支持数学运算。
示例:
> SET views 100
> INCR views
(integer) 101
> INCRBY views 50
(integer) 151
> INCRBYFLOAT price 1.99
"1.99"
> INCRBYFLOAT price 0.01
"2.00"注意:
INCR系列命令是原子操作,非常适合做高并发计数器(如文章阅读量、限流计数)。
3. 字符串操作
示例:
> SET msg "Hello"
> APPEND msg " World"
(integer) 11
> GET msg
"Hello World"
> STRLEN msg
(integer) 11
> GETRANGE msg 0 4
"Hello"
> GETRANGE msg -5 -1
"World"4. 安全设置(分布式锁常用)
分布式锁示例:
# 尝试获取锁(5秒自动释放)
> SET mylock "client_001" NX EX 5
OK # 成功获取
> SET mylock "client_002" NX EX 5
(nil) # 已被占用,获取失败5. 位操作(Bitmaps 基础)
虽然 Bitmaps 是高层抽象,但底层就是 String 的位操作:
用户签到示例:
# 第 5 天签到(offset 从 0 开始)
> SETBIT sign:202511 4 1
(integer) 0
# 查看第 5 天是否签到
> GETBIT sign:202511 4
(integer) 1
# 统计本月签到天数
> BITCOUNT sign:202511
(integer) 1🔹 三、String 的典型应用场景
🔹 四、注意事项
最大值限制:单个 String 最大 512 MB。
整数范围:
INCR支持 64 位有符号整数(-2⁶³ ~ 2⁶³-1)。浮点精度:
INCRBYFLOAT使用 IEEE 754 双精度,可能有精度误差。性能极高:所有 String 操作都是 O(1) 或 O(N)(N 为字符串长度),非常快。
动手建议(Ubuntu)
打开终端,运行:
redis-cli
# 尝试以下命令
SET counter 0
INCR counter
INCRBY counter 10
GET counter
SET message "Hello Redis!"
APPEND message " How are you?"
GETRANGE message 0 10Hash命令
🔹 一、hash 类型简介
结构:hash 是一个 键值对集合,类似于编程语言中的“字典”或“对象”。
存储形式:一个 key 对应多个 field-value 对。
user:1001
├── name → "alice"
├── age → "28"
└── city → "beijing"特点:
所有 field 和 value 都是字符串(二进制安全)。
适合存储结构化数据,如用户信息、商品详情等。
内存效率高:小 hash 会使用紧凑编码(如
listpack)。
注意:hash 的 value 不支持嵌套(不能直接存另一个 hash),但可以存 JSON 字符串。
🔹 二、hash 常见命令(全小写)
1. 写入与更新
示例:
> hset user:1001 name "alice" age "28"
(integer) 2 # 成功设置了 2 个新字段
> hsetnx user:1001 name "bob"
(integer) 0 # name 已存在,未修改
> hsetnx user:1001 email "alice@example.com"
(integer) 1 # 新字段,设置成功2. 读取数据
示例:
> hget user:1001 name
"alice"
> hmget user:1001 name age city
1) "alice"
2) "28"
3) (nil) # city 不存在
> hgetall user:1001
1) "name"
2) "alice"
3) "age"
4) "28"
5) "email"
6) "alice@example.com"3. 查询与检查
示例:
> hexists user:1001 age
(integer) 1
> hexists user:1001 salary
(integer) 0
> hlen user:1001
(integer) 34. 数值操作(类似 string 的 incr)
要求 value 是数字格式字符串(整数或浮点数)
示例:
> hset product:101 stock "100"
> hincrby product:101 stock 10
(integer) 110
> hincrbyfloat product:101 price 9.99
"9.99"
> hincrbyfloat product:101 price 0.01
"10.00"5. 删除操作
示例:
> hdel user:1001 email
(integer) 1 # 成功删除 1 个字段
> hdel user:1001 password
(integer) 0 # 字段不存在🔹 三、典型应用场景
优势:相比把整个对象存为一个 string,hash 允许部分更新和部分读取,更灵活高效。
🔹 四、注意事项
value 是字符串:即使存的是数字
"28",类型仍是 string,但hincrby能正确处理。避免大 hash:如果一个 hash 有上万个 field,
hgetall会阻塞 Redis,建议用hscan分页读取。内存优化:小 hash 使用
listpack编码(Redis 7+),非常省内存。原子性:每个 hash 命令都是原子的,但多个命令组合不是(需用 Lua 或事务)。
动手练习(Ubuntu 终端)
redis-cli
# 创建一个用户
hset user:2001 name "tom" age "22" city "shanghai"
# 查看
hget user:2001 name
hgetall user:2001
# 更新年龄
hincrby user:2001 age 1
# 检查字段
hexists user:2001 email
hlen user:2001
# 删除字段
hdel user:2001 citylist命令
当然可以!下面为你详细介绍 Redis 中的 list(列表)类型 及其常见命令(全部小写),适合你在 Ubuntu 上通过 redis-cli 学习和实践。
🔹 一、list 类型简介
结构:list 是一个有序的字符串元素列表,元素可以重复。
底层实现:Redis 3.2 起使用
quicklist(由多个压缩列表listpack组成的双向链表),兼顾内存效率和性能。插入方向:
左边(head / left):用
lpush、lpop右边(tail / right):用
rpush、rpop
索引规则:
从左到右:0, 1, 2, ...
从右到左:-1(最后一个), -2(倒数第二), ...
list 支持双向操作,非常适合实现队列(FIFO) 和 栈(LIFO)。
🔹 二、list 常见命令
1. 添加元素
示例:
> rpush tasks "task1" "task2"
(integer) 2
> lpush tasks "urgent_task"
(integer) 3
> lrange tasks 0 -1
1) "urgent_task"
2) "task1"
3) "task2"2. 弹出元素(删除并返回)
Redis 6.2+ 支持
count参数,可一次弹出多个。
示例:
> lpop tasks
"urgent_task"
> rpop tasks
"task2"3. 查看元素(不删除)
示例:
> lrange tasks 0 -1
1) "task1"
> lindex tasks 0
"task1"
> llen tasks
(integer) 14. 修改与插入
示例:
> lset tasks 0 "normal_task"
OK
> linsert tasks after "normal_task" "task3"
(integer) 2 # 当前列表长度
> lrange tasks 0 -1
1) "normal_task"
2) "task3"5. 删除元素
示例:
> rpush logs "info" "error" "info" "debug"
> lrem logs 1 "info" # 从左边删 1 个 "info"
(integer) 1
> lrange logs 0 -1
1) "error"
2) "info"
3) "debug"6. 阻塞式弹出(用于消息队列)
timeout = 0表示永久阻塞,直到有元素可弹出。
示例(在另一个终端模拟生产者):
# 消费者
> blpop job_queue 10
... 等待最多 10 秒 ...
# 生产者(另一窗口)
> rpush job_queue "job_001"🔹 三、典型应用场景
小技巧:用
ltrim保留最近 100 条:lpush timeline "new post" ltrim timeline 0 99 # 只保留 0~99 共 100 个元素
🔹 四、注意事项
元素是字符串:即使存数字
"123",也是字符串类型。索引越界:
lindex或lset访问不存在的索引会返回nil或报错。大列表慎用
lrange 0 -1:可能阻塞 Redis,建议分页(如lrange key 0 99)。阻塞命令不阻塞整个 Redis:只阻塞当前客户端连接,其他命令照常执行。
动手练习(Ubuntu 终端)
redis-cli
# 创建任务队列
rpush queue "taskA" "taskB"
lpush queue "priority_task"
# 查看
lrange queue 0 -1
llen queue
# 消费一个任务
lpop queue
# 模拟阻塞等待(可另开终端 push 新任务)
blpop queue 5set命令
当然可以!下面为你详细介绍 Redis 中的 set(集合)类型 及其常用命令(全部小写),适合你在 Ubuntu 上通过 redis-cli 学习和实践。
🔹 一、set 类型简介
结构:set 是一个无序、不重复的字符串元素集合。
特点:
元素不能重复(自动去重)
元素没有顺序(不能通过索引访问)
底层根据数据大小自动选择编码:
小整数集合 →
intset(非常省内存)大集合或含字符串 →
hashtable
时间复杂度:大多数操作是 O(1)(平均),非常适合做成员判断、交并差集等。
set 常用于标签系统、好友关系、抽奖去重等场景。
🔹 二、set 常用命令(全小写)
1. 添加与删除元素
示例:
> sadd tags "redis" "database" "cache" "redis"
(integer) 3 # "redis" 重复,只加了 3 个
> srem tags "cache"
(integer) 12. 查询操作
示例:
> smembers tags
1) "redis"
2) "database"
> scard tags
(integer) 2
> sismember tags "mysql"
(integer) 03. 随机操作(常用于抽奖)
示例:
> sadd users "alice" "bob" "charlie" "david"
# 抽 2 个幸运用户(不移除)
> srandmember users 2
1) "bob"
2) "alice"
# 弹出 1 个(移除)
> spop users
"david"注意:
srandmember和spop的“随机”在小集合中是近似均匀的。
4. 集合运算(多集合操作)
示例(用户标签):
> sadd user:1:tags "python" "redis" "linux"
> sadd user:2:tags "redis" "go" "docker"
# 共同技能
> sinter user:1:tags user:2:tags
1) "redis"
# 所有技能
> sunion user:1:tags user:2:tags
1) "python"
2) "redis"
3) "linux"
4) "go"
5) "docker"
# user1 有但 user2 没有的
> sdiff user:1:tags user:2:tags
1) "python"
2) "linux"5. 存储结果到新集合
示例:
> sinterstore common_tags user:1:tags user:2:tags
(integer) 1 # 结果存入 common_tags
> smembers common_tags
1) "redis"🔹 三、典型应用场景
🔹 四、注意事项
元素是字符串:即使存整数
"100",也是字符串类型(但小整数会用intset优化存储)。避免大集合的
smembers:建议用sscan分页遍历(类似keys *的安全替代)。集合运算性能:交集/并集的时间复杂度 ≈ O(N),N 是最小集合的大小。
内存友好:小整数集合使用
intset,非常紧凑。
动手练习(Ubuntu 终端)
redis-cli
# 创建两个集合
sadd fruits "apple" "banana" "orange"
sadd colors "red" "banana" "blue"
# 查看
smembers fruits
sismember fruits "apple"
# 集合运算
sinter fruits colors # "banana"
sunion fruits colors
# 随机抽取
srandmember fruits
spop colorszset
当然可以!下面为你详细介绍 Redis 中的 zset(sorted set,有序集合)类型 及其常用命令(全部小写),适合你在 Ubuntu 上通过 redis-cli 学习和实践。
🔹 一、zset 类型简介
结构:zset 是一个不重复、有序的字符串元素集合。
排序依据:每个成员(member)关联一个 score(分数),按 score 从小到大排序。
score 相同时,按 member 的字典序排序(Redis 7+ 行为)。
特点:
成员唯一,但 score 可以重复。
支持按分数范围或按排名范围快速查询。
底层使用
listpack(小集合) +skiplist(跳跃表) 实现,插入/查询/范围操作均为 O(log N)。
典型用途:排行榜、带权重的任务队列、延迟队列等。
你可以把 zset 理解为:“带分数的 set”,且自动按分数排序。
🔹 二、zset 常用命令(全小写)
1. 添加与更新成员
示例:
> zadd leaderboard 100 "alice" 95 "bob" 98 "charlie"
(integer) 3
# 更新 alice 的分数
> zadd leaderboard 105 "alice"
(integer) 0 # 成员已存在,仅更新(默认返回新增数量)
# 仅当不存在时添加
> zadd leaderboard nx 90 "david"
(integer) 12. 查询成员分数与排名
示例:
> zscore leaderboard "alice"
"105"
> zrank leaderboard "alice"
(integer) 0 # 分数最高?不对!注意:zrank 是从小到大排!
# 实际数据(按 score 升序):
# bob:95 → rank 0
# charlie:98 → rank 1
# david:90 → rank 0? 等等,我们重新看:
> zadd test 90 "david" 95 "bob" 105 "alice"
> zrange test 0 -1 withscores
1) "david" # 90
2) "bob" # 95
3) "alice" # 105
> zrank test "alice"
(integer) 2 # 正确:排名第 2(0 起始)
> zrevrank test "alice"
(integer) 0 # 倒数第 0 名(即第 1 名)3. 范围查询(核心功能!)
分数范围支持:
(100:表示 >100(不包含 100)
inf/-inf:正无穷 / 负无穷
示例:
# 获取前 3 名(降序,即高分在前)
> zrevrange leaderboard 0 2 withscores
1) "alice"
2) "105"
3) "charlie"
4) "98"
5) "bob"
6) "95"
# 获取分数在 95~100 之间的成员
> zrangebyscore leaderboard 95 100 withscores
1) "bob"
2) "95"
3) "charlie"
4) "98"
# 获取分数 >100 的前 1 名
> zrangebyscore leaderboard (100 +inf limit 0 1
1) "alice"4. 统计与删除
示例:
> zcard leaderboard
(integer) 4
> zcount leaderboard 90 100
(integer) 3
# 删除最后一名(最低分)
> zremrangebyrank leaderboard 0 0
# 删除分数 < 95 的成员
> zremrangebyscore leaderboard -inf (955. 分数增减(原子操作)
示例:
> zincrby leaderboard 5 "bob"
"100" # bob 原来是 95,现在 100🔹 三、典型应用场景
延迟队列示例:
# 10 秒后执行任务(当前时间戳 + 10) zadd delay_queue 1712345678 "task_001" # 消费:取出所有到期任务 zrangebyscore delay_queue -inf 1712345678 zremrangebyscore delay_queue -inf 1712345678
🔹 四、注意事项
score 是双精度浮点数:支持小数,但注意精度问题。
member 是字符串:最大 512MB,但通常很短。
范围查询高效:得益于 skiplist,即使百万级数据也能快速查 Top 100。
避免大范围
zrange 0 -1:建议分页(如zrange key 0 99)。Redis 7+ 行为:score 相同时,按 member 字典序排序(旧版未定义顺序)。
动手练习(Ubuntu 终端)
redis-cli
# 添加排行榜数据
zadd game_score 1500 "player1" 1200 "player2" 1800 "player3"
# 查看前三名(高分在前)
zrevrange game_score 0 2 withscores
# 给 player2 加 100 分
zincrby game_score 100 "player2"
# 查看 player2 的排名
zrevrank game_score "player2"
# 删除最低分玩家
zremrangebyrank game_score 0 0Stream、Geospatial、HyperLogLog、BitMap命令
🔹 一、Stream(流)—— 消息队列
简介
用于实现持久化、可回溯、支持消费者组的消息队列。
每条消息有唯一 ID(格式:
timestamp-sequence,如1678901234567-0)。支持多消费者组(类似 Kafka)。
常用命令
示例
# 添加消息
> xadd mystream * name "alice" event "login"
"1712345678901-0"
# 读取所有消息
> xread streams mystream 0-0
1) 1) "mystream"
2) 1) 1) "1712345678901-0"
2) 1) "name"
2) "alice"
3) "event"
4) "login"
# 创建消费者组
> xgroup create mystream mygroup $
# 消费者 alice 读取消息
> xreadgroup group mygroup alice streams mystream >适用场景:日志收集、事件溯源、微服务间异步通信。
🔹 二、Geospatial(地理位置)
简介
用于存储和查询地理位置信息(经纬度)。
底层使用 Sorted Set(zset) 实现,score 是 GeoHash 编码后的值。
常用命令
示例
# 添加城市位置(经度, 纬度)
> geoadd cities 116.40 39.90 "beijing" 121.47 31.23 "shanghai"
# 查看北京坐标
> geopos cities beijing
1) 1) "116.39999896287918091"
2) "39.90000126504897823"
# 计算北京到上海距离(公里)
> geodist cities beijing shanghai km
"1067.3965"
# 查找北京 1500km 内的城市
> georadius cities 116.40 39.90 1500 km withdist
1) 1) "beijing"
2) "0.0000"
2) 1) "shanghai"
2) "1067.3965"适用场景:附近的人、门店搜索、地理围栏。
🔹 三、HyperLogLog —— 基数统计(去重计数)
简介
用于估算集合的基数(不重复元素数量)。
极省内存:最多只需 12KB 内存,标准误差约 0.81%。
不存储原始数据,只存概率结构。
常用命令
示例
# 统计 UV(独立访客)
> pfadd uv:20250405 user1 user2 user3 user1
(integer) 1
> pfcount uv:20250405
(integer) 3
# 合并两天的 UV
> pfmerge uv:apr uv:20250404 uv:20250405
> pfcount uv:apr
(integer) 5 # 估算值适用场景:网站 UV 统计、大规模去重计数(不要求精确)。
🔹 四、Bitmap(位图)—— 位操作
简介
不是独立数据类型!本质是 String 类型的位操作。
每个 bit 代表一个状态(0/1),极其节省空间。
1 亿用户签到只需 ~12MB 内存。
🔧 常用命令
示例(用户签到)
# 用户 ID 为 1001,在第 5 天签到(offset = 4)
> setbit sign:202504 4 1
(integer) 0
# 检查是否签到
> getbit sign:202504 4
(integer) 1
# 统计本月签到天数
> bitcount sign:202504
(integer) 1
# 找出第一个未签到的天(bit=0)
> bitpos sign:202504 0
(integer) 0 # 第 0 天没签到适用场景:用户签到、活跃分析、布隆过滤器(需多个 bitmap)。
🔹 五、总结对比表
动手建议(Ubuntu)
redis-cli
# 尝试 Bitmap 签到
setbit sign:today 1001 1
getbit sign:today 1001
bitcount sign:today
# 尝试 HyperLogLog
pfadd uv:user "u1" "u2" "u1"
pfcount uv:user数据库管理命令
在 Redis 中,虽然它是一个 内存型 NoSQL 数据库,不提供传统关系型数据库(如 MySQL)那样复杂的用户权限、表结构等管理功能,但它仍提供了一套简洁而实用的 数据库管理命令,用于日常运维、监控、调试和维护。
🔹 一、数据库切换与清空
Redis 默认提供 16 个逻辑数据库(编号 0~15),可通过配置 databases 修改数量。
示例:
> select 1
OK
> dbsize
(integer) 0
> set temp "data"
> flushdb
OK
> dbsize
(integer) 0生产建议:
避免直接使用
flushall/flushdb(除非确认)可通过配置
rename-command FLUSHALL ""禁用危险命令
🔹 二、信息查看与监控
1. 数据库基本信息
示例:
> dbsize
(integer) 12345
> info memory
# Memory
used_memory:1234567
used_memory_human:1.18M
...
> info keyspace
# Keyspace
db0:keys=12345,expires=1000,avg_ttl=12345672. 键空间分析
🔹 三、持久化控制
Redis 支持 RDB 快照 和 AOF 日志两种持久化方式。
查看持久化状态:
> info persistence
...
rdb_last_bgsave_status:ok
aof_enabled:1
...生产环境永远用
bgsave,不要用save!
🔹 四、连接与客户端管理
示例:
> client setname worker-01
OK
> client list
id=123 addr=127.0.0.1:54321 ... name=worker-01 ...🔹 五、服务器控制
安全修改最大内存:
> config set maxmemory 2gb
> config get maxmemory
1) "maxmemory"
2) "2147483648"🔹 六、时间与延迟诊断
分析慢命令:
> slowlog get 5 # 查看最近 5 条慢日志
1) 1) (integer) 12345
2) (integer) 1712345678
3) (integer) 15000 # 耗时 15ms
4) 1) "keys"
2) "*"🔹 七、键的通用操作(跨类型)
这些命令适用于任何类型的 key:
安全删除大 key:
> unlink big_hash_key # 后台线程回收内存,不阻塞主线程🔹 八、生产环境最佳实践建议
禁用危险命令:在
redis.conf中重命名或禁用:
rename-command FLUSHALL ""
rename-command KEYS ""
rename-command CONFIG ""用
SCAN代替KEYS用
UNLINK代替DEL删除大 key定期监控
INFO和SLOWLOG避免在业务高峰期执行
BGREWRITEAOF或BGSAVE
总结:常用管理命令速查表
Key的过期策略以及定时器原理(浅谈)
非常好的问题!Redis 的 key 过期策略 和 定时器原理 是其高效内存管理的关键机制之一。下面我将用清晰、简洁的方式为你讲解:
🔹 一、Redis 中 key 的过期策略
Redis 并不会在 key 到期的那一刻立即删除它,而是采用 “惰性删除 + 定期删除” 相结合的混合策略,兼顾性能与内存回收效率。
1. 惰性删除(Lazy Expiration)
触发时机:每次访问一个 key 时(如
GET、EXISTS等),Redis 会先检查该 key 是否已过期。如果过期:立即删除,并返回空(如
nil)。优点:不浪费 CPU 资源去主动扫描。
缺点:如果一个过期 key 长时间不被访问,它会一直占用内存(“内存泄漏”风险)。
举例: 你设置了一个 key
temp:123,10 秒后过期。但之后没人读它,它可能在内存中“躺尸”很久。
2. 定期删除(Active Expiration / Periodic Eviction)
触发时机:Redis 后台每秒运行 10 次(即每 100 毫秒一次)的定时任务。
工作方式:
随机从设置了过期时间的 key 集合(expires dict)中抽取 20 个 key。
检查这些 key 是否过期。
删除其中所有已过期的 key。
如果过期 key 的比例超过 25%,则重复此过程(最多循环 25 次,防止长时间阻塞)。
目的:主动清理“惰性删除”漏掉的过期 key,控制内存占用。
注意:这是一个概率性、非精确的清理机制,不能保证所有过期 key 立即被删。
🔹 二、Redis 定时器原理(底层机制)
Redis 是单线程事件驱动模型(基于 Reactor 模式),使用 时间事件(time event) 来实现定时任务。
核心组件:时间事件(Time Event)
Redis 内部维护一个时间事件链表(在较新版本中优化为更高效结构)。
每次事件循环(
aeProcessEvents)时,会检查是否有时间事件到期。serverCron函数 是最重要的时间事件,默认每 100 毫秒执行一次(可通过hz配置调整频率,范围 1~500,默认 10)。
serverCron 做了什么?
执行定期删除逻辑(上面提到的过期 key 清理)
处理客户端超时
触发 AOF 重写或 RDB 快照(如果配置了)
更新统计信息(如 uptime、内存使用等)
hz越高 → 定期删除越频繁 → 内存回收更快,但 CPU 开销更大。
🔹 三、总结:过期策略 vs 定时器关系
两者互补:
惰性删除确保“用到时一定干净”
定期删除防止“垃圾堆积太多”
补充:如何查看/控制?
查看 key 剩余时间:
TTL key或PTTL key取消过期:
PERSIST key调整定时器频率(高级):修改
redis.conf中的hz参数(例如hz 20)
# redis.conf
hz 10 # 默认值,每秒 10 次定时任务不建议随意调高
hz,除非你明确需要更快的过期回收(如缓存场景),且能接受更高 CPU 使用率。
实际建议
开发/测试:可以用
KEYS *+TTL调试生产环境:
避免大量短期 key 集中过期(可能导致
serverCron负载突增)使用
EXPIRE时尽量分散过期时间(加随机偏移)监控
used_memory和expired_keys指标(通过INFO stats)
常见的数据类型和编码方式
在 Redis 中,数据类型(Data Types) 和 底层编码方式(Encodings) 是两个不同但紧密相关的概念:
数据类型:是 Redis 对外暴露的逻辑结构,比如字符串、列表、哈希等,用户通过命令操作这些类型。
编码方式:是 Redis 内部实际存储数据的底层数据结构,会根据数据大小、元素数量等自动选择最节省内存或最高效的编码。
🔹 一、Redis 常见数据类型(5 种基本 + 3 种扩展)
注意:Bitmaps、HyperLogLog、Geospatial(地理位置)等是基于 String 的高层抽象,不是独立的数据类型。
🔹 二、每种类型的底层编码方式(Encoding)
Redis 会根据数据特征自动切换编码,以平衡内存占用和性能。可通过 OBJECT ENCODING key 查看当前编码。
1. String(字符串)
编码方式:
int:当值是64 位有符号整数(如"123"),直接用整数存储(节省内存)embstr:当字符串长度 ≤ 44 字节(Redis 7+ 是 44,早期是 39),使用优化的只读字符串raw:长字符串(>44 字节),使用标准 SDS(Simple Dynamic String)
> SET num 100
> OBJECT ENCODING num
"int"
> SET short "hello"
> OBJECT ENCODING short
"embstr"
> SET long "a very long string over 44 bytes..."
> OBJECT ENCODING long
"raw"2. List(列表)
编码方式:
quicklist(Redis 3.2+ 默认):ziplist 的双向链表,兼顾内存和性能早期版本用
ziplist(小列表)或linkedlist(大列表)
quicklist本质上是多个 ziplist 节点组成的 linked list
为什么不用纯 ziplist?因为插入/删除中间元素时,ziplist 需要大量内存拷贝。
3. Hash(哈希)
编码方式:
ziplist:当满足以下两个条件时使用:哈希中字段数 ≤ 512(可配置
hash-max-ziplist-entries)每个 field/value 长度 ≤ 64 字节(可配置
hash-max-ziplist-value)
hashtable:超出上述限制时,转为真正的哈希表(dict)
> HSET user name "Alice" age "25"
> OBJECT ENCODING user
"ziplist" # 小对象用 ziplist
# 添加很多字段后
> OBJECT ENCODING user
"hashtable"4. Set(集合)
编码方式:
intset:当所有元素都是整数且数量 ≤ 512(set-max-intset-entries)hashtable:包含字符串 或 元素过多时
> SADD nums 1 2 3
> OBJECT ENCODING nums
"intset"
> SADD tags "redis" "db"
> OBJECT ENCODING tags
"hashtable"5. Sorted Set(有序集合)
编码方式:
ziplist:Redis 7 之前支持,现已弃用listpack:Redis 7+ 引入,替代 ziplist(更紧凑、无连锁更新问题)skiplist(跳跃表):默认编码,支持 O(log N) 插入/查询/范围操作
实际上,现代 Redis(≥7.0)中 ZSet 只用
listpack+skiplist组合:
listpack存储成员和分数(紧凑)
skiplist提供快速查找和范围扫描
可通过 zset-max-listpack-entries 控制何时从 listpack 切换到 skiplist(默认 128)。
🔹 三、如何查看和调试编码?
# 查看 key 的编码
OBJECT ENCODING mykey
# 查看 Redis 版本
redis-server --version
# 查看配置(如最大 ziplist 大小)
CONFIG GET hash-max-ziplist-entries🔹 四、为什么需要多种编码?
总结表
提示:Redis 7 开始逐步用
listpack替代ziplist,因为 listpack 更安全、内存更紧凑。
完!