Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩

目录

 

Redis 配置

Redis持久化

RDB(Redis DataBase)

AOF(Append Only File)

Redis发布订阅

Redis 发布订阅命令

Redis 主从复制

Redis集群环境配置

复制原理

哨兵模式

Redis缓存穿透、缓存击穿和缓存雪崩

缓存穿透

缓存击穿

缓存雪崩


 学习参考: 【狂神说Java】Redis最新超详细版教程通俗易懂


 

Redis 配置

Redis 的配置文件位于 Redis 安装目录下,文件名为 redis.conf(Windows 名为 redis.windows.conf。

redis.conf分为一些模块,我们将通过这些模块来解释Redis的配置

  • 配置文件 unit单位 对大小写不敏感
# Redis configuration file example
# 当需要需要内存大小的时候 可以指定内存大小 
# Note on units: when memory size is needed, it is possible to specify
# 它通常的形式是1k 5GB 4M等等
# it in the usual form of 1k 5GB 4M and so forth:
#
# 1k => 1000 bytes
# 1kb => 1024 bytes
# 1m => 1000000 bytes
# 1mb => 1024*1024 bytes
# 1g => 1000000000 bytes
# 1gb => 1024*1024*1024 bytes
#
# units 单位对大小写不敏感
# units are case insensitive so 1GB 1Gb 1gB are all the same.
  • INCLUDES
    • 可以包含其他的配置文件,可以把其他的配置文件都配置进Redis
#  指定包含其它的配置文件,可以在同一主机上多个Redis实例之间使用同一份配置文件,而同时各个实例又拥有自己的特定配置文件
 include .\path\to\local.conf
 include c:\path\to\other.conf
  • NETWORK
# 绑定的主机地址
bind 127.0.0.1
# 保护模式
protected-mode
# 端口设置
port 6379
  •  GENERAL
# Redis 默认不是以守护进程的方式运行,可以通过该配置项修改,使用 yes 启用守护进程
# 否则一退出进程就结束了
# Windows的配置文件没有这一项
deamonize yes

# 当 Redis 以守护进程方式运行时,Redis 默认会把 pid 写入 /var/run/redis.pid 文件,可以通过 pidfile 指定 
pidfile /var/run/redis.pid

# 指定日志记录级别,Redis 总共支持四个级别:debug、verbose、notice、warning,默认为 notice 
loglevel notice

# 日志记录方式,默认为标准输出,如果配置 Redis 为守护进程方式运行,而这里又配置为日志记录方式为标准输出,则日志将会发送给 /dev/null 
logfile ""

# 默认数据库的数量
databases 16
  • SNAPSHOTTING
# 指定在多长时间内,有多少次更新操作,就将数据同步到数据文件,可以多个条件配合 
# 分别表示 900 秒(15 分钟)内有 1 个更改,300 秒(5 分钟)内有 10 个更改以及 60 秒内有 10000 个更改
save 900 1
save 300 10
save 60 10000

# 持久化如果出错,是否还需要继续工作
stop-writes-on-bgsave-error yes
# 是否压缩rdb文件,需要消耗一些cpu资源
rdbcompression yes
# 保存rdb文件的时候 进行一些校验
rdbchecksum yes

# rdb文件保存的目录 
dir ./
  • REPLICATION  复制 在后面讲主从复制的时候再讲解
  • SECURITY 
# Redis密码设置 默认没有密码 可以通过命令设置 :config set  requirepass '123456'
requirepass foobared
  • LIMITS
# Redis 最大客户端的数量
 maxclients 10000
# Redis 配置最大的内容容量
 maxmemory 
# 内存达到上限之后的处理策略
 maxmemory-policy noeviction
  • APPEND ONLY MODE aof配置
# 默认是不开启aof模式的,默认是rdb方式持久化,在大部分的情况下,rdb完全够用
appendonly no 
# 持久化文件名字 
appendfilename "appendonly.aof"

# 每次修改都会同步 消耗性能
appendfsync always
# 每秒执行一次同步 可能会丢失这1s的数据
appendfsync everysec
# 不执行同步 
appendfsync no

Redis持久化

Redis是内存数据库,如果不将内存中的数据状态保存到硬盘,那么一旦服务进程退出,服务器中的数据库状态也会消失。所以Redis也提供了持久化功能。

RDB(Redis DataBase)

什么是RDB?

在指定的时间间隔将内存中的数据集快照写入磁盘,也就是Snapshot(快照),它恢复时是将快照文件直接读取到内存里。

Redis会单独创建fork一个子进程来持久化,会将数据写入到一个临时文件中,待持久化过程都结束了,再用这个临时文件替换上次持久化好的文件。整个过程中,主进程是不进行任何IO操作的。这就确保了极高的性能。如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。RDB的缺点最后一次持久化后的数据可能会丢失

RDB保存的文件是 dump.rdb,可以在配置文件中进行配置。

在Redis配置的时候,SNAPSHOTTING模块,可以自己定义在多少秒内,进行多少次更新操作。

我们来试试修改配置文件中的这个部分,让60s内修改文件五次,就触发rdb操作。

目前在Redis文件夹下,就有一个dump.rdb,现在可以删掉它来查看我们的修改后的触发rdb的操作是否可以执行。

 五次 修改操作

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK
127.0.0.1:6379> set k5 v5
OK
127.0.0.1:6379> set k4 v4
OK

新生成的rdb文件

 触发机制:

  • save的规则满足的情况下,会自动触发rdb规则
  • 执行flushall命令,也会触发rdb规则
  • 推出redis,也会产生rdb文件

如何恢复rdb文件?

  • 只需要把rdb文件放在redis启动目录就可以,redis启动的时候就会自动检查dump.rdb恢复其中的数据。
  • 查看需要存放的位置
# 如果在这个目录下存在dump.rdb文件,启动就会自动恢复其中的数据
127.0.0.1:6379> config get dir
1) "dir"
2) "D:\\Enviroment\\Redis-x64-3.2.100"

