Redis:安装配置、核心概念与实践应用
一、Redis核心概念总览
1.1 Redis是什么?
-
内存数据库:数据主要存储在内存中,读写速度极快
-
键值存储:采用Key-Value存储结构,类似Python字典
-
数据结构丰富:支持字符串、列表、集合、哈希、有序集合等
-
NoSQL数据库:非关系型数据库,无需固定表结构
1.2 Redis与传统关系型数据库对比
| 特性 | Redis | MySQL/Oracle |
|---|---|---|
| 存储位置 | 内存为主,可持久化到磁盘 | 磁盘为主 |
| 数据结构 | Key-Value,多种数据结构 | 表-行-字段结构 |
| 查询语言 | 专用命令(SET/GET等) | SQL |
| 性能 | 极高(TPS可达10万+) | 较高(TPS约1万+) |
| 使用场景 | 缓存、会话存储、排行榜等 | 事务性数据、复杂查询 |
| 数据关系 | 无固定关系,灵活 | 关系模型,结构严谨 |
1.3 Redis主要应用场景
-
缓存系统:缓解数据库压力,提升读取速度
-
会话存储:分布式Session存储,解决集群登录问题
-
消息队列:轻量级消息传递,支持发布订阅
-
排行榜系统:实时排行,如微博热搜
-
计数器:阅读量、点赞数等实时统计
-
时效性控制:优惠券过期、验证码过期等
二、Redis安装与配置详解
2.1 安装方式对比
| 安装方式 | 命令/方法 | 特点 | 适用场景 |
|---|---|---|---|
| 源码安装 | make && make install |
最灵活,可自定义编译选项 | 生产环境,需要特定优化 |
| YUM安装 | yum install redis |
最简单,自动解决依赖 | 快速测试,内部环境 |
| Docker安装 | docker run redis |
最干净,环境隔离 | 容器化部署,多版本并存 |
2.2 源码安装完整步骤
# 1. 下载源码包(以Redis 5.0.14为例)
wget http://download.redis.io/releases/redis-5.0.14.tar.gz
# 2. 解压
tar xzvf redis-5.0.14.tar.gz
cd redis-5.0.14
# 3. 安装编译依赖
yum install -y gcc make
# 4. 编译
make
# 5. 安装到系统目录
make install
# 6. 创建配置目录
mkdir -p /etc/redis
cp redis.conf /etc/redis/
# 7. 创建数据目录
mkdir -p /var/lib/redis
2.3 关键配置项解析
# /etc/redis/redis.conf
# 基础配置
daemonize yes # 后台运行(必须修改)
bind 0.0.0.0 # 允许远程访问(默认127.0.0.1只允许本机)
protected-mode no # 关闭保护模式(允许远程连接)
port 6379 # 默认端口
# 持久化配置
save 900 1 # 900秒内至少1个key变化则保存
save 300 10 # 300秒内至少10个key变化则保存
save 60 10000 # 60秒内至少10000个key变化则保存
# 内存管理
maxmemory 1gb # 最大内存限制
maxmemory-policy allkeys-lru # 内存满时的淘汰策略
# 安全配置
requirepass yourpassword # 设置访问密码
# 日志配置
loglevel notice # 日志级别
logfile /var/log/redis.log # 日志文件路径
# 客户端配置
maxclients 10000 # 最大客户端连接数
timeout 300 # 客户端空闲超时时间(秒)
2.4 服务管理命令
# 启动Redis
redis-server /etc/redis/redis.conf
# 连接Redis(本地)
redis-cli
# 连接Redis(远程)
redis-cli -h host -p port -a password
# 关闭Redis
redis-cli shutdown
# 或
pkill redis-server
# 查看Redis状态
ps aux | grep redis
netstat -tlnp | grep 6379
# 设置开机自启(Systemd)
systemctl enable redis
systemctl start redis
systemctl status redis
三、Redis核心数据类型与命令
3.1 全局键命令
| 命令 | 语法 | 描述 | 示例 |
|---|---|---|---|
| KEYS | KEYS pattern |
查找匹配模式的键 | KEYS user:* |
| DEL | DEL key [key...] |
删除一个或多个键 | DEL user:1001 |
| EXISTS | EXISTS key |
检查键是否存在 | EXISTS user:1001 |
| TYPE | TYPE key |
获取键存储的数据类型 | TYPE user:1001 |
| EXPIRE | EXPIRE key seconds |
设置键过期时间 | EXPIRE session:abc 3600 |
| TTL | TTL key |
获取键剩余生存时间 | TTL session:abc |
| FLUSHDB | FLUSHDB |
清空当前数据库 | FLUSHDB(危险!) |
| FLUSHALL | FLUSHALL |
清空所有数据库 | FLUSHALL(更危险!) |
3.2 String(字符串)类型
特点:最基本的类型,一个key对应一个value,value最大512MB
# 基础操作
SET user:1001 "{'name':'张三','age':25}" # 设置值
GET user:1001 # 获取值
SETEX session:abc 3600 "user_data" # 设置值并指定过期时间
SETNX lock:order 1 # 不存在时才设置(分布式锁)
MSET user:1001 "张三" user:1002 "李四" # 批量设置
MGET user:1001 user:1002 # 批量获取
# 数值操作
SET counter 100
INCR counter # 自增1 => 101
INCRBY counter 10 # 增加10 => 111
DECR counter # 自减1 => 110
DECRBY counter 5 # 减少5 => 105
# 字符串操作
SET message "hello"
APPEND message " world" # 追加 => "hello world"
STRLEN message # 长度 => 11
GETRANGE message 0 4 # 截取 => "hello"
SETRANGE message 6 "Redis" # 替换 => "hello Redis"
3.3 List(列表)类型
特点:有序、可重复的字符串集合,类似双向链表
# 添加元素
LPUSH comments:post:100 "评论1" # 左侧插入
RPUSH comments:post:100 "评论2" # 右侧插入
LPUSHX comments:post:100 "评论0" # 列表存在时才插入
# 查询元素
LRANGE comments:post:100 0 -1 # 获取全部元素
LINDEX comments:post:100 0 # 获取指定位置元素
LLEN comments:post:100 # 获取列表长度
# 弹出元素
LPOP comments:post:100 # 左侧弹出
RPOP comments:post:100 # 右侧弹出
BLPOP task:queue 30 # 阻塞式左侧弹出
# 修改元素
LSET comments:post:100 0 "新评论" # 设置指定位置值
LINSERT comments:post:100 BEFORE "评论2" "评论1.5" # 在元素前插入
# 删除元素
LREM comments:post:100 1 "评论1" # 删除1个匹配元素
LTRIM comments:post:100 0 9 # 只保留前10个
# 应用场景:消息队列
LPUSH task:queue "{'type':'email','data':{...}}"
RPOP task:queue
3.4 Hash(哈希)类型
特点:field-value映射表,适合存储对象
# 操作整个Hash
HSET user:1001 name "张三" age 25 city "北京"
HGETALL user:1001 # 获取所有字段
HDEL user:1001 age # 删除字段
HEXISTS user:1001 name # 检查字段是否存在
HLEN user:1001 # 获取字段数量
# 操作单个字段
HGET user:1001 name # 获取字段值 => "张三"
HSET user:1001 age 26 # 设置字段值
HINCRBY user:1001 age 1 # 字段值自增 => 27
# 批量操作
HMSET product:1001 name "手机" price 2999 stock 100
HMGET product:1001 name price # 批量获取
# 获取字段
HKEYS user:1001 # 获取所有字段名
HVALS user:1001 # 获取所有字段值
# 应用场景:购物车
HSET cart:user:1001 item:1001 2 # 商品ID:1001,数量2
HINCRBY cart:user:1001 item:1001 1 # 增加1个
HDEL cart:user:1001 item:1001 # 删除商品
3.5 Set(集合)类型
特点:无序、不重复的字符串集合
# 添加/删除元素
SADD tags:post:100 "科技" "编程" "Redis"
SREM tags:post:100 "科技" # 删除元素
SPOP tags:post:100 # 随机弹出元素
# 查询元素
SMEMBERS tags:post:100 # 获取所有元素
SISMEMBER tags:post:100 "编程" # 判断元素是否存在 => 1
SCARD tags:post:100 # 获取元素数量
# 集合运算
SADD setA 1 2 3
SADD setB 2 3 4
SINTER setA setB # 交集 => 2,3
SUNION setA setB # 并集 => 1,2,3,4
SDIFF setA setB # 差集(A有B无)=> 1
# 应用场景
# 1. 标签系统
SADD article:100:tags "Redis" "数据库" "缓存"
# 2. 共同好友
SINTER user:1001:friends user:1002:friends
# 3. 抽奖系统
SADD lottery:20231101 user:1001 user:1002 user:1003
SRANDMEMBER lottery:20231101 2 # 随机抽取2个
3.6 Sorted Set(有序集合)类型
特点:有序、不重复,每个元素关联一个分数(score)
# 添加元素
ZADD leaderboard 95 "张三" 88 "李四" 92 "王五"
ZADD leaderboard CH 96 "张三" # CH返回被修改元素数量
# 查询元素
ZRANGE leaderboard 0 -1 # 按索引范围获取
ZRANGE leaderboard 0 -1 WITHSCORES # 带分数获取
ZREVRANGE leaderboard 0 2 # 按分数倒序获取前3
# 按分数查询
ZRANGEBYSCORE leaderboard 90 100 # 分数90-100
ZCOUNT leaderboard 90 100 # 统计数量
# 排名操作
ZRANK leaderboard "张三" # 获取正序排名
ZREVRANK leaderboard "张三" # 获取倒序排名
ZSCORE leaderboard "张三" # 获取分数
# 删除元素
ZREM leaderboard "李四" # 删除元素
ZREMRANGEBYRANK leaderboard 0 1 # 删除排名0-1
ZREMRANGEBYSCORE leaderboard 0 90 # 删除分数0-90
# 应用场景:排行榜
ZADD daily:ranking:20231101 1000 user:1001
ZINCRBY daily:ranking:20231101 50 user:1001
ZREVRANGE daily:ranking:20231101 0 9 WITHSCORES
四、Redis高级特性
4.1 事务处理
# 开启事务
MULTI
# 执行多个命令
SET user:1001:name "张三"
SET user:1001:age 25
INCR user:1001:visits
# 提交事务
EXEC
# 取消事务
DISCARD
# 监控键变化(乐观锁)
WATCH user:1001:balance
# ... 业务逻辑 ...
MULTI
DECRBY user:1001:balance 100
EXEC # 如果期间balance被修改,事务失败
4.2 发布订阅模式
# 终端1:订阅频道
SUBSCRIBE news.sports news.tech
# 终端2:发布消息
PUBLISH news.sports "中国女排夺冠!"
PUBLISH news.tech "Redis 7.0发布"
# 模式订阅
PSUBSCRIBE news.* # 订阅所有news开头的频道
# 取消订阅
UNSUBSCRIBE news.sports
PUNSUBSCRIBE news.*
4.3 Lua脚本支持
-- 原子性操作示例:检查并设置
local current = redis.call('GET', KEYS[1])
if current == ARGV[1] then
return redis.call('SET', KEYS[1], ARGV[2])
else
return 0
end
# 执行Lua脚本
EVAL "return redis.call('GET', KEYS[1])" 1 user:1001:name
EVALSHA "脚本SHA值" 1 user:1001:name
4.4 管道技术(Pipeline)
# Python示例
import redis
r = redis.Redis()
pipe = r.pipeline()
pipe.set('key1', 'value1')
pipe.set('key2', 'value2')
pipe.get('key1')
pipe.get('key2')
result = pipe.execute() # 一次性发送所有命令
五、Redis持久化机制
5.1 RDB(快照)持久化
# 配置文件设置
save 900 1 # 900秒内至少1个key变化
save 300 10 # 300秒内至少10个key变化
save 60 10000 # 60秒内至少10000个key变化
dbfilename dump.rdb # RDB文件名
dir /var/lib/redis # 保存目录
rdbcompression yes # 压缩存储
优点:
-
文件紧凑,适合备份
-
恢复大数据集时速度更快
-
最大化Redis性能
缺点:
-
可能丢失最后一次快照后的数据
-
数据集大时fork过程可能阻塞服务
5.2 AOF(追加日志)持久化
# 配置文件设置
appendonly yes # 开启AOF
appendfilename "appendonly.aof" # AOF文件名
appendfsync everysec # 同步策略:每秒同步
# 同步策略选项:
# always:每次写操作都同步(最安全,性能差)
# everysec:每秒同步一次(平衡选择)
# no:由操作系统决定(性能最好,可能丢失数据)
优点:
-
数据安全性更高
-
可读的日志格式
-
持久化更精细
缺点:
-
文件体积较大
-
恢复速度较慢
-
性能略低于RDB
5.3 混合持久化(Redis 4.0+)
aof-use-rdb-preamble yes # 开启混合持久化
工作原理:
-
AOF重写时,先将数据以RDB格式写入
-
后续增量数据以AOF格式追加
-
结合了两者的优点