Redis 数据类型和常用命令
一、Redis 概述
1.1 什么是 Redis
Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储数据库。它支持多种数据结构,常用作缓存、消息队列、会话存储等。
1.2 Redis 核心特性
|
特性 |
说明 |
|---|---|
|
内存存储 |
数据存放在内存中,读写速度极快(微秒级) |
|
持久化 |
支持 RDB 快照和 AOF 日志两种持久化方式 |
|
丰富的数据类型 |
String、Hash、List、Set、Sorted Set 等 |
|
原子操作 |
所有操作都是原子的 |
|
单线程模型 |
6.0 前网络 I/O 与命令执行均为单线程;6.0+ 网络 I/O 多线程 |
|
高可用 |
支持主从复制、哨兵模式、集群模式 |
|
过期策略 |
支持 TTL 和多种淘汰策略 |
|
发布订阅 |
内置 Pub/Sub 消息系统 |
1.3 连接 Redis
# 本地连接
redis-cli
# 远程连接
redis-cli -h 127.0.0.1 -p 6379 -a yourpassword
# 测试连接
PING
# 返回 PONG 表示连接成功
二、String(字符串)
2.1 概述
- 描述:最基础的数据类型,二进制安全,最大可存储 512MB
- 适用场景:缓存对象、计数器、分布式锁、Session 存储
2.2 常用命令
SET / GET — 设置和获取值
# 设置值
SET key value
# 获取值
GET key
# 示例
SET name "张三"
GET name # 返回 "张三"
SETEX — 设置值并指定过期时间(秒)
# 设置 key 在 60 秒后过期
SETEX token 60 "abc123xyz"
TTL token # 查看剩余存活时间(秒)
SETNX — 仅当 key 不存在时设置(分布式锁基础)
# 如果 lock:order 不存在则设置
SETNX lock:order "locked"
# 返回 1 表示设置成功,0 表示 key 已存在
# 现代版本更推荐使用 SET key value NX EX seconds(原子操作)
SET lock:order "locked" NX EX 30
MSET / MGET — 批量操作
# 批量设置
MSET user:1:name "张三" user:1:age "25" user:1:city "北京"
# 批量获取
MGET user:1:name user:1:age user:1:city
# 返回: ["张三", "25", "北京"]
INCR / DECR — 原子增减(计数器)
# 自增 1
INCR page:view:count
INCR page:view:count
GET page:view:count # "2"
# 自增指定值
INCRBY stock:item001 100
# 自减
DECR stock:item001
DECRBY stock:item001 50
# 浮点数自增
INCRBYFLOAT price 0.5
GETSET — 设置新值并返回旧值
SET counter "10"
GETSET counter "20" # 返回 "10"
GET counter # "20"
APPEND / STRLEN — 追加和长度
SET msg "Hello"
APPEND msg " World" # 返回 11(新字符串长度)
GET msg # "Hello World"
STRLEN msg # 返回 11
GETRANGE / SETRANGE — 子串操作
SET greeting "Hello World"
GETRANGE greeting 0 4 # "Hello"
GETRANGE greeting -5 -1 # "World"(负数从末尾开始)
SETRANGE greeting 6 "Redis" # 从第 6 位开始替换
GET greeting # "Hello Redis"
2.3 应用场景
# 缓存 JSON 对象
SET user:1001 '{"name":"张三","age":25}'
EXPIRE user:1001 3600
# 文章阅读计数
INCR article:123:views
# 限流计数器
INCR rate:user:1001
EXPIRE rate:user:1001 60
# 分布式锁
SET lock:resource "unique_id" NX PX 30000
三、Hash(哈希)
3.1 概述
- 描述:String 类型的 field-value 映射表,类似 Java 的 HashMap
- 适用场景:存储对象、用户属性、配置信息
3.2 常用命令
# 设置单个字段
HSET user:1001 name "张三"
HSET user:1001 age 25
# 获取单个字段
HGET user:1001 name
# 批量设置多个字段
HMSET user:1001 name "张三" age 25 city "北京"
# 获取所有字段和值
HGETALL user:1001
# 批量获取指定字段
HMGET user:1001 name age city
# 获取所有键 / 所有值
HKEYS user:1001
HVALS user:1001
# 删除字段
HDEL user:1001 email
# 判断字段是否存在
HEXISTS user:1001 name
# 字段值增减
HINCRBY user:1001 age 1
HINCRBYFLOAT product:1001 price 0.5
# 获取字段数量
HLEN user:1001
# 渐进式遍历(生产环境推荐替代 HGETALL)
HSCAN user:1001 0 COUNT 100
注意事项:HGETALL 在大 Hash 上会阻塞,生产环境优先用 HSCAN 分批获取。
四、List(列表)
4.1 概述
- 描述:双向链表,支持从两端操作,元素可重复,有序
- 适用场景:消息队列、最新消息列表、时间线
4.2 常用命令
# 从左侧(头部)推入
LPUSH tasks "任务3" "任务2" "任务1"
# 从右侧(尾部)推入
RPUSH tasks "任务4"
# 左/右弹出
LPOP tasks
RPOP tasks
# 获取所有元素
LRANGE tasks 0 -1
# 获取列表长度
LLEN tasks
# 按索引获取元素
LINDEX tasks 0
# 删除指定元素
LREM tasks 0 "任务2"
# 修剪列表(只保留索引 0-4)
LTRIM tasks 0 4
# 阻塞弹出(消息队列核心)
BLPOP tasks 10
BRPOP tasks 0
# 可靠队列模式(原子操作)
RPOPLPUSH tasks tasks:backup
4.3 应用场景
# 消息队列
# 生产者
RPUSH queue:order "order:12345"
# 消费者
BRPOP queue:order 0
# 最新消息列表(保留最近 100 条)
LPUSH news:latest "新消息内容"
LTRIM news:latest 0 99
五、Set(集合)
5.1 概述
- 描述:无序、元素唯一、基于哈希表实现
- 适用场景:标签系统、共同好友、去重统计、抽奖
5.2 常用命令
# 添加/删除成员
SADD tags:article:1 "redis" "database" "nosql"
SREM tags:article:1 "nosql"
# 获取所有成员
SMEMBERS tags:article:1
# 判断是否为成员
SISMEMBER tags:article:1 "redis"
# 获取集合大小
SCARD tags:article:1
# 随机获取成员(不删除)
SRANDMEMBER tags:article:1 3
# 随机弹出成员(会删除)
SPOP tags:article:1 3
# 移动成员到另一个集合
SMOVE tags:article:1 tags:article:2 "redis"
5.3 集合运算
# 交集(共同元素)
SINTER set1 set2
# 并集(全部元素)
SUNION set1 set2
# 差集(set1 有但 set2 没有的)
SDIFF set1 set2
# 交集并存储到新集合
SINTERSTORE common_tags set1 set2
# 并集并存储
SUNIONSTORE all_tags set1 set2
5.4 应用场景
# 共同兴趣
SINTER user:1001:interests user:1002:interests
# 抽奖系统
SPOP lottery:2024 1
# 点赞用户去重
SADD post:123:likes user:1001
SCARD post:123:likes # 点赞数
SISMEMBER post:123:likes user:1001 # 是否已点赞
六、Sorted Set(有序集合)
6.1 概述
- 描述:每个成员关联一个 score(分数),按 score 排序,成员唯一
- 适用场景:排行榜、优先级队列、延迟队列
6.2 常用命令
# 添加成员
ZADD leaderboard 100 "张三" 95 "李四" 88 "王五"
# NX — 仅新增 / XX — 仅更新
ZADD leaderboard NX 100 "赵六"
# INCR — 增加分数
ZADD leaderboard INCR 5 "张三"
# 获取前 3 名
ZRANGE leaderboard 0 2 WITHSCORES
# 降序获取(分数从大到小)
ZREVRANGE leaderboard 0 2 WITHSCORES
# 按分数范围获取
ZRANGEBYSCORE leaderboard 80 100 WITHSCORES
# 获取排名
ZRANK leaderboard "张三" # 升序排名
ZREVRANK leaderboard "张三" # 降序排名
# 获取分数
ZSCORE leaderboard "张三"
# 统计分数范围内数量
ZCOUNT leaderboard 80 100
# 删除成员
ZREM leaderboard "王五"
ZREMRANGEBYRANK leaderboard 0 2
ZREMRANGEBYSCORE leaderboard 0 60
# 增加/减少分数
ZINCRBY leaderboard 10 "张三"
ZINCRBY leaderboard -5 "张三"
6.3 应用场景
# 游戏排行榜
ZREVRANGE game:rank 0 9 WITHSCORES
# 延迟队列(score = 处理时间戳)
ZADD delay:queue 1713600000 "order:123"
ZRANGEBYSCORE delay:queue 0 $(date +%s) LIMIT 0 10
# 搜索建议
ZADD suggest:keywords 100 "redis" 80 "react" 60 "ruby"
ZREVRANGEBYSCORE suggest:keywords +inf 0 LIMIT 0 5
七、其他数据类型
7.1 Bitmap(位图)
# 用户签到
SETBIT user:1001:sign:2024 0 1
GETBIT user:1001:sign:2024 0
BITCOUNT user:1001:sign:2024
# 连续签到天数
BITPOS user:1001:sign:2024 0
7.2 HyperLogLog(基数统计)
# UV 统计(去重估算,误差约 0.81%)
PFADD uv:page:home user1 user2 user3
PFCOUNT uv:page:home
# 合并多日 UV
PFMERGE uv:total uv:20240101 uv:20240102
PFCOUNT uv:total
7.3 GEO(地理位置)
GEOADD cities 116.404 39.915 "北京"
GEOADD cities 121.473 31.230 "上海"
# 计算距离
GEODIST cities "北京" "上海" km
# 获取附近
GEORADIUSBYMEMBER cities "北京" 500 km
# 按经纬度获取附近
GEORADIUS cities 116.404 39.915 500 km
7.4 Stream(流,Redis 5.0+)
# 添加消息
XADD mystream * sensor-id 1234 temperature 36.5
# 读取消息
XREAD COUNT 2 STREAMS mystream 0
# 创建消费者组
XGROUP CREATE mystream mygroup 0
# 消费者组读取
XREADGROUP GROUP mygroup consumer1 COUNT 1 STREAMS mystream >
# 确认消息已处理
XACK mystream mygroup 消息ID
八、通用命令
8.1 Key 管理
# 查找匹配的 key(生产环境慎用 KEYS)
SCAN 0 MATCH user:* COUNT 100
# 判断 key 是否存在
EXISTS mykey
# 查看 key 类型
TYPE mykey
# 删除 key
DEL key1 key2
UNLINK key1 key2 # 异步删除(推荐)
# 设置过期时间
EXPIRE mykey 3600
EXPIREAT mykey 1713600000
# 查看过期时间
TTL mykey
PTTL mykey
# 移除过期时间
PERSIST mykey
# 重命名
RENAME oldkey newkey
RENAMENX oldkey newkey
8.2 服务器管理
# 切换数据库(0-15)
SELECT 1
# 查看 key 数量
DBSIZE
# 清空当前数据库
FLUSHDB
# 查看服务器信息
INFO
INFO memory
INFO replication
# 慢查询日志
SLOWLOG GET 10
SLOWLOG LEN
SLOWLOG RESET
# 客户端管理
CLIENT LIST
九、Key 命名规范与设计模式
9.1 命名规范建议
# 使用冒号分隔(约定俗成)
user:1001:profile
user:1001:settings
article:123:views
# Hash Tag(集群模式确保同 slot)
{user:1001}:profile
{user:1001}:settings
9.2 常见设计模式
# 缓存模式:Cache Aside(旁路缓存)
# 读:先查缓存 → 未命中则查 DB → 回写缓存
# 写:先更新 DB → 删除缓存
# 计数器模式
INCR article:123:views
HINCRBY user:1001:stats login_days 1
# 分布式锁
SET lock:order:123 unique_id NX PX 30000
# 释放需用 Lua 脚本保障原子性
# 限流(滑动窗口)
# 使用 Sorted Set 实现
十、性能优化要点
|
优化点 |
建议 |
|---|---|
|
避免 KEYS * |
线上使用 SCAN 替代 |
|
大 key 拆分 |
Hash 控制在 5000 个 field 以内 |
|
批量操作 |
使用 MGET/MSET、Pipeline 减少 RTT |
|
过期时间 |
设置随机偏移量,避免集中过期 |
|
连接池 |
合理配置连接池大小 |
|
禁用危险命令 |
线上 rename 或禁用 FLUSHALL、KEYS |
|
Pipeline |
批量命令减少网络往返 |
|
Lua 脚本 |
需要原子性时使用 Lua |
十一、常用资源
- Redis 官方文档:https://redis.io/docs/latest/
- Redis 命令参考:https://redis.io/commands/
- 中文文档:http://redis.cn
- 可视化工具:RedisInsight、Another Redis Desktop Manager