RDB的优点:

  • 适合大规模的数据恢复,dump.rdb
  • 如果对数据完整性不高,那么可以使用rdb(因为rdb可能会在最后一秒宕机,那么数据就无法保存下来,比如在60秒以内 5次修改操作,在59秒的时候宕机,那么就数据就可能丢失。)

RDB的缺点:

  • 需要一定的时间间隔操作,如果Redis意外宕机,最后一次修改数据就没有了。
  • fork进程的时候,会占用一定的内存空间

一般来说,RDB的文件配置其实完全够用,不需要特别的更改。

AOF(Append Only File)

将我们所有的命令都记录下来。

以日志的形式来记录每个写操作,将Redis执行过的所有指令记录下来(读操作不记录),只许追加文件但不可以改写文件,redis启动之初会读取该文件重新构建数据。换言之,Redis重启的话就根据日志文件的内容将写指令从前到后执行一次完成数据的恢复工作。

AOF 保存的是 appendonly.aof 文件

在Redis配置的时候,简单的讲了讲 APPEND ONLY MODE,默认情况下是不开启的,需要手动进行配置,把appendonly 改为yes就开启了aof

# aof模式默认是没有开启的,需要手动进行配置为yes开启
appendonly yes

# aof
appendfilename "appendonly.aof"

# rewirte 重写

# 如果aof文件大于64m,那么就太大,会触发重写机制.aof默认文件就是无限追加,文件就会越来越大.
auto-aof-rewrite-percentage 100
auto-aof-rewrite-min-size 64mb

重启以后,aof就生效了,可以看到Redis启动目录下多了一个appendonly.aof文件。

现在我们来set三个数据试试

127.0.0.1:6379> set k1 v1
OK
127.0.0.1:6379> set k2 v2
OK
127.0.0.1:6379> set k3 v3
OK

接着我们打开appendonly.aof ,可以看到它把我们的操作命令都记录了下来。

*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*3
$3
set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
v3

 如果aof文件有错误,redis是无法启动起来的。

现在试着在appenonly.aof文件中乱加入一些字符,来破坏aof文件,保存以后再启动redis。

*2
$6
SELECT
$1
0
*3
$3
set
$2
k1
$2
v1
*3
$3
set
$2
k2
$2
v2
*3
$3
set
$2
k3
$2
v3
I wiill destory you!!!!!!!!!aof!

启动redis显示错误

那么这个时候该如何去处理呢?redis给我们提供了一个工具 :redis-check-aof --fix

在Windowns下,使用cmd打开 redis-check-aof.exe ,然后输入:redis-check-aof --fix appendonly.aof 即可完成修复

# cmd 命令下打开 redis-check-aof.exe
D:\Enviroment\Redis-x64-3.2.100>redis-check-aof.exe
# 提示使用  redis-check-aof.exe [--fix]  命令
Usage: redis-check-aof.exe [--fix] 

