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
posted @ 2024-07-03 09:47  codegjj  阅读(3)  评论(0编辑  收藏  举报