Redis 8.4.0 完整教程
1. Redis简介与安装
1.1 Redis是什么
Redis(Remote Dictionary Server)是一个开源的内存数据结构存储系统,可用作数据库、缓存和消息中间件。
Redis支持多种数据结构,如字符串、哈希、列表、集合、有序集合等,并提供了丰富的操作命令。
1.2 Redis 8.4.0 新特性
- 重回自由开源阵营
- 显著的性能与效率提升(超过30项性能改进)
- 关键修复与性能优化
- 增强的安全性
- 更好的集群管理功能
- 新增多项实用功能
- 改进的内存管理
- 增强的复制机制
- 优化的持久化性能
1.3 安装Redis 8.4.0
1.3.1 Linux系统安装
# 下载Redis 8.4.0源代码wgethttp://download.redis.io/releases/redis-8.4.0.tar.gz# 解压源代码tarxzf redis-8.4.0.tar.gz# 进入Redis目录cdredis-8.4.0# 编译Redismake# 安装Redismakeinstall# 创建Redis配置目录mkdir-p /etc/redis# 复制默认配置文件cpredis.conf /etc/redis/1.3.1.1 配置Redis
# 编辑Redis配置文件vi/etc/redis/redis.conf# 在配置文件中进行以下设置:# 1. 设置Redis密码# requirepass foobared# 改为:requirepass your_strong_password# 2. 允许所有远程主机访问# bind 127.0.0.1 -::1# 改为:bind0.0.0.0# 3. 线程优化(Redis 6.0+支持多线程)io-threads4io-threads-do-readsyes# 4. 设置后台运行daemonizeyes# 5. 设置日志文件路径logfile /var/log/redis/redis-server.log# 6. 设置数据目录dir/var/lib/redis# 保存并退出编辑器1.3.1.2 创建Redis数据目录和日志目录
# 创建数据目录mkdir-p /var/lib/redis# 创建日志目录mkdir-p /var/log/redis# 设置目录权限chown-R redis:redis /var/lib/redischown-R redis:redis /var/log/redischmod755/var/lib/redischmod755/var/log/redis1.3.1.3 创建Redis系统用户
# 创建Redis用户useradd-r -s /bin/false redis1.3.1.4 设置Redis为系统服务
# 复制Redis服务脚本到系统服务目录cputils/systemd-redis_server.service /etc/systemd/system/redis-server.service# 编辑服务脚本vi/etc/systemd/system/redis-server.service# 确保以下内容正确:[Unit]Description=Redis In-Memory Data StoreAfter=network.target[Service]User=redisGroup=redisExecStart=/usr/local/bin/redis-server /etc/redis/redis.confExecStop=/usr/local/bin/redis-cli -a your_strong_passwordshutdownRestart=always[Install]WantedBy=multi-user.target# 保存并退出编辑器# 重新加载系统服务systemctl daemon-reload# 启动Redis服务systemctl start redis-server# 设置Redis开机自动启动systemctlenableredis-server# 检查Redis服务状态systemctl status redis-server1.3.1.5 验证Redis安装
# 使用密码连接Redisredis-cli -a your_strong_password# 测试Redis连接ping# 应返回 PONG# 退出Redis客户端exit1.3.2 Windows系统安装
Redis官方提供了Windows版本的安装包,我们可以从redis-windows仓库下载最新的8.4.0版本。
1.3.2.1 下载Redis 8.4.0 Windows版本
访问Redis Windows版本的GitHub发布页面:
https://github.com/redis-windows/redis-windows/releases/tag/8.4.0下载适合您系统的安装包:
- 对于64位Windows系统:选择
redis-8.4.0-windows-x64.zip - 对于32位Windows系统:选择
redis-8.4.0-windows-x86.zip
- 对于64位Windows系统:选择
1.3.2.2 安装Redis
解压下载的ZIP文件到您想要安装的目录,例如:
C:\Redis\解压后,您将看到以下主要文件:
redis-server.exe:Redis服务器程序redis-cli.exe:Redis命令行客户端redis.windows.conf:Redis配置文件redis-benchmark.exe:Redis性能测试工具redis-check-aof.exe:AOF文件检查工具redis-check-dump.exe:RDB文件检查工具
1.3.2.3 配置Redis
打开Redis配置文件
redis.windows.conf进行以下重要配置(可选):
- 设置Redis密码:找到
requirepass行,取消注释并设置密码requirepass your_strong_password - 设置最大内存:找到
maxmemory行,取消注释并设置合适的内存大小maxmemory 512mb - 设置内存淘汰策略:找到
maxmemory-policy行,设置合适的淘汰策略maxmemory-policy allkeys-lru
- 设置Redis密码:找到
1.3.2.4 启动Redis
方法一:临时启动(命令行方式)
打开命令提示符(cmd)或PowerShell
导航到Redis安装目录:
cd C:\Redis启动Redis服务器:
redis-server.exe redis.windows.conf此时Redis服务器将在当前窗口运行,关闭窗口则Redis服务器停止
方法二:安装为Windows服务(推荐)
以管理员身份打开命令提示符(cmd)或PowerShell
导航到Redis安装目录:
cd C:\Redis安装Redis服务:
redis-server.exe --service-install redis.windows.conf --loglevel verbose启动Redis服务:
redis-server.exe --service-start停止Redis服务(如需):
redis-server.exe --service-stop卸载Redis服务(如需):
redis-server.exe --service-uninstall
1.3.2.5 测试Redis连接
打开一个新的命令提示符或PowerShell窗口
导航到Redis安装目录:
cd C:\Redis使用Redis客户端连接到Redis服务器:
redis-cli.exe如果设置了密码,使用以下命令认证:
AUTH your_strong_password测试Redis连接:
ping- 成功连接将返回:
PONG
- 成功连接将返回:
测试设置和获取键值:
SET test_key "Hello Redis 8.4.0" GET test_key- 成功将返回:
"Hello Redis 8.4.0"
- 成功将返回:
退出Redis客户端:
exit
1.3.2.6 验证Redis服务状态
打开Windows服务管理器:
- 按
Win + R键,输入services.msc,然后按回车
- 按
在服务列表中查找
Redis服务检查服务状态,确保其显示为
正在运行您可以右键点击服务,选择
属性来修改启动类型(例如设置为自动,以便开机自启)
1.4 启动Redis
# 启动Redis服务器redis-server# 使用指定配置文件启动redis-server /path/to/redis.conf# 启动Redis客户端redis-cli1.5 Redis架构图
2. Redis基础命令
2.1 连接与认证
# 连接到本地Redis服务器redis-cli# 连接到远程Redis服务器redis-cli -hhost-p port# 使用密码认证redis-cli -a password# 在客户端中认证AUTH password2.2 服务器信息
# 获取服务器信息INFO# 获取指定部分的信息INFO server INFO clients INFO memory INFO persistence INFO replication INFO cpu INFO stats2.3 键操作命令
# 设置键值对SET key value# 获取键对应的值GET key# 检查键是否存在EXISTS key# 删除键DEL key# 重命名键RENAME key newkey# 查看所有键KEYS *# 查看键的类型TYPE key# 设置键的过期时间(秒)EXPIRE key seconds# 设置键的过期时间(毫秒)PEXPIRE key milliseconds# 查看键的剩余过期时间(秒)TTL key# 查看键的剩余过期时间(毫秒)PTTL key# 移除键的过期时间PERSIST key3. Redis数据类型详解
3.1 字符串(String)
字符串是Redis最基本的数据类型,一个键最大能存储512MB。
3.1.1 基本操作
# 设置字符串值SET name"Redis"# 将键name的值设置为"Redis"# 获取字符串值GET name# 返回键name的值"Redis"# 批量设置多个键值对MSET key1 value1 key2 value2# 同时设置多个键值对# 批量获取多个键的值MGET key1 key2# 同时获取多个键的值# 追加字符串APPEND name" 8.2.1"# 追加字符串到键name的值末尾,结果为"Redis 8.4.0"# 获取字符串长度STRLEN name# 返回键name的值的长度3.1.2 数字操作
# 递增1INCR counter# 将键counter的值递增1# 递减1DECR counter# 将键counter的值递减1# 递增指定数值INCRBY counter10# 将键counter的值递增10# 递减指定数值DECRBY counter5# 将键counter的值递减5# 递增浮点数INCRBYFLOAT counter0.5# 将键counter的值递增0.53.1.3 字符串数据结构图
3.2 哈希(Hash)
哈希是一个键值对集合,适合存储对象。
3.2.1 基本操作
# 设置哈希字段值HSET user:1 name"John"# 设置哈希user:1的name字段为"John"# 获取哈希字段值HGET user:1 name# 获取哈希user:1的name字段值# 设置多个哈希字段值HMSET user:1 age30city"New York"# 同时设置哈希user:1的多个字段# 获取多个哈希字段值HMGET user:1 name age city# 同时获取哈希user:1的多个字段值# 获取所有哈希字段和值HGETALL user:1# 返回哈希user:1的所有字段和值# 获取所有哈希字段HKEYS user:1# 返回哈希user:1的所有字段# 获取所有哈希值HVALS user:1# 返回哈希user:1的所有值# 获取哈希字段数量HLEN user:1# 返回哈希user:1的字段数量# 检查哈希字段是否存在HEXISTS user:1 name# 检查哈希user:1是否存在name字段# 删除哈希字段HDEL user:1 city# 删除哈希user:1的city字段3.2.2 数字操作
# 哈希字段值递增HINCRBY user:1 age1# 将哈希user:1的age字段值递增1# 哈希字段值递增浮点数HINCRBYFLOAT user:1 salary100.5# 将哈希user:1的salary字段值递增100.53.2.3 哈希数据结构图
3.3 列表(List)
列表是简单的字符串列表,按照插入顺序排序。
3.3.1 基本操作
# 从列表左侧插入元素LPUSH mylist"a"# 将元素"a"插入到列表mylist的左侧LPUSH mylist"b""c"# 将元素"b"和"c"插入到列表mylist的左侧# 从列表右侧插入元素RPUSH mylist"d"# 将元素"d"插入到列表mylist的右侧# 从列表左侧弹出元素LPOP mylist# 从列表mylist的左侧弹出一个元素# 从列表右侧弹出元素RPOP mylist# 从列表mylist的右侧弹出一个元素# 获取列表长度LLEN mylist# 返回列表mylist的长度# 获取列表指定范围的元素LRANGE mylist0-1# 返回列表mylist的所有元素LRANGE mylist02# 返回列表mylist的前3个元素3.3.2 列表操作进阶
# 获取列表指定索引的元素LINDEX mylist1# 返回列表mylist索引为1的元素# 设置列表指定索引的元素值LSET mylist1"new_value"# 设置列表mylist索引为1的元素值# 在列表指定元素前插入元素LINSERT mylist BEFORE"b""new_elem"# 在列表mylist中元素"b"前插入"new_elem"# 在列表指定元素后插入元素LINSERT mylist AFTER"b""new_elem"# 在列表mylist中元素"b"后插入"new_elem"# 移除列表中指定数量的指定元素LREM mylist0"a"# 移除列表mylist中所有的"a"元素LREM mylist2"b"# 移除列表mylist中前2个"b"元素# 修剪列表,只保留指定范围的元素LTRIM mylist02# 只保留列表mylist的前3个元素3.3.3 列表数据结构图
3.4 集合(Set)
集合是字符串的无序集合,不允许重复元素。
3.4.1 基本操作
# 向集合添加元素SADD myset"a"# 向集合myset添加元素"a"SADD myset"b""c""d"# 向集合myset添加多个元素# 从集合移除元素SREM myset"a"# 从集合myset移除元素"a"# 获取集合所有元素SMEMBERS myset# 返回集合myset的所有元素# 检查元素是否在集合中SISMEMBER myset"b"# 检查元素"b"是否在集合myset中# 获取集合大小SCARD myset# 返回集合myset的元素数量# 从集合随机弹出一个元素SPOP myset# 从集合myset随机弹出一个元素# 从集合随机获取指定数量的元素SRANDMEMBER myset2# 从集合myset随机获取2个元素,不弹出3.4.2 集合运算
# 集合交集SINTER set1 set2# 返回集合set1和set2的交集# 集合并集SUNION set1 set2# 返回集合set1和set2的并集# 集合并集存储到新集合SUNIONSTORE newset set1 set2# 将集合set1和set2的并集存储到newset# 集合差集SDIFF set1 set2# 返回集合set1和set2的差集(set1中有而set2中没有的元素)3.4.3 集合数据结构图
3.5 有序集合(Sorted Set)
有序集合是字符串的有序集合,不允许重复元素,每个元素关联一个分数(score)用于排序。
3.5.1 基本操作
# 向有序集合添加元素ZADD myzset1"a"# 向有序集合myzset添加元素"a",分数为1ZADD myzset2"b"3"c"# 向有序集合myzset添加多个元素# 获取有序集合元素数量ZCARD myzset# 返回有序集合myzset的元素数量# 获取有序集合指定分数范围的元素数量ZCOUNT myzset13# 返回有序集合myzset中分数在1-3之间的元素数量# 增加有序集合元素的分数ZINCRBY myzset1"a"# 将有序集合myzset中元素"a"的分数增加13.5.2 有序集合排序操作
# 按分数从小到大获取元素ZRANGE myzset0-1# 返回有序集合myzset的所有元素,按分数从小到大排序ZRANGE myzset02# 返回有序集合myzset的前3个元素,按分数从小到大排序# 按分数从大到小获取元素ZREVRANGE myzset0-1# 返回有序集合myzset的所有元素,按分数从大到小排序# 按分数从小到大获取元素及分数ZRANGE myzset0-1 WITHSCORES# 返回有序集合myzset的所有元素及分数,按分数从小到大排序# 获取元素的分数ZSCORE myzset"a"# 返回有序集合myzset中元素"a"的分数# 获取元素的排名(按分数从小到大,从0开始)ZRANK myzset"a"# 返回有序集合myzset中元素"a"的排名# 获取元素的排名(按分数从大到小,从0开始)ZREVRANK myzset"a"# 返回有序集合myzset中元素"a"的逆序排名3.5.3 有序集合范围操作
# 按分数范围获取元素(从小到大)ZRANGEBYSCORE myzset13# 返回有序集合myzset中分数在1-3之间的元素ZRANGEBYSCORE myzset(13# 返回有序集合myzset中分数大于1且小于等于3的元素ZRANGEBYSCORE myzset -inf +inf# 返回有序集合myzset的所有元素# 按分数范围删除元素ZREMRANGEBYSCORE myzset13# 删除有序集合myzset中分数在1-3之间的元素# 按排名范围删除元素ZREMRANGEBYRANK myzset02# 删除有序集合myzset中排名0-2的元素3.5.4 有序集合数据结构图
3.6 其他数据类型
3.6.1 HyperLogLog
用于统计基数(不重复元素的数量)。
# 添加元素到HyperLogLogPFADD myhll"a""b""c"# 向HyperLogLog myhll添加元素# 获取HyperLogLog的基数估计值PFCOUNT myhll# 返回HyperLogLog myhll的基数估计值# 合并多个HyperLogLogPFMERGE newhll hll1 hll2# 将hll1和hll2合并到newhll3.6.2 Geo
用于存储地理位置信息。
# 添加地理位置GEOADD cities116.407439.9042"Beijing"# 添加北京的经纬度GEOADD cities121.473731.2304"Shanghai"# 添加上海的经纬度# 计算两个地理位置的距离GEODIST cities"Beijing""Shanghai"km# 计算北京到上海的距离,单位为公里# 根据经纬度范围获取地理位置GEORADIUS cities116.407439.9042100km# 获取北京100公里范围内的城市# 获取地理位置的经纬度GEOPOS cities"Beijing"# 获取北京的经纬度3.6.3 Bitmap
用于位操作。
# 设置位值SETBIT mybitmap01# 设置mybitmap的第0位为1# 获取位值GETBIT mybitmap0# 获取mybitmap的第0位的值# 统计位为1的数量BITCOUNT mybitmap# 统计mybitmap中位为1的数量# 位运算BITOP AND destbitmap bitmap1 bitmap2# 对bitmap1和bitmap2进行AND运算,结果存储到destbitmap4. Redis持久化
4.1 持久化概述
Redis提供了两种持久化方式:RDB(Redis Database)和AOF(Append Only File)。
4.2 RDB持久化
RDB是Redis默认的持久化方式,它会在指定的时间间隔内生成数据集的快照。
4.2.1 RDB配置
# 900秒内至少有1个键被修改,执行RDB持久化 save 900 1 # 300秒内至少有10个键被修改,执行RDB持久化 save 300 10 # 60秒内至少有10000个键被修改,执行RDB持久化 save 60 10000 # RDB文件名称 dbfilename dump.rdb # RDB文件存储路径 dir ./4.2.2 RDB优缺点
优点:
- 适合备份和灾难恢复
- 恢复速度比AOF快
- 文件体积小
缺点:
- 可能会丢失最后一次快照后的所有数据
- 执行快照时会阻塞主线程
4.3 AOF持久化
AOF持久化会记录服务器执行的所有写操作命令,并在服务器启动时通过重新执行这些命令来恢复数据。
4.3.1 AOF配置
# 开启AOF持久化 appendonly yes # AOF文件名称 appendfilename "appendonly.aof" # AOF持久化策略 # always:每次写操作都持久化到磁盘 # everysec:每秒持久化一次 # no:由操作系统决定何时持久化 appendfsync everysec # AOF重写策略 auto-aof-rewrite-percentage 100 auto-aof-rewrite-min-size 64mb4.3.2 AOF优缺点
优点:
- 数据安全性更高,丢失数据更少
- 支持"appendfsync everysec"模式,每秒持久化一次,最多丢失1秒的数据
- AOF文件是可读的,可以手动修改和恢复
缺点:
- AOF文件体积比RDB大
- 恢复速度比RDB慢
4.4 持久化选择建议
| 场景 | 推荐持久化方式 |
|---|---|
| 数据安全性要求高 | RDB + AOF |
| 主要用于缓存 | 禁用持久化或使用RDB |
| 大数据集 | RDB |
4.5 Redis持久化架构图
5. Redis主从复制
5.1 主从复制概述
主从复制是Redis实现高可用的基础,它允许将一个Redis服务器的数据复制到多个从服务器上。
5.2 主从复制的作用
- 数据冗余:实现数据的热备份
- 负载均衡:读写分离,主服务器处理写请求,从服务器处理读请求
- 故障恢复:当主服务器出现故障时,可以将从服务器升级为主服务器
- 高可用基础:是哨兵模式和集群模式的基础
5.3 配置主从复制
5.3.1 方法一:修改配置文件
在从服务器的配置文件中添加:
# 指定主服务器的IP和端口 replicaof masterip masterport # 如果主服务器有密码,需要配置密码 masterauth masterpassword5.3.2 方法二:使用命令
在从服务器的客户端中执行:
# 设置主服务器REPLICAOF masterip masterport# 设置主服务器密码CONFIG SET masterauth masterpassword5.4 主从复制原理
- 从服务器连接到主服务器,发送SYNC命令
- 主服务器收到SYNC命令后,执行BGSAVE生成RDB文件,并记录此时开始的所有写命令
- 主服务器将RDB文件发送给从服务器
- 从服务器接收并加载RDB文件,恢复数据
- 主服务器将记录的写命令发送给从服务器
- 从服务器执行这些写命令,与主服务器数据保持一致
- 之后主服务器每次执行写命令,都会将命令发送给从服务器执行
5.5 主从复制架构图
6. Redis哨兵模式
6.1 哨兵模式概述
哨兵模式是Redis的高可用解决方案,它可以监控Redis主从服务器,并在主服务器出现故障时自动将从服务器升级为主服务器。
6.2 哨兵模式的作用
- 监控:监控主从服务器是否正常运行
- 通知:当服务器出现故障时,向管理员或其他应用程序发送通知
- 自动故障转移:当主服务器出现故障时,自动将从服务器升级为主服务器
- 配置管理:当故障转移发生后,通知客户端更新主服务器的地址
6.3 配置哨兵模式
6.3.1 哨兵配置文件(sentinel.conf)
# 哨兵监听的主服务器,名称为mymaster,IP为127.0.0.1,端口为6379,投票数为2 sentinel monitor mymaster 127.0.0.1 6379 2 # 主服务器的密码 sentinel auth-pass mymaster password # 主服务器多久没有响应,就认为主服务器下线(毫秒) sentinel down-after-milliseconds mymaster 30000 # 故障转移超时时间(毫秒) sentinel failover-timeout mymaster 1800006.3.2 启动哨兵
# 启动哨兵redis-sentinel /path/to/sentinel.conf# 使用redis-server启动哨兵redis-server /path/to/sentinel.conf --sentinel6.4 哨兵模式工作原理
- 哨兵定期向主从服务器发送PING命令,检测服务器是否正常运行
- 如果主服务器在指定时间内没有响应,哨兵会将其标记为"主观下线"
- 其他哨兵也会检测主服务器,如果超过指定数量的哨兵都认为主服务器下线,就会将其标记为"客观下线"
- 哨兵们会选举出一个领导者,负责执行故障转移
- 领导者哨兵会从从服务器中选择一个最合适的升级为主服务器
- 领导者哨兵会通知其他从服务器复制新的主服务器
- 领导者哨兵会通知客户端更新主服务器的地址
6.5 哨兵模式架构图
7. Redis集群
7.1 集群模式概述
Redis集群是Redis的分布式解决方案,它将数据分布在多个节点上,实现了数据的分片存储和高可用。
7.2 集群模式的特点
- 数据分片:将数据分布在多个节点上,每个节点存储部分数据
- 高可用性:支持自动故障转移,当某个节点出现故障时,其他节点会自动接管其工作
- 水平扩展:可以通过添加节点来扩展集群的容量和性能
- 无中心架构:集群中的每个节点都是平等的,没有主从之分
7.3 集群数据分片
Redis集群使用哈希槽(Hash Slot)来分配数据,整个集群共有16384个哈希槽。
- 每个键通过CRC16算法计算出哈希值,然后对16384取模,得到对应的哈希槽
- 每个节点负责处理一部分哈希槽
- 当添加或删除节点时,哈希槽会在节点之间重新分配
7.4 配置集群模式
7.4.1 配置文件
在每个节点的配置文件中添加:
# 开启集群模式 cluster-enabled yes # 集群配置文件,由Redis自动生成和更新 cluster-config-file nodes.conf # 集群节点超时时间(毫秒) cluster-node-timeout 150007.4.2 启动节点
# 启动第一个节点redis-server /path/to/redis.conf --port7000# 启动第二个节点redis-server /path/to/redis.conf --port7001# 启动第三个节点redis-server /path/to/redis.conf --port7002# 启动第四个节点redis-server /path/to/redis.conf --port7003# 启动第五个节点redis-server /path/to/redis.conf --port7004# 启动第六个节点redis-server /path/to/redis.conf --port70057.4.3 创建集群
# 创建集群,使用redis-cli的--cluster选项redis-cli --cluster create127.0.0.1:7000127.0.0.1:7001127.0.0.1:7002127.0.0.1:7003127.0.0.1:7004127.0.0.1:7005 --cluster-replicas17.5 集群模式架构图
8. Redis事务与Lua脚本
8.1 Redis事务
Redis事务允许将多个命令打包执行,要么全部执行,要么全部不执行。
8.1.1 事务命令
# 开始事务MULTI# 标记事务的开始# 执行命令(此时命令会被放入事务队列,不会立即执行)SET key1 value1 SET key2 value2 GET key1# 执行事务EXEC# 执行事务队列中的所有命令# 取消事务DISCARD# 取消事务,清空事务队列8.1.2 事务的特点
- 原子性:事务中的所有命令要么全部执行,要么全部不执行
- 隔离性:事务执行期间,其他客户端的命令不会插入到事务执行序列中
- 没有持久性:Redis事务的持久性取决于Redis的持久化配置
8.2 Lua脚本
Lua脚本是Redis支持的一种脚本语言,可以在Redis服务器端执行复杂的操作。
8.2.1 执行Lua脚本
# 使用EVAL命令执行Lua脚本EVAL"return redis.call('SET', KEYS[1], ARGV[1])"1mykey myvalue# 使用EVALSHA命令执行已缓存的Lua脚本SCRIPT LOAD"return redis.call('SET', KEYS[1], ARGV[1])"EVALSHA<script_sha1>1mykey myvalue# 检查Lua脚本是否已缓存SCRIPT EXISTS<script_sha1># 清除所有已缓存的Lua脚本SCRIPT FLUSH8.2.2 Lua脚本的优势
- 原子性:Lua脚本在执行期间不会被其他命令打断
- 减少网络开销:将多个命令合并为一个脚本执行,减少了网络往返次数
- 复用性:可以将常用的操作封装为Lua脚本,方便复用
- 灵活性:可以实现Redis内置命令无法实现的复杂逻辑
8.3 事务与Lua脚本的比较
| 特性 | 事务 | Lua脚本 |
|---|---|---|
| 原子性 | 支持 | 支持 |
| 复杂逻辑 | 不支持 | 支持 |
| 网络开销 | 较大 | 较小 |
| 复用性 | 不支持 | 支持 |
| 调试难度 | 较易 | 较难 |
9. Redis发布订阅
9.1 发布订阅概述
Redis发布订阅是一种消息通信模式,发送者(publisher)发送消息,订阅者(subscriber)接收消息。
9.2 发布订阅命令
# 订阅频道SUBSCRIBE channel1 channel2# 订阅channel1和channel2频道# 发布消息PUBLISH channel1"Hello, Redis!"# 向channel1频道发布消息"Hello, Redis!"# 订阅模式PSUBSCRIBE ch*# 订阅所有以"ch"开头的频道# 取消订阅UNSUBSCRIBE channel1# 取消订阅channel1频道PUNSUBSCRIBE ch*# 取消订阅所有以"ch"开头的频道9.3 发布订阅架构图
10. Redis内存管理
10.1 内存管理概述
Redis是内存数据库,内存管理对Redis的性能和稳定性至关重要。
10.2 内存配置
# 设置Redis最大使用内存 maxmemory 1gb # 设置内存淘汰策略 maxmemory-policy volatile-lru10.3 内存淘汰策略
| 策略 | 描述 |
|---|---|
| noeviction | 当内存不足时,新写入操作会报错 |
| allkeys-lru | 移除最近最少使用的键 |
| allkeys-random | 随机移除某个键 |
| volatile-lru | 移除最近最少使用的键,只针对设置了过期时间的键 |
| volatile-random | 随机移除某个键,只针对设置了过期时间的键 |
| volatile-ttl | 移除剩余过期时间最短的键 |
| volatile-lfu | 移除最不经常使用的键,只针对设置了过期时间的键 |
| allkeys-lfu | 移除最不经常使用的键 |
10.4 内存优化建议
- 设置合理的maxmemory和maxmemory-policy
- 使用适当的数据类型,例如:
- 存储整数时,使用字符串类型,Redis会自动编码为整数
- 存储对象时,使用哈希类型,而不是多个字符串类型
- 存储大量相同前缀的键时,考虑使用哈希类型或压缩列表
- 定期清理过期键
- 使用Redis集群进行水平扩展
- 考虑使用Redis的持久化机制,将不常用的数据持久化到磁盘
10.5 内存分析工具
# 获取内存使用信息INFO memory# 查看键的内存使用情况MEMORY USAGE key# 查看内存分配情况MEMORY STATS# 查看内存碎片率MEMORY FRAGMENTATION RATIO11. Redis性能优化
11.1 性能优化概述
Redis的性能优化涉及多个方面,包括硬件、配置、数据结构设计、命令使用等。
11.2 硬件优化
- 使用高性能的CPU和内存
- 使用SSD存储,提高持久化性能
- 确保网络带宽充足,减少网络延迟
11.3 配置优化
# 关闭持久化(如果主要用于缓存) appendonly no # 设置合理的maxmemory和maxmemory-policy maxmemory 1gb maxmemory-policy allkeys-lru # 开启慢查询日志,便于分析性能问题 slowlog-log-slower-than 10000 slowlog-max-len 128 # 调整TCP连接参数 tcp-keepalive 300 timeout 0 # 调整线程数(Redis 6.0+) io-threads 411.4 数据结构优化
- 选择合适的数据类型
- 避免使用大键
- 使用压缩列表和整数集合
- 合理使用哈希槽(集群模式)
11.5 命令使用优化
- 减少命令的执行次数,使用批量命令
- 避免使用O(N)复杂度的命令,例如:
- KEYS * (使用SCAN代替)
- HGETALL (使用HMGET或HSCAN代替)
- LRANGE 0 -1 (使用LLEN和LRANGE分批获取)
- 合理使用管道(Pipeline)
- 使用Lua脚本减少网络开销
11.6 性能监控
# 查看Redis的性能统计信息INFO stats# 查看慢查询日志SLOWLOG GET# 使用redis-cli的--latency选项测试延迟redis-cli --latency -hhost-p port# 使用redis-cli的--stat选项查看实时统计信息redis-cli --stat -hhost-p port12. Redis安全配置
12.1 安全配置概述
Redis默认配置的安全性较低,需要进行适当的配置来提高安全性。
12.2 安全配置建议
- 设置强密码
# 设置Redis密码 requirepass strong_password- 绑定特定IP
# 只允许本地访问 bind 127.0.0.1- 禁用危险命令
# 重命名危险命令 rename-command FLUSHDB "" rename-command FLUSHALL "" rename-command CONFIG "" rename-command KEYS ""使用防火墙限制访问
定期更新Redis版本
开启AOF持久化,提高数据安全性
配置合理的持久化策略
12.3 安全审计
# 查看当前连接的客户端CLIENT LIST# 查看Redis的配置CONFIG GET *# 查看Redis的日志tail-f /path/to/redis.log13. Redis应用场景
13.1 缓存
Redis最常用的场景是作为缓存使用,用于存储热点数据,减少数据库的访问压力。
使用示例:
importredisimportmysql.connector# 连接Redisr=redis.Redis(host='localhost',port=6379,db=0)# 连接MySQLdb=mysql.connector.connect(host='localhost',user='root',password='password',database='test_db')cursor=db.cursor()defget_user(user_id):# 先从Redis获取user=r.get(f'user:{user_id}')ifuser:returneval(user)# 如果Redis没有,从MySQL获取cursor.execute(f"SELECT * FROM users WHERE id ={user_id}")user=cursor.fetchone()ifuser:# 将数据存入Redis,设置过期时间为1小时r.setex(f'user:{user_id}',3600,str(user))returnuser13.2 会话存储
Redis可以用于存储用户会话信息,支持分布式部署。
13.3 消息队列
Redis的列表和发布订阅功能可以用于实现简单的消息队列。
使用列表实现消息队列:
# 生产者向队列发送消息LPUSH queue message1 LPUSH queue message2# 消费者从队列获取消息RPOP queue使用发布订阅实现消息队列:
# 消费者订阅频道SUBSCRIBE channel# 生产者向频道发布消息PUBLISH channel message13.4 计数器
Redis的原子递增命令可以用于实现各种计数器。
使用示例:
# 页面访问计数INCR page:visits# 获取当前访问量GET page:visits# 设置过期时间EXPIRE page:visits8640013.5 排行榜
Redis的有序集合可以用于实现各种排行榜。
使用示例:
# 添加用户分数ZADD leaderboard100user1 ZADD leaderboard200user2 ZADD leaderboard150user3# 获取排行榜前10名ZREVRANGE leaderboard09WITHSCORES# 获取用户排名ZREVRANK leaderboard user113.6 分布式锁
Redis可以用于实现分布式锁,确保多个进程或线程在同一时间只能有一个执行特定操作。
使用示例:
importredisimporttime r=redis.Redis(host='localhost',port=6379,db=0)defacquire_lock(lock_name,expire_time=10):"""获取分布式锁"""whileTrue:# 使用SETNX命令尝试获取锁result=r.setnx(lock_name,time.time()+expire_time)ifresult:returnTrue# 检查锁是否过期current_time=time.time()lock_value=r.get(lock_name)iflock_valueandfloat(lock_value)<current_time:# 锁已过期,尝试获取锁old_value=r.getset(lock_name,current_time+expire_time)ifold_value==lock_value:returnTruetime.sleep(0.1)defrelease_lock(lock_name):"""释放分布式锁"""r.delete(lock_name)# 使用分布式锁ifacquire_lock('my_lock'):try:# 执行需要加锁的操作print("Executing critical section...")time.sleep(5)finally:# 释放锁release_lock('my_lock')14. Redis最佳实践
14.1 数据设计
- 选择合适的数据类型
- 设计合理的键名,例如:
- 使用冒号分隔命名空间和键名:
user:123:name - 键名要简洁明了,不要太长
- 避免使用特殊字符
- 使用冒号分隔命名空间和键名:
- 避免使用大键,单个键的值不要超过10MB
- 合理设置过期时间
14.2 命令使用
- 减少命令的执行次数,使用批量命令
- 避免使用O(N)复杂度的命令
- 合理使用管道(Pipeline)
- 使用Lua脚本减少网络开销
14.3 性能优化
- 设置合理的maxmemory和maxmemory-policy
- 开启慢查询日志,便于分析性能问题
- 定期监控Redis的性能指标
- 考虑使用Redis集群进行水平扩展
14.4 高可用设计
- 使用主从复制实现数据冗余
- 使用哨兵模式实现自动故障转移
- 使用Redis集群实现分布式部署
- 考虑使用多可用区部署,提高容灾能力
14.5 安全性
- 设置强密码
- 绑定特定IP
- 禁用危险命令
- 使用防火墙限制访问
- 定期更新Redis版本
15. 常见问题与解决方案
15.1 Redis连接超时
问题:客户端连接Redis超时
解决方案:
- 检查Redis服务器是否正常运行
- 检查网络连接是否正常
- 检查Redis配置的bind参数是否正确
- 检查防火墙设置是否允许Redis端口访问
- 调整Redis的timeout参数
15.2 Redis内存不足
问题:Redis内存使用率过高,出现OOM错误
解决方案:
- 增加Redis服务器的内存
- 设置合理的maxmemory和maxmemory-policy
- 清理过期键和无用数据
- 考虑使用Redis集群进行水平扩展
- 优化数据结构设计,减少内存占用
15.3 Redis持久化失败
问题:Redis持久化失败,导致数据丢失
解决方案:
- 检查磁盘空间是否充足
- 检查磁盘权限是否正确
- 调整AOF重写策略
- 考虑使用RDB + AOF的持久化方式
- 定期备份Redis数据
15.4 Redis集群节点故障
问题:Redis集群中的某个节点出现故障
解决方案:
- 检查节点的日志,找出故障原因
- 如果是硬件故障,更换硬件并重启节点
- 如果是软件故障,修复后重启节点
- 等待集群自动进行故障转移
- 如果故障转移失败,手动执行故障转移
16. 总结
Redis是一个功能强大的内存数据结构存储系统,具有高性能、高可用、支持多种数据结构等特点。
本教程详细介绍了Redis 8.4.0的安装、配置、数据类型、持久化、主从复制、哨兵模式、集群模式、事务、Lua脚本、发布订阅、内存管理、性能优化、安全配置和应用场景等内容。
通过学习本教程,读者可以全面了解Redis的各种功能和最佳实践,并能够根据实际需求选择合适的Redis架构和配置。
在实际应用中,还需要根据具体情况进行调整和优化,以充分发挥Redis的性能和可靠性。
Redis的发展非常迅速,新的版本不断推出新的功能和优化。
建议关注Redis的官方网站和社区,及时了解最新的发展动态和最佳实践。
官方网站:https://redis.io/
GitHub仓库:https://github.com/redis/redis
希望本教程有所帮助,祝大家在Redis的学习和应用中取得成功!