# 输入修复命令
D:\Enviroment\Redis-x64-3.2.100>redis-check-aof --fix appendonly.aof
0x              6e: Expected prefix 'I', got: '*'
AOF analyzed: size=142, ok_up_to=110, diff=32
This will shrink the AOF from 142 bytes, with 32 bytes, to 110 bytes
# 确定是否修复
Continue? [y/N]: y
# 成功修复
Successfully truncated AOF

这个时候再打开appendonly.aof可以看到刚刚乱输入的符号已经没有了,并且redis也能够重启成功。

AOF的优点:

  • 每一次修改都同步,文件的完整性会更加的好
  • 每秒同步一次,可能会丢失一秒的数据
  • 从不同步,效率是最高的

AOF的缺点:

  • 相对于数据文件来说,AOF远远大于RDB,修复的速度也比RDB慢。
  • AOF运行效率也要比RDB慢,所以Redis默认的配置是RDB持久化

Redis发布订阅

Redis 发布订阅(pub/sub)是一种消息通信模式:发送者(pub)发送消息,订阅者(sub)接收消息。

Redis 客户端可以订阅任意数量的频道。

下图展示了频道 channel1 , 以及订阅这个频道的三个客户端 —— client2 、 client5 和 client1 之间的关系:

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第1张图片

当有新消息通过 PUBLISH 命令发送给频道 channel1 时, 这个消息就会被发送给订阅它的三个客户端:

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第2张图片

Redis 发布订阅命令

序号 命令及描述
1 PSUBSCRIBE pattern [pattern ...]
订阅一个或多个符合给定模式的频道。
2 PUBSUB subcommand [argument [argument ...]]
查看订阅与发布系统状态。
3 PUBLISH channel message
将信息发送到指定的频道。
4 PUNSUBSCRIBE [pattern [pattern ...]]
退订所有给定模式的频道。
5 SUBSCRIBE channel [channel ...]
订阅给定的一个或多个频道的信息。
6 UNSUBSCRIBE [channel [channel ...]]
指退订给定的频道。

实例(一)测试订阅消息、发布消息、接受消息

订阅端

# 订阅一个频道
127.0.0.1:6379> subscribe clawsFM
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "clawsFM"
3) (integer) 1

发布端

# 消息发布 clawFM发布一条hello
127.0.0.1:6379> publish clawsFM 'hello'
(integer) 1

推送以后的订阅端

# 订阅一个频道 
127.0.0.1:6379> subscribe clawsFM
Reading messages... (press Ctrl-C to quit)
1) "subscribe"
2) "clawsFM"
3) (integer) 1
# 等待读取推送的消息
# 消息
1) "message"
# 这个 消息来自 clawsFM
2) "clawsFM"
# 消息内容
3) "hello"

Redis 主从复制

概念

主从复制,是将一台Redis服务器的数据,复制到其他Redis服务器。前者称为主节点(master、leader),后者称为从节点(slave/follwer),数据的复制是单向的只能由主节点到从节点Master以写为主,Slave以读为主。

默认情况下,每台Redis服务器都是主节点;且一个主节点可以有多个从节点(或没有从节点),但一个节点只能有一个主节点。

主从复制的作用:

  • 数据冗余:主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式
  • 故障恢复:当主节点出现问题时,可以由从节点提供服务,实现快速故障恢复,实际上是一种服务的冗余
  • 负载均衡:在主从复制的基础上,配合读写分离,可以由主节点提供写的服务,由从从节点提供读服务(即写Redis数据时应用连接主节点,读Redis数据时应用连接从节点)分担服务器负载;尤其是在写少读多的场景下,通过多个节点分担读负载,可以大大提高Redis服务器的并发量
  • 高可用基石;除了上述作用以外,主从复制还是哨兵和集群能够实施的基础,因此说主从复制是Redis高可用的基础

一般来说,要将Redis运用于工程项目中,只使用一台Redis是万万不能的

  • 从结构上,单个Redis服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大
  • 从容量上,单个Redis服务器内存容量有限,就算一台Redis服务器内存容量为256G,也不能将所有内存作用Redis存储内存,一般来说,单台Redis最大使用内存不应该超过20G

电商网站上的商品,一般都是一次上传,无数次浏览,也是多读少写的情况。

主从复制,读写分离,80%都是在进行读操作,这是为了减缓服务器的压力。

一般来说,主从分离的最低配置是一主两从,在实际开发中,主从复制是必须要使用的,因为真实的项目不可能是单机。

