Redis 详细教程
Redis(Remote Dictionary Server)是一个开源的内存数据结构存储系统,常用作数据库、缓存和消息代理。以下是 Redis 的全面教程:
1. Redis 简介
主要特点
- 内存存储:数据主要存储在内存中,提供极高的读写性能
- 数据结构丰富:支持字符串、哈希、列表、集合、有序集合等
- 持久化:支持 RDB 和 AOF 两种持久化方式
- 高可用:支持主从复制和 Redis Sentinel
- 分布式:通过 Redis Cluster 实现分布式存储
- 原子操作:所有操作都是原子性的
适用场景
- 缓存系统
- 会话缓存
- 排行榜/计数器
- 消息队列
- 实时数据分析
2. Redis 安装
Linux 安装
# Ubuntu/Debian
sudo apt update
sudo apt install redis-server
# CentOS/RHEL
sudo yum install epel-release
sudo yum install redis
# 启动Redis
sudo systemctl start redis
sudo systemctl enable redis
Mac 安装
brew install redis
brew services start redis
Windows 安装
Windows 官方不支持 Redis,但可以使用:
- Microsoft 维护的 Windows 版本:https://github.com/microsoftarchive/redis
- 使用 WSL (Windows Subsystem for Linux)
Docker 运行 Redis
docker run --name some-redis -d redis
3. Redis 命令行客户端
连接 Redis
redis-cli
# 带密码连接
redis-cli -a password
# 指定主机和端口
redis-cli -h host -p port
基本命令
PING # 测试连接,返回 PONG
AUTH pwd # 认证密码
SELECT n # 选择数据库(0-15)
QUIT # 退出连接
INFO # 获取服务器信息
FLUSHDB # 清空当前数据库
FLUSHALL # 清空所有数据库
4. Redis 数据结构与操作
1. 字符串(String)
SET key value # 设置键值
GET key # 获取值
DEL key # 删除键
EXISTS key # 检查键是否存在
EXPIRE key seconds # 设置过期时间(秒)
TTL key # 查看剩余时间
INCR key # 值递增1
DECR key # 值递减1
INCRBY key increment # 值增加指定数值
APPEND key value # 追加值
2. 哈希(Hash)
HSET key field value # 设置哈希字段值
HGET key field # 获取哈希字段值
HGETALL key # 获取所有字段和值
HDEL key field # 删除哈希字段
HEXISTS key field # 检查字段是否存在
HKEYS key # 获取所有字段名
HVALS key # 获取所有字段值
HLEN key # 获取字段数量
3. 列表(List)
LPUSH key value1 [value2] # 从左侧插入
RPUSH key value1 [value2] # 从右侧插入
LPOP key # 从左侧弹出
RPOP key # 从右侧弹出
LLEN key # 获取列表长度
LRANGE key start stop # 获取列表范围
LINDEX key index # 获取指定位置元素
LREM key count value # 删除元素
4. 集合(Set)
SADD key member1 [member2] # 添加元素
SMEMBERS key # 获取所有元素
SISMEMBER key member # 检查元素是否存在
SCARD key # 获取元素数量
SREM key member # 删除元素
SINTER key1 key2 # 交集
SUNION key1 key2 # 并集
SDIFF key1 key2 # 差集
5. 有序集合(Sorted Set)
ZADD key score1 member1 [score2 member2] # 添加元素
ZRANGE key start stop [WITHSCORES] # 按索引范围获取
ZREVRANGE key start stop [WITHSCORES] # 按索引倒序获取
ZRANGEBYSCORE key min max [WITHSCORES] # 按分数范围获取
ZREM key member # 删除元素
ZCARD key # 获取元素数量
ZCOUNT key min max # 统计分数范围内元素
ZRANK key member # 获取元素排名(升序)
ZREVRANK key member # 获取元素排名(降序)
5. Redis 高级功能
1. 发布/订阅
# 订阅频道
SUBSCRIBE channel1 channel2
# 发布消息(另开客户端)
PUBLISH channel1 "Hello Redis"
# 模式订阅
PSUBSCRIBE news.*
# 取消订阅
UNSUBSCRIBE channel1
PUNSUBSCRIBE news.*
2. 事务
MULTI # 开始事务
SET key1 value1
SET key2 value2
EXEC # 执行事务
DISCARD # 取消事务
3. Lua 脚本
EVAL "return redis.call('GET', KEYS[1])" 1 mykey
4. 管道(Pipeline)
客户端技术,减少网络往返时间,示例(Python):
pipe = r.pipeline()
pipe.set('foo', 'bar')
pipe.get('foo')
result = pipe.execute()
6. Redis 持久化
1. RDB (Redis Database)
- 定时快照
配置(redis.conf):
conf
save 900 1 # 900秒内至少1个key变化 save 300 10 # 300秒内至少10个key变化 save 60 10000 # 60秒内至少10000个key变化 dbfilename dump.rdb dir ./
2. AOF (Append Only File)
- 记录所有写操作
配置(redis.conf):
conf
appendonly yes appendfilename "appendonly.aof" appendfsync everysec # 每秒同步 # appendfsync always # 每次写都同步 # appendfsync no # 不主动同步
7. Redis 高可用
1. 主从复制
# 从服务器配置(redis.conf)
replicaof 主服务器IP 主服务器端口
masterauth 主服务器密码
2. Redis Sentinel
监控主从服务器,自动故障转移
配置 sentinel.conf:
conf
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster password
sentinel down-after-milliseconds mymaster 5000
sentinel failover-timeout mymaster 60000
启动 Sentinel:
redis-server /path/to/sentinel.conf --sentinel
3. Redis Cluster
分布式解决方案,数据分片存储在多个节点
创建集群(至少3主3从):
redis-cli --cluster create 127.0.0.1:7000 127.0.0.1:7001 \
127.0.0.1:7002 127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
--cluster-replicas 1
8. Redis 安全
1. 认证密码
配置 redis.conf:
conf
requirepass yourpassword
2. 绑定IP
conf
bind 127.0.0.1
3. 禁用危险命令
conf
rename-command FLUSHALL ""
rename-command CONFIG ""
4. 防火墙设置
iptables -A INPUT -p tcp --dport 6379 -s trusted_ip -j ACCEPT
iptables -A INPUT -p tcp --dport 6379 -j DROP
9. Redis 性能优化
- 合理使用数据结构:根据场景选择最适合的数据结构
- 批量操作:使用管道或批量命令(MSET, HMSET等)
- 避免大键:单个键值不宜过大(建议小于1MB)
- 设置合理过期时间:避免内存无限增长
- 使用连接池:减少连接创建开销
持久化优化:
- RDB适合备份,AOF适合数据安全
- 根据业务需求选择适当的同步策略
内存优化:
- 使用
redis-cli --bigkeys
分析大键 - 使用
MEMORY USAGE key
查看键内存占用
- 使用
10. 常用客户端
Python (redis-py)
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
r.set('foo', 'bar')
print(r.get('foo'))
Java (Jedis)
Jedis jedis = new Jedis("localhost");
jedis.set("foo", "bar");
System.out.println(jedis.get("foo"));
jedis.close();
Node.js (ioredis)
const Redis = require('ioredis');
const redis = new Redis();
redis.set('foo', 'bar');
redis.get('foo', (err, result) => {
console.log(result);
});
11. Redis 监控与管理
1. 监控命令
INFO # 查看服务器信息
INFO memory # 内存信息
INFO stats # 统计信息
INFO cpu # CPU信息
CLIENT LIST # 查看客户端连接
SLOWLOG GET # 查看慢查询
2. 性能测试
redis-benchmark -h 127.0.0.1 -p 6379 -c 100 -n 100000
3. 数据迁移
# 导出
redis-cli --rdb dump.rdb
# 导入
redis-cli --pipe < dump.rdb
12. Redis 常见应用场景实现
1. 缓存实现
def get_data(key):
data = redis.get(key)
if not data:
data = db.query(...) # 从数据库获取
redis.setex(key, 3600, data) # 缓存1小时
return data
2. 分布式锁
def acquire_lock(lock_name, acquire_timeout=10):
identifier = str(uuid.uuid4())
end = time.time() + acquire_timeout
while time.time() < end:
if redis.setnx(lock_name, identifier):
redis.expire(lock_name, lock_timeout)
return identifier
elif not redis.ttl(lock_name):
redis.expire(lock_name, lock_timeout)
time.sleep(0.001)
return False
def release_lock(lock_name, identifier):
with redis.pipeline() as pipe:
while True:
try:
pipe.watch(lock_name)
if pipe.get(lock_name) == identifier:
pipe.multi()
pipe.delete(lock_name)
pipe.execute()
return True
pipe.unwatch()
break
except redis.exceptions.WatchError:
pass
return False
3. 排行榜
# 添加分数
ZADD leaderboard 100 "player1" 200 "player2"
# 获取前10名
ZREVRANGE leaderboard 0 9 WITHSCORES
# 获取玩家排名
ZREVRANK leaderboard "player1"
4. 限流器
def rate_limiter(user_id, limit=10, period=60):
key = f"rate_limit:{user_id}"
current = redis.llen(key)
if current >= limit:
return False
if not redis.exists(key):
pipeline = redis.pipeline()
pipeline.rpush(key, "1")
pipeline.expire(key, period)
pipeline.execute()
else:
redis.rpushx(key, "1")
return True
Redis 是一个功能强大且灵活的工具,适用于各种高性能场景。通过合理使用其数据结构和特性,可以构建出高效可靠的系统。