本文是 Redis 的快速入门指南,将带你从零开始学习 Redis 的安装部署、基本操作和实际应用。无论你是初学者还是有一定经验的开发者,都能从中获得实用的知识。
一、Redis 简介
1.1 什么是 Redis?
Redis(Remote Dictionary Server)是一个开源的、基于内存的键值存储系统,通常用作数据库、缓存和消息中间件。
核心特点:
- 🚀 高性能 - 读写速度可达 10 万 + QPS
- 💾 持久化 - 支持 RDB 和 AOF 两种持久化方式
- 🔧 丰富数据类型 - String、List、Hash、Set、ZSet 等
- ⚡ 原子操作 - 所有操作都是原子性的
- 📦 发布订阅 - 内置 Pub/Sub 功能
- 🔐 事务支持 - 支持简单事务
1.2 适用场景
| 场景 | 说明 | 典型应用 |
|---|---|---|
| 缓存 | 加速数据访问 | 用户信息、商品详情 |
| 会话存储 | 分布式 Session | 用户登录状态 |
| 消息队列 | 异步任务处理 | 订单处理、邮件发送 |
| 排行榜 | 实时排序 | 游戏排名、热搜榜 |
| 计数器 | 高并发计数 | 文章阅读量、点赞数 |
| 分布式锁 | 并发控制 | 秒杀、库存扣减 |
二、安装与部署
2.1 Docker 部署(推荐)
单机部署:
# 拉取最新镜像
docker pull redis:7.2
# 启动 Redis 容器
docker run -d \
--name redis \
-p 6379:6379 \
-v /data/redis/data:/data \
-v /data/redis/redis.conf:/etc/redis/redis.conf \
redis:7.2 redis-server /etc/redis/redis.conf --appendonly yes
配置文件(redis.conf):
# 基础配置
port 6379
bind 0.0.0.0
protected-mode yes
daemonize no
# 持久化配置
appendonly yes
appendfsync everysec
dir /data
# 内存配置
maxmemory 2gb
maxmemory-policy allkeys-lru
# 安全配置
requirepass your-strong-password
rename-command FLUSHALL ""
rename-command FLUSHDB ""
rename-command CONFIG ""
# 日志配置
loglevel notice
logfile /var/log/redis/redis.log
Docker Compose 部署:
version: '3.8'
services:
redis:
image: redis:7.2
container_name: redis
ports:
- "6379:6379"
volumes:
- ./data:/data
- ./redis.conf:/etc/redis/redis.conf
command: redis-server /etc/redis/redis.conf
restart: unless-stopped
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
redis-commander:
image: rediscommander/redis-commander:latest
container_name: redis-commander
environment:
- REDIS_HOSTS=local:redis:6379:0:your-password
ports:
- "8081:8081"
depends_on:
- redis
2.2 Linux 源码编译安装
# 下载安装包
wget https://download.redis.io/releases/redis-7.2.4.tar.gz
tar xzf redis-7.2.4.tar.gz
cd redis-7.2.4
# 编译
make
make test
# 安装
sudo make install
# 验证安装
redis-server --version
redis-cli --version
启动服务:
# 后台启动
redis-server /etc/redis/redis.conf --daemonize yes
# 前台启动(调试用)
redis-server --port 6379
# 设置开机自启(systemd)
sudo vim /etc/systemd/system/redis.service
Systemd 服务配置:
[Unit]
Description=Redis In-Memory Data Store
After=network.target
[Service]
User=redis
Group=redis
ExecStart=/usr/local/bin/redis-server /etc/redis/redis.conf
ExecStop=/usr/local/bin/redis-cli shutdown
Restart=always
[Install]
WantedBy=multi-user.target
# 启动服务
sudo systemctl start redis
sudo systemctl enable redis
# 查看状态
sudo systemctl status redis
2.3 Windows 部署
Redis 官方不支持 Windows,但可以通过以下方式运行:
方式一:WSL2(推荐)
# 在 WSL2 中安装
sudo apt update
sudo apt install redis-server
# 启动
sudo service redis-server start
方式二:Docker Desktop
# 使用 Docker Desktop 运行
docker run -d -p 6379:6379 redis:7.2
方式三:Microsoft Archive(不推荐)
⚠️ 已停止维护,仅用于学习
三、基本操作
3.1 连接 Redis
# 本地连接
redis-cli
# 远程连接
redis-cli -h 192.168.1.100 -p 6379
# 带密码连接
redis-cli -h localhost -p 6379 -a your-password
# 执行单条命令
redis-cli INCR counter
redis-cli GET user:1001
# 交互模式
redis-cli
127.0.0.1:6379> PING
PONG
3.2 通用命令
# 查看键
KEYS pattern # 查看所有匹配的键(生产环境慎用)
SCAN 0 MATCH pattern COUNT 10 # 安全遍历键
# 检查键
EXISTS key # 判断键是否存在
TYPE key # 查看键的类型
TTL key # 查看剩余生存时间
# 删除键
DEL key [key ...] # 删除键
UNLINK key [key ...] # 异步删除(推荐)
EXPIRE key seconds # 设置过期时间
PEXPIRE key milliseconds # 设置毫秒级过期时间
# 数据库操作
SELECT db_index # 切换数据库
DBSIZE # 查看键数量
FLUSHDB # 清空当前数据库
FLUSHALL # 清空所有数据库
# 其他
RANDOMKEY # 随机返回一个键
MOVE key db # 将键移到另一个数据库
RENAME key newkey # 重命名键
3.3 String 类型操作
# 基本操作
SET key value # 设置值
GET key # 获取值
MSET key1 value1 key2 value2 # 批量设置
MGET key1 key2 # 批量获取
# 带过期时间
SETEX key seconds value # 设置值和过期时间
SET key value EX seconds # 同上(Redis 2.6.12+)
SET key value NX EX seconds # 不存在时设置(分布式锁)
# 数值操作
INCR key # 自增 1
INCRBY key increment # 自增指定值
DECR key # 自减 1
DECRBY key decrement # 自减指定值
# 字符串操作
APPEND key value # 追加字符串
STRLEN key # 获取字符串长度
GETRANGE key start end # 获取子串
SETRANGE key offset value # 覆盖部分字符串
# 位操作(用于布隆过滤器、计数器)
SETBIT key offset value # 设置位值
GETBIT key offset # 获取位值
BITCOUNT key [start end] # 统计 1 的数量
实战示例:
# 1. 缓存用户信息
SET user:1001 '{"name":"张三","age":25}' EX 300
# 2. 文章阅读量
INCR article:888:views
# 3. 分布式锁
SET lock:order:12345 "worker-1" NX EX 10
# 4. 验证码存储
SET sms:code:13800138000 "123456" EX 300
# 5. 限流计数
INCR rate:api:user:1001
EXPIRE rate:api:user:1001 60
3.4 Hash 类型操作
# 基本操作
HSET key field value # 设置字段值
HGET key field # 获取字段值
HMSET key field1 value1 ... # 批量设置(3.0+ 废弃,用 HSET)
HMGET key field1 field2 # 批量获取
HGETALL key # 获取所有字段
# 字段操作
HDEL key field [field ...] # 删除字段
HEXISTS key field # 判断字段是否存在
HLEN key # 获取字段数量
HKEYS key # 获取所有字段名
HVALS key # 获取所有字段值
# 数值操作
HINCRBY key field increment # 字段自增
HINCRBYFLOAT key field incr # 字段自增(浮点数)
实战示例:
# 1. 存储用户信息
HSET user:1001 name "张三" age 25 email "zhangsan@example.com"
HGET user:1001 name
HMGET user:1001 name age email
# 2. 购物车
HSET cart:user:1001 product:888 2 product:999 1
HINCRBY cart:user:1001 product:888 1 # 增加数量
# 3. 商品详情
HMSET product:888 title "iPhone 15" price 5999 stock 100
HGETALL product:888
3.5 List 类型操作
# 左侧操作
LPUSH key value [value ...] # 左侧插入
LPOP key # 左侧弹出
LINDEX key index # 获取指定位置元素
LLEN key # 获取列表长度
# 右侧操作
RPUSH key value [value ...] # 右侧插入
RPOP key # 右侧弹出
# 阻塞操作(消息队列)
BLPOP key [key ...] timeout # 阻塞左侧弹出
BRPOP key [key ...] timeout # 阻塞右侧弹出
# 范围操作
LRANGE key start stop # 获取范围元素
LTRIM key start stop # 修剪列表
LREM key count value # 删除元素
LSET key index value # 设置指定位置的值
实战示例:
# 1. 消息队列
LPUSH queue:tasks "task-1" "task-2" "task-3"
BRPOP queue:tasks 5 # 阻塞 5 秒等待任务
# 2. 最新文章列表
LPUSH articles:latest id1 id2 id3
LTRIM articles:latest 0 99 # 保留最新 100 篇
# 3. 用户动态时间线
LPUSH timeline:user:1001 "action:1" "action:2"
LRANGE timeline:user:1001 0 49 # 获取最近 50 条动态
3.6 Set 类型操作
# 基本操作
SADD key member [member ...] # 添加成员
SREM key member [member ...] # 删除成员
SISMEMBER key member # 判断成员是否存在
SMEMBERS key # 获取所有成员
SCARD key # 获取成员数量
# 集合运算
SINTER key [key ...] # 交集
SUNION key [key ...] # 并集
SDIFF key [key ...] # 差集
# 随机操作
SPOP key [count] # 随机弹出
SRANDMEMBER key [count] # 随机获取
实战示例:
# 1. 用户标签
SADD user:1001:tags "java" "python" "redis"
SISMEMBER user:1001:tags "java"
# 2. 共同好友
SINTER friends:user:1001 friends:user:1002
# 3. 抽奖
SADD lottery:participants "user1" "user2" "user3"
SPOP lottery:participants 3 # 抽取 3 名幸运用户
# 4. 在线用户
SADD online:users "user1" "user2"
SCARD online:users # 在线人数
3.7 ZSet 类型操作
# 基本操作
ZADD key [NX|XX] [GT|LT] score member # 添加成员
ZREM key member [member ...] # 删除成员
ZSCORE key member # 获取分数
ZCARD key # 获取成员数量
# 排名查询
ZREVRANK key member # 倒序排名
ZRANK key member # 正序排名
ZRANGE key start stop [WITHSCORES] # 正序范围
ZREVRANGE key start stop [WITHSCORES] # 倒序范围
# 范围查询(按分数)
ZRANGEBYSCORE key min max [WITHSCORES] # 按分数范围
ZREVRANGEBYSCORE key max min # 倒序按分数
# 计数
ZCOUNT key min max # 统计分数范围内的数量
ZINCRBY key increment member # 增加分数
实战示例:
# 1. 游戏排行榜
ZADD leaderboard:game1 1000 "player1"
ZADD leaderboard:game1 950 "player2"
ZREVRANGE leaderboard:game1 0 9 WITHSCORES # Top 10
# 2. 热搜榜
ZINCRBY hot:search 1 "Redis 教程"
ZINCRBY hot:search 1 "Java 并发"
ZREVRANGE hot:search 0 49 WITHSCORES # 热搜前 50
# 3. 延迟队列(分数为执行时间戳)
ZADD queue:delay 1712649600 "task-1"
ZRANGEBYSCORE queue:delay 0 1712649600 # 获取到期任务
四、客户端集成
4.1 Python(redis-py)
# 安装
pip install redis
# 基本使用
import redis
import json
# 连接
r = redis.Redis(
host='localhost',
port=6379,
db=0,
password='your-password',
decode_responses=True,
socket_timeout=5,
socket_connect_timeout=5
)
# 连接池
pool = redis.ConnectionPool(
host='localhost',
port=6379,
max_connections=50
)
r = redis.Redis(connection_pool=pool)
# String 操作
r.set('user:1001', json.dumps({'name': '张三', 'age': 25}), ex=300)
user = json.loads(r.get('user:1001'))
# Hash 操作
r.hset('user:1002', mapping={'name': '李四', 'age': '28'})
name = r.hget('user:1002', 'name')
# List 操作(消息队列)
r.lpush('queue:tasks', 'task-1', 'task-2')
task = r.brpop('queue:tasks', timeout=5)
# Pipeline(批量操作)
pipe = r.pipeline()
for i in range(100):
pipe.set(f'key:{i}', i)
pipe.execute()
# 事务
with r.pipeline() as pipe:
pipe.multi()
pipe.set('key1', 'value1')
pipe.set('key2', 'value2')
pipe.execute()
# Lua 脚本
lua_script = """
if redis.call('get', KEYS[1]) == ARGV[1] then
return redis.call('del', KEYS[1])
else
return 0
end
"""
script = r.register_script(lua_script)
script(keys=['lock:key'], args=['value'])
4.2 Java(Lettuce / Jedis)
<!-- Maven 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
# application.yml
spring:
redis:
host: localhost
port: 6379
password: your-password
database: 0
lettuce:
pool:
max-active: 50
max-idle: 20
min-idle: 5
// Spring Data Redis 使用
@Autowired
private RedisTemplate<String, Object> redisTemplate;
// String 操作
redisTemplate.opsForValue().set("user:1001", user, 300, TimeUnit.SECONDS);
User user = (User) redisTemplate.opsForValue().get("user:1001");
// Hash 操作
redisTemplate.opsForHash().put("user:1002", "name", "张三");
String name = (String) redisTemplate.opsForHash().get("user:1002", "name");
// List 操作
redisTemplate.opsForList().leftPush("queue:tasks", "task-1");
Object task = redisTemplate.opsForList().rightPop("queue:tasks");
// ZSet 操作
redisTemplate.opsForZSet().add("leaderboard", "player1", 1000);
Set<Object> top10 = redisTemplate.opsForZSet().reverseRange("leaderboard", 0, 9);
// 使用 StringRedisTemplate(推荐)
@Autowired
private StringRedisTemplate stringRedisTemplate;
stringRedisTemplate.opsForValue().increment("counter");
4.3 Node.js(ioredis)
npm install ioredis
const Redis = require('ioredis');
// 连接
const redis = new Redis({
host: 'localhost',
port: 6379,
password: 'your-password',
db: 0,
retryStrategy: (times) => Math.min(times * 50, 2000),
});
// 基本操作
await redis.set('user:1001', JSON.stringify({ name: '张三' }), 'EX', 300);
const user = JSON.parse(await redis.get('user:1001'));
// Pipeline
const pipeline = redis.pipeline();
for (let i = 0; i < 100; i++) {
pipeline.set(`key:${i}`, i);
}
await pipeline.exec();
// 发布订阅
const sub = new Redis();
await sub.subscribe('channel:news');
sub.on('message', (channel, message) => {
console.log(`收到消息:${message}`);
});
const pub = new Redis();
await pub.publish('channel:news', '突发新闻!');
// 关闭连接
await redis.quit();
五、监控与诊断
5.1 INFO 命令
# 查看所有信息
INFO
# 查看特定部分
INFO server # 服务器信息
INFO memory # 内存信息
INFO persistence # 持久化信息
INFO stats # 统计信息
INFO clients # 客户端信息
关键指标解读:
# 内存
used_memory: 1048576000 # 已用内存(字节)
used_memory_peak: 1200000000 # 内存峰值
maxmemory: 2147483648 # 最大内存限制
# 连接
connected_clients: 100 # 当前连接数
blocked_clients: 5 # 阻塞客户端数
# 性能
instantaneous_ops_per_sec: 10000 # 每秒操作数
total_commands_processed: 1000000 # 总命令数
# 持久化
rdb_last_save_time: 1712649600 # 上次 RDB 保存时间
aof_enabled: 1 # AOF 是否开启
5.2 慢查询日志
# 设置慢查询阈值(微秒)
CONFIG SET slowlog-log-slower-than 10000 # 10ms
# 查看慢查询
SLOWLOG GET 10
# 慢查询数量
SLOWLOG LEN
# 清空慢查询
SLOWLOG RESET
5.3 实时监控
# 实时监控命令
MONITOR
# 查看当前连接
CLIENT LIST
# 查看某个客户端
CLIENT LIST ID 123
# 杀死某个客户端
CLIENT KILL ID 123
# 查看内存使用
MEMORY USAGE key
MEMORY STATS
六、最佳实践
6.1 Key 命名规范
✅ 推荐格式:
业务名:模块名:ID
user:info:1001
order:detail:20260407001
article:views:888
❌ 避免:
user_1001 # 语义不清晰
1001 # 无任何语义
user:1001:name:zhang # 层级混乱
6.2 避免大 Key
# 查找大 Key
redis-cli --bigkeys
# 查找大 Key(脚本)
for key in $(redis-cli keys "*"); do
size=$(redis-cli memory usage $key)
echo "$size $key"
done | sort -rn | head -20
大 Key 处理:
| 类型 | 阈值 | 解决方案 |
|---|---|---|
| String | > 10KB | 拆分或压缩 |
| Hash | > 1000 字段 | 按业务拆分 |
| List | > 5000 元素 | 分页存储 |
| Set/ZSet | > 5000 元素 | 分片存储 |
6.3 批量操作
# ❌ 低效:N 次网络往返
for i in range(1000):
redis.set(f"key:{i}", i)
# ✅ 高效:1 次网络往返(Pipeline)
pipe = redis.pipeline()
for i in range(1000):
pipe.set(f"key:{i}", i)
pipe.execute()
# ✅ 批量命令(MSET/MGET)
redis.mset({f"key:{i}": i for i in range(1000)})
values = redis.mget([f"key:{i}" for i in range(1000)])
6.4 连接池配置
# Python 连接池
pool = redis.ConnectionPool(
host='localhost',
port=6379,
max_connections=50, # 最大连接数
socket_timeout=5, # 超时时间
socket_connect_timeout=5,
retry_on_timeout=True,
decode_responses=True
)
// Java 连接池
LettuceConnectionFactory factory = new LettuceConnectionFactory();
factory.setPoolConfig(GenericObjectPoolConfig.builder()
.maxTotal(50)
.maxIdle(20)
.minIdle(5)
.build()
);
七、总结
快速参考表
| 操作 | 命令 | 时间复杂度 |
|---|---|---|
| 字符串读写 | SET/GET | O(1) |
| Hash 字段操作 | HSET/HGET | O(1) |
| List 两端操作 | LPUSH/RPOP | O(1) |
| Set 添加删除 | SADD/SREM | O(1) |
| ZSet 添加 | ZADD | O(log N) |
| ZSet 排名 | ZRANK | O(1) |
| 过期设置 | EXPIRE | O(1) |
| 删除键 | DEL | O(1) |
学习路线
flowchart LR
A[基础] --> B[数据类型]
B --> C[持久化]
C --> D[高可用]
D --> E[集群]
E --> F[性能优化]
F --> G[实战应用]
参考资料
- Redis 官方文档
- Redis 命令参考
- 《Redis 实战》- Josiah L. Carlson
- Redis 大学 - 美团技术博客