Redis集群环境配置

我们只需要配置从库就好了,不用配置主库,因为Redis本身就是主节点。

 使用info replication 查看当前库的信息,可以看到当前库的角色是master 以及 connected_slaves:0 为0,也就是说没有从机。

#  info replication 查看当前库的信息
127.0.0.1:6379> info replication
# Replication
# 角色
role:master
# 0 :没有从机
connected_slaves:0
master_replid:0a1a6b7a7a4a21aa8d0dbcf182600f3898c0ad35
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

 复制三个配置文件,修改对应的信息

# 进入配置文件目录
[root@clawsServer bin]# cd /usr/local/bin/cconfig
[root@clawsServer cconfig]# ls
redis.conf
# 将配置文件复制三份 以端口号区分开来
[root@clawsServer cconfig]# cp redis.conf redis-6379.conf
[root@clawsServer cconfig]# cp redis.conf redis-6380.conf
[root@clawsServer cconfig]# cp redis.conf redis-6381.conf
[root@clawsServer cconfig]# ls
redis-6379.conf  redis-6380.conf  redis-6381.conf  redis.conf
  • 端口号

  • pid名字

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第3张图片

  • log文件名字

  • dump.rdb

修改完毕后接下来开启3个服务器,连接redis服务

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第4张图片

[root@clawsServer bin]# redis-server cconfig/redis-6380.conf 
[root@clawsServer bin]# redis-server cconfig/redis-6382.conf 
redis-server cconfig/redis-6382.conf 

 使用 ps -ef|grep redis 命令可以看到当前有三个redis进程了。

但是在每台服务器上,使用info replication命令可以发现每台服务器它的角色都是master。当然redis服务器本身就是一个master,所以我们要进行配置。

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第5张图片

该如何配置主从关系呢?只需要配置从机即可,让从机去认某一台服务器是它的master。

在一台从机的Redis服务器上使用 SLAVEOF 命令,现在我们让6379端口号为master,所以我们让6380和6382这两台服务器使用此命令来配置自己的主机。

6380服务器

6380服务器的主从复制状态:

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第6张图片

6382服务器

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第7张图片

6382主从复制状态:

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第8张图片

此时再使用查看6379服务器,可以看到已经连接上了两台从机了。

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第9张图片

 真实的主从配置应该是在配置文件中配置,这样的话是永久的。现在我们使用的命令,这是暂时的。

那么如何在配置文件中配置呢?

打开从机的配置文件,replicaof <主机ip> <主机端口>,这样配置以后,从机启动以后就是从机了。

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第10张图片

主从配置细节:

主机负责写,从机负责读。主机中的所有信息和数据都会自动被从机保存。

实例(一):测试主机写数据和从机写入数据

主机写入数据成功

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第11张图片

从机写入数据失败

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第12张图片

实例(二):主机断开连接,从机依旧连接到主机,但是没有写操作,这个时候主机如果回来了,从机依旧可以获取到主机写的信息。

现在关闭master 6379服务器

# 关闭6379服务器
127.0.0.1:6379> SHUTDOWN
not connected> exit

可以看到6379的进程已经没有了

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第13张图片

在6380服务器上获取keys

# 在主机断开情况下,查看主从复制信息仍然看到从机6380的主机为6379,这个并没有发生改变。
127.0.0.1:6380> info replication
# Replication
role:slave
master_host:127.0.0.1
master_port:6379
master_link_status:down
master_last_io_seconds_ago:-1
master_sync_in_progress:0
slave_repl_offset:3062
master_link_down_since_seconds:599
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:306567a1b3c8a3f9d773ac16b827438c95ca53b9
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:3062
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:43
repl_backlog_histlen:3020
# 获取keys 可以获取到
127.0.0.1:6380> keys *
1) "k1"

再使6379连接回来

[root@clawsServer bin]# redis-server cconfig/redis-6379.conf 
[root@clawsServer bin]# redis-cli
127.0.0.1:6379> set k3 v3
OK

在6382上获取k3

127.0.0.1:6382> get k3
"v3"

实例(三)从机断开连接

现在让6380服务断开连接。

# 断开6380的连接
127.0.0.1:6380> shutdown
not connected> exit

查看当前进程,6380进程已终止

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第14张图片

在主机上写入数据

