redis 进阶篇
一. 发布订阅(redis篇)
1. 原生操作
只要发布者一发布,订阅者都会受到消息
# 发布消息
publish <channel> <message>
# 订阅
subscribe <channel>
2. python 代码操作
2.1 发布者
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
# 发布者
pub = r.pubsub()
pub.publish('channel', 'message')
2.2 订阅者
import redis
r = redis.Redis(host='localhost', port=6379, db=0)
# 订阅者
sub = r.pubsub()
sub.subscribe('channel')
for message in sub.listen():
print(message)
二. redis 持久化方案
redis的所有数据保存在内存中,对数据的更新将异步的保存到硬盘上
1. 持久化方案实现方式
快照:rdb
日志:aof
1.1 快照:rdb (方案一)
RDB是一种快照持久化方式,它会在指定的时间间隔内将内存中的数据集快照写入磁盘。
-
优点:
-
RDB文件紧凑,适合备份和灾难恢复。
-
对于大规模数据恢复,RDB的启动速度比AOF快。
-
-
缺点:
- 可能会丢失最后一次快照后的数据,因为快照是周期性生成的。
# 配置示例
save 900 1
save 300 10
save 60 10000 # 表示如果在60秒(1分钟)内,至少有10000个键发生了变化(例如新增、修改或删除),那么Redis将触发一次RDB快照持久化操作,将当前内存中的数据集保存到磁盘上的一个RDB文件中。
1.2 日志:aof(方案二)
AOF持久化方式会记录服务器接收到的每个写操作,并在服务器启动时通过重新执行这些操作来重建数据集。
-
优点:
-
更高的数据安全性,可以配置不同的fsync策略(如每秒fsync、每次写操作fsync等)。
-
AOF文件是追加写入的,即使写入过程中出现故障,也可以通过redis-check-aof工具修复。
-
-
缺点:
-
AOF文件通常比RDB文件大。
-
对于相同的数据集,AOF文件的恢复速度可能比RDB慢
-
# 配置示例
appendonly yes:
- 这个指令用于启用AOF持久化。当设置为yes时,Redis会将每个写操作追加到AOF文件中,
从而记录下所有的写操作,以便在服务器重启时可以通过重新执行这些操作来恢复数据。
appendfsync everysec:
- 这个指令用于配置AOF文件的同步策略。appendfsync有三个可选值:
- always:每次写操作都同步到磁盘,数据安全性最高,但性能开销最大。
- everysec:每秒同步一次,数据安全性较高,性能开销适中。
- no:不同步,由操作系统决定何时同步,数据安全性最低,性能开销最小。
1.3 混合持久化 (方案三)(Redis 4.0+)
Redis 4.0引入了混合持久化模式,结合了RDB和AOF的优点。在这种模式下,AOF文件包含一个RDB格式的全量数据快照,后面是增量AOF文件。
7.x默认自动开启
# 配置示例
aof-use-rdb-preamble yes
2. AOF 重写机制
AOF重写(AOF Rewrite)是Redis中用于优化AOF文件大小和提高恢复速度的一种机制
2.1 触发方式
手动触发
127.0.0.1:6379> BGREWRITEAOF
配置文件:两个参数同时配置
# 当AOF文件大小比上次重写后的文件大小增加了100%(即翻倍)则会触发。
auto-aof-rewrite-percentage 100
# 并且当前AOF文件大小至少为64MB时,Redis会自动触发AOF重写。
auto-aof-rewrite-min-size 64mb
三. redis 主从复制
1. 原理
1. 首先从库通过 saveof <主库ip 端口>(127.0.0.1 6379)的命令,连接主库,并发送 SYNC 命令给主库。
2. 主库收到 SYNC 后,会立即触发 BGSAVE,后台保存 RDB, 并发送给副本库。
3. 副本库接收后会应用 RDB 快照。
4. 主库会陆续将中间产生的新的操作,保存并发送给副本库, 到此,就实现了主从复制。
2. 作用
做读写分离
, 做数据副本
3. 实际应用(配置主从)
3.1 命令(方式一)
# slaveof 主<ip> 主<端口>
slaveof 127.0.0.1 6379
# 断开主从复制
slaveof no one
3.2 配置文件(方式二)
# slaveof 主<ip> 主<端口>
slaveof 127.0.0.1 6379
# masterauth 主<password>, 如果主服务器设置了密码,从服务器需要配置这个密码来进行身份验证。
masterauth 123456
# 从库只读
slave-read-only yes
# 主从复制的辅助配置
# 在从服务器的数量少于2个,或者三个从服务器的延迟(lag)值都大于或等于3秒时,主服务器将拒绝执行写命令
min-slaves-to-write 2
min-slaves-max-lag 3
具体配置如下:
# 主从配置
################### 主(redis_master.conf) ###################
daemonize yes # 以守护进程方式运行
bind 0.0.0.0 # 绑定所有 IP 地址
pidfile "/var/run/redis_master.pid" # 指定 PID 文件路径
port 6379
dir "/root/redis/data" # 指定数据目录
logfile "6379.log"
protected-mode no # 关闭保护模式
requirepass "654321" # 设置访问密码
save 60 5 # 设置 RDB 持久化策略
appendonly yes # 开启 AOF 持久化
appendfilename "appendonly-6379.aof" # 指定 AOF 文件名
appendfsync everysec # 每秒执行一次 AOF 持久化
no-appendfsync-on-rewrite yes # 在 AOF 重写期间不执行 fsync
aof-use-rdb-preamble yes # 使用 RDB 作为 AOF 的前缀
masterauth '123456' # 设置主节点密码
################### 从(可以多从)(redis_slave1.conf) ###################
daemonize yes
bind 0.0.0.0
pidfile "/var/run/redis_slave.pid"
port 6380
dir "/root/redis/data"
logfile "6380.log"
protected-mode no
requirepass "654321"
save 60 5
appendonly yes
appendfilename "appendonly-6380.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
aof-use-rdb-preamble yes
masterauth '123456'
# 配置从节点连接主节点
slaveof 127.0.0.1 6379
################### 启动 ###################
# redis-server <文件名.conf>
redis-server redis_master.conf # 启动主
redis-server redis_slave1.conf # 启动从
4. 实际操作
4.1 原生操作
# 下载 redis
pip install redis
import redis
# 配置主节点连接
master_host = 'your_master_host'
master_port = 6379 # 默认端口
master_password = 'your_master_password' # 如果有密码
# 配置从节点连接
slave_host = 'your_slave_host'
slave_port = 6379 # 默认端口
slave_password = 'your_slave_password' # 如果有密码
# 连接到主节点
master_redis = redis.StrictRedis(host=master_host, port=master_port, password=master_password, decode_responses=True)
# 连接到从节点
slave_redis = redis.StrictRedis(host=slave_host, port=slave_port, password=slave_password, decode_responses=True)
# 写操作(写到主节点)
master_redis.set('key', 'value')
# 读操作(从从节点读取)
value = slave_redis.get('key')
print(f'Read value from slave: {value}')
4.2 django 操作
# 下载
pip install django-redis
# 配置
CACHES = {
"default": {
"BACKEND": "django_redis.cache.RedisCache",
"LOCATION": [
"redis://your_master_host:6379/0", # 主节点
"redis://your_slave_host:6379/0", # 从节点
],
"OPTIONS": {
"CLIENT_CLASS": "django_redis.client.DefaultClient",
# 主从密码相同
"PASSWORD": "your_redis_password", # 如果有密码
# 主从密码不同
"PASSWORD": {
"redis://your_master_host:6379/0": "master_password",
"redis://your_slave_host:6379/0": "slave_password",
}
}
}
}
# 数据操作
from django.core.cache import caches
cache.set('key', 'value') # 写操作(写到主节点)
value = cache.get('key') # 读操作(从从节点读取)
print(value)
四. 哨兵机制
1. 哨兵的原理
可以做故障判断,故障转移,通知客户端(其实是一个进程),客户端直接连接sentinel的地址
1 多个sentinel
发现并确认master
有问题
2 选举一个sentinel
作为领导
3 选取一个slave
作为新的master
4 通知其余slave成为新的master的slave
5 通知客户端主从变化
6 等待老的master复活成为新master的slave
2. 哨兵搭建
第一步:搭配 redis 主从关系, 下面是一主两从的关系
##### ##### ##### 主库 ##### ##### #####
daemonize yes
bind 0.0.0.0
pidfile "/var/run/redis.pid"
port 6379
dir "/root/redis/data"
logfile "6379.log"
protected-mode no
requirepass "654321"
save 60 5
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
aof-use-rdb-preamble yes
masterauth '123456'
##### ##### ##### 从库1 ##### ##### #####
daemonize yes
bind 0.0.0.0
pidfile "/var/run/redis.pid"
port 6380
dir "/root/redis/data"
logfile "6380.log"
protected-mode no
requirepass "654321"
save 60 5
appendonly yes
appendfilename "appendonly-6380.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
aof-use-rdb-preamble yes
slaveof 主库地址 6379
masterauth "123456"
slave-read-only yes
##### ##### ##### 从库2 ##### ##### #####
daemonize yes
bind 0.0.0.0
pidfile "/var/run/redis.pid"
port 6379
dir "/root/redis/data"
logfile "6379.log"
protected-mode no
requirepass "654321"
save 60 5
appendonly yes
appendfilename "appendonly-6379.aof"
appendfsync everysec
no-appendfsync-on-rewrite yes
aof-use-rdb-preamble yes
slaveof 主库地址 6379
masterauth "654321"
slave-read-only yes
第二步搭建哨兵
info 查看状态
##### ##### ##### 哨兵1 配置文件 ##### ##### #####
port 26379
daemonize yes
dir data
protected-mode no
bind 0.0.0.0
logfile "redis_sentinel.log"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster "654321"
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
##### ##### ##### 哨兵2 配置文件 ##### ##### #####
port 26380
daemonize yes
dir data
protected-mode no
bind 0.0.0.0
logfile "redis_sentinel.log"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster "654321"
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
##### ##### ##### 哨兵3 配置文件 ##### ##### #####
port 26381
daemonize yes
dir data
protected-mode no
bind 0.0.0.0
logfile "redis_sentinel.log"
sentinel monitor mymaster 127.0.0.1 6379 2
sentinel auth-pass mymaster "654321"
sentinel down-after-milliseconds mymaster 30000
sentinel parallel-syncs mymaster 1
sentinel failover-timeout mymaster 180000
##### ##### ##### 启动3个哨兵 ##### ##### #####
redis-sentinel ./sentinel_26379.conf
redis-sentinel ./sentinel_26380.conf
redis-sentinel ./sentinel_26381.conf
##### ##### ##### 链接哨兵 ##### ##### #####
redis-cli -p 26379