# 查看当前主从复制信息
127.0.0.1:6379> info replication
# Replication
role:master
# 只有一台服务器在连接了
connected_slaves:1
slave0:ip=127.0.0.1,port=6382,state=online,offset=1593,lag=0
master_replid:9f3fb66306e4aad2e414cd5749ec90ec3f415687
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:1593
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:1593
# set k5
127.0.0.1:6379> set k5 v5
OK

此时恢复6380服务器的连接,获取k5的值为空。此时查看主从复制的信息,发现6380变成主机了,这是因为我们一开始配置主从信息的时候使用的是命令行,如果重启了,就会变成主机。

# 重连6380服务
[root@clawsServer bin]# redis-server cconfig/redis-6380.conf 
# 启动6380 redis-cli 
[root@clawsServer bin]# redis-cli -p 6380
# 获取k5的值
127.0.0.1:6380> get k5
# 获得的值为空
(nil)
# 查看主从复制信息,因为一开始使用命令slaveof,在关机后重启就失效了,现在6380自己就是主机了.
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:0
master_replid:a805c95322fb18050642304b6c95ea1afc180a9b
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:0
second_repl_offset:-1
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0

重新配置主从信息,变成从机以后,它得到了k5的值。

# 重新配置主从信息
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
# 获取到了k5的值
127.0.0.1:6380> get k5
"v5"

复制原理

Slave 启动成功后连接到master后会发送一个sync同步命令

Master接到命令后,启动后台的存盘进程,同时收集所有接受到用于修改数据命令集,在后台进程执行完毕后,master将传送整个数据文件到slave,并完成一次完全同步。

全量复制:而slave服务在接受到数据库文件数据后,将其存盘并加载到内存中

增量复制:Master继续将新的收集到的修改命令依次传递给slave,完成同步 (比如现在在主机写入数据,马上在从机获取,这是增量复制做到的)

但是只要重新连接到master,一次完全同步(全量复制)将被自动执行,我们的数据一定可以在从机中得到

另外一种主从复制模式

刚刚我们的主从复制的思想是一主两从

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第15张图片

另外一种主从复制模式,层层链路模式,第二个服务器即是从机,也是主机。

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第16张图片

我们让服务器实现这种主从复制思想

6379仍然为我们的主服务器,6380为6379的从机,6382为6380的从机。

修改6382主机为6380

127.0.0.1:6382> slaveof 127.0.0.1 6380
OK

此时查看三个服务器各自的主从复制信息

6379:

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第17张图片

可以看到6380依旧为从节点

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第18张图片

6382

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第19张图片

如果这个模式下主机宕机了怎么办?

如果主机宕机了,我们可以使用slaveof  no one 使用这个命令的服务器变为主机,其他节点就可以手动连接到最新的主节点

使6379宕机

 此时剩下两台服务器的配置信息

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第20张图片

在6380服务器上使用 slaveof no one 命令,再查看主从信息可以看到6380变为主机了

127.0.0.1:6380> slaveof no one
OK
127.0.0.1:6380> info replication
# Replication
role:master
connected_slaves:1
slave0:ip=127.0.0.1,port=6382,state=online,offset=1358,lag=1
master_replid:f3718d07ec13c91cc18f0f13bb78825bcae7a014
master_replid2:79968b80f750f53df091e90e867372ace9b592eb
master_repl_offset:1358
second_repl_offset:1317
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:29
repl_backlog_histlen:1330

 如果这个时候6379恢复连接,那么它也不再是主机了,需要重新配置为主机。

哨兵模式

它能够后台监控主机是否故障,如果故障了根据投票数自动将从库转换为主库。

哨兵模式是一种特殊模式,首先Redis提供了哨兵的命令,哨兵是一个独立进程,作为进程,他会独立运行,其原理是哨兵通过发送命令,等待Redis服务响应,从而监控运行的多个Redis实例。

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第21张图片

这里的哨兵有两个作用

  • 通过发送命令,让Redis服务器返回监控其运行状态,包括主服务器和从服务器
  • 当哨兵检测到master宕机,会自动将slave切换成master,然后通过发布订阅模式通知其他的从服务器,修改配置文件,让他们切换主机

然而一个哨兵进程对Redis服务进行监控,可能会出现问题,如果哨兵进程也终止了怎么办?为此我们可以使用多个哨兵进行监控。各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第22张图片

假设主服务器宕机,哨兵1先检测到这个结果,系统并不会马上进行failover过程,仅仅是哨兵1主观的认为主服务器不可用。这个现象成为主观下线。当后面的哨兵也检测到主服务器不可用,并且当数量达到一定值时,那么哨兵之间就会进行一次投票,投票结果由一个哨兵发起,进行failover[故障转移]操作,切换成功后,就会通过发布订阅模式,让各个哨兵把之间监控的从服务器实现切换主机,这个过程称为客观下线。

实例(一):测试哨兵模式

  • 配置哨兵配置文件,sentinel.conf
sentinel monitor myredis 127.0.0.1 6379 1
  • 指定,sentinel.conf 启动reids-sentinel

端口号后面这个数字1,代表主机宕机,slave投票看让谁接替成为主机

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第23张图片

现在的主从复制模式仍然是一主二从,让6379宕机。

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第24张图片

在哨兵的进程中看到已经选举6382为master

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第25张图片

6382主从复制信息

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第26张图片

如果现在6379连接回来了,它会变为从机。

Redis(三):Redis配置、持久化、发布订阅、主从配置、缓存穿透和雪崩_第27张图片

哨兵模式的优点

  • 哨兵集群,基于主从复制,所有的主从配置优点它都有
  • 主从可以切换,故障可以转移,系统的可用性就会更好
  • 哨兵模式就是主从模式的升级,手动到自动,更加健壮

哨兵模式的优点

  • Redis不好在线扩容的,集群一旦达到上限,在线扩容就会很麻烦
  • 实现哨兵模式的配置其实是很麻烦的,里面有很多选择

Redis缓存穿透、缓存击穿和缓存雪崩

参考: REDIS缓存穿透,缓存击穿,缓存雪崩原因+解决方案

缓存穿透

概念

key对应的数据在数据源并不存在,每次针对于此key的请求从缓存获取不到,请求都会到数据源,从而会压垮数据源。比如用一个不存在的id获取用户信息,不论缓存和数据库都没有,若黑客利用此漏洞进行攻击有可能压垮数据库。

如果出现了这种问题,有两种解决方案:布隆过滤器和缓存空对象。

布隆过滤器:将所有可能存在的数据hash到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层数据存储系统的查询压力

缓存空对象:如果一个查询返回的数据为空,我们仍会把这个空结果进行缓存,但是他的过期时间很短。

缓存击穿

一个key非常的热点,在不停的扛着大并发,大并发集中对这个点进行访问,当这个key在失效的瞬间,持续的大并发就会穿破缓存,直接请求数据库,就像在一个屏障上凿开一个洞。

当某个key在过期的瞬间,有大量请求并发访问,这类数据一般是热点数据,由于缓存过期,会同时访问数据库来查询数据,并写回缓存,会导致数据库压力瞬间压力过大。

解决方案:

设置热点数据永不过期

从缓存层面来看,没有设置过期时间,所以不会出现热点key过期后产生的问题

加互斥锁

分布式锁:使用分布式锁,保证对于每个key同时只有一个线程去查询后端服务,其他线程没有获得分布式锁的权限,因此只需要等待即可。这种方式将高并发的压力转移到分布式锁,因此对分布式锁考研很大。

缓存雪崩

缓存雪崩,是指在某一个时间段,缓存集中过期失效,Redis宕机。

产生雪崩的原因之一,比如双十一的一点,很快会迎来一波抢购,这波商品都放入了缓存,假设缓存时间一个小时对于数据库而言,会产生周期性的压力波峰,于是所有的请求都会到达存储层,存储层的调用量会暴增,造成存储层也挂掉情况。

其实集中过期倒不是非常致命的,比较致命的是缓存雪崩,是缓存服务器某个节点宕机或断网。因为自然形成的缓存雪崩,一定是在某个时间段集中创建缓存,这个时候数据库也是可以顶住压力的,无非就是对于数据库产生的周期性压力而已,而缓存服务节点宕机,对于数据库服务器造成的压力是不可预知的。很有可能瞬间把数据库压垮。

解决方案

redis高可用

这个思想的含义是,既然redis有可能挂掉,那么多设几台redis,这样一台挂掉以后其他还可以继续工作,其实就是搭建集群

限流降级

这个解决方案的思想是,在缓存失效后,通过加锁或者队列来控制数据库读写的线程数量,比如对某个key值只允许一个线程的查询和写缓存,其他线程等待

数据预热

将数据预热的含义是在正式部署之前,我先把可能的数据先预先访问一遍,这样部分可能大量访问的数据就会加载到缓存中,在即将发生大并发访问前手动触发加载缓存不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

 

 

 

 

你可能感兴趣的:(Redis)