这篇文章上次修改于 365 天前,可能其部分内容已经发生变化,如有疑问可询问作者。
如何应对Redis的缓存击穿,穿透,雪崩的情况
1、缓存击穿(Cache Breakdown):
- 问题描述: 缓存中某个数据失效,而此时有大量请求同时访问这个数据,导致这些请求直接落到数据库上,造成数据库负载激增。
- 解决方案:
- 使用互斥锁或分布式锁,确保只有一个线程去查询数据库并重新写入缓存,其他线程等待获取锁。
- 在缓存失效时,使用短暂的随机时间(短暂的“过期时间波动”)来防止大量请求同时到达数据库。
2、缓存穿透(Cache Penetration):
- 问题描述: 恶意请求或者查询不存在的数据,导致每次请求都落到数据库上,对数据库造成巨大压力。
- 解决方案:
- 使用布隆过滤器等数据结构,预先将可能存在的数据哈希到一个足够大的位图中,可以快速判断请求的数据是否存在。
- 缓存空对象(缓存穿透时返回一个空对象,并设置短暂的过期时间),防止对数据库的频繁查询。
3、缓存雪崩(Cache Avalanche):
- 问题描述: 大量缓存数据在同一时间失效,导致大量请求直接落到数据库上,引起系统崩溃。
- 解决方案:
- 为缓存数据设置不同的过期时间,避免同一时间大量缓存数据失效。
- 使用缓存预热,提前加载热门数据到缓存中,确保这部分数据在同一时间不会失效。
- 使用多级缓存,将缓存数据分散到不同的缓存服务器,降低整体缓存失效的风险。
详细说一下Redis的主从复制原理
Redis的主从复制是一种数据同步机制,用于将一个Redis服务器的数据复制到其他Redis服务器,从而实现数据的备份、负载均衡和故障恢复等功能。以下是Redis主从复制的基本原理:
角色定义:
- 主服务器(Master): 拥有原始数据的服务器,负责处理写操作和推送数据给从服务器。
- 从服务器(Slave): 接收主服务器的数据,并复制保存,负责处理读操作。
初始化同步:
- 当一个从服务器连接到主服务器时,它发送一条SYNC命令请求同步。
- 主服务器接收到请求后,开始执行一个后台保存(snapshot),将整个数据集的快照保存到一个RDB文件中。
- 主服务器将RDB文件发送给从服务器,并且在发送期间,主服务器会将写命令缓存起来。
增量同步:
- 一旦初始同步完成,主服务器会继续将新的写命令缓存到内存中,并将这些写命令的操作传播给所有连接的从服务器。
- 从服务器收到写命令,会在本地执行,从而保持数据的同步。
复制流程:
- 主服务器将写命令(包括读命令,但不会影响数据)发送给所有连接的从服务器。
- 从服务器接收并执行这些写命令,保持数据同步。
- 如果一个从服务器断开连接或者重新连接,它会请求从最近一个复制偏移量处开始同步。
心跳和偏移量:
- 主服务器和从服务器之间保持心跳连接,以检测连接状态。
- 主服务器会记录每个从服务器的复制偏移量,从服务器在断开连接后重新连接时,会使用这个偏移量请求增量同步。
通过这种主从复制机制,Redis实现了数据的高可用性和故障恢复。如果主服务器宕机,可以手动或自动将一个从服务器切换为主服务器,确保系统的连续性。在生产环境中,还可以结合Redis的哨兵模式实现自动故障检测和主从切换。
详细说一下redis的哨兵模式
Redis的哨兵模式是一种用于监控和自动管理Redis主从复制和高可用性的机制。哨兵模式包括一个或多个哨兵进程,它们负责监测Redis服务器的状态,并在主服务器发生故障时自动进行故障转移。
1、哨兵角色:
- 主服务器(Master): 响应客户端请求,维护多个从服务器。
- 从服务器(Slave): 复制主服务器的数据,处理读请求。
- 哨兵(Sentinel): 用于监控主服务器和从服务器的状态,发现故障并执行故障转移。
2、哨兵配置:
- 在每个哨兵的配置文件中进行如下配置:
# 哨兵监听的端口
port 26379
# 指定监控的主服务器
sentinel monitor mymaster 127.0.0.1 6379 2
# 指定故障转移的时间间隔
sentinel down-after-milliseconds mymaster 60000
# 指定故障转移的投票数
sentinel failover-timeout mymaster 180000
# 指定密码
sentinel auth-pass mymaster your_password
3、启动哨兵
redis-sentinel /path/to/sentinel.conf
4、监控和故障转移:
- 哨兵定期检查主从服务器的状态。
- 当主服务器宕机或无法响应时,哨兵会选择一个从服务器晋升为新的主服务器。
- 哨兵将其他从服务器切换到新的主服务器,确保高可用性。
5、哨兵选举master节点机制
- 如果一个节点在down-after-milliseconds时间内没有回复Sentinel节点的心跳包,则该节点被该Sentinel节点主观下线,当节点被一个Sentinel节点记为主观下线时,并不意味着该节点肯定故障了,还需要Sentinel集群的其他Sentinel节点共同判断为主观下线才行。如果客观下线的redis节点是从节点或者是Sentinel节点,则操作到此为止,没有后续的操作了;如果客观下线的redis节点为主节点,则开始故障转移,从从节点中选举一个节点升级为主节点。
- 要从redis集群选举一个节点为主节点,首先需要从Sentinel集群中选举一个Sentinel节点作为Leader。
- 每一个Sentinel节点都可以成为Leader,当一个Sentinel节点确认redis集群的主节点主观下线后,会请求其他Sentinel节点要求将自己选举为Leader。被请求的Sentinel节点如果没有同意过其他Sentinel节点的选举请求,则同意该请求(选举票数+1),否则不同意。如果一个Sentinel节点获得的选举票数达到Leader最低票数(quorum和Sentinel节点数/2+1的最大值),则该Sentinel节点选举为Leader;否则重新进行选举。
当Sentinel集群选举出Sentinel Leader后,由Sentinel Leader从redis从节点中选择一个redis节点作为主节点:
1、先过滤故障的节点
2、选择优先级slave-priority最大的从节点作为主节点,如不存在则继续
3、选择复制偏移量(数据写入量的字节,记录写了多少数据。主服务器会把偏移量同步给从服务器,当主从的偏移量一致,则数据是完全同步)最大的从节点作为主节点,如不存在则继续
4、选择runid(redis每次启动的时候生成随机的runid作为redis的标识)最小的从节点作为主节点
详细说一下redis集群工作方式
Redis 集群是一种分布式架构,用于提供高可用性和横向扩展性。Redis 集群的工作方式如下:
1. 数据分片
- 在 Redis 集群中,数据被分成多个分片(slot)。每个分片包含一部分数据,通过哈希函数将 Key 映射到具体的分片。默认情况下,Redis 集群有 16384 个槽,每个槽对应一个分片。
2. 主从复制
- 每个分片都有一个主节点和若干个从节点。主节点负责读写操作,而从节点则复制主节点的数据。在 Redis 集群中,主从复制用于提高可用性和数据冗余。
3. Gossip 协议
- Redis 集群使用 Gossip 协议进行节点间的信息交换。每个节点都会定期向其他节点发送自己的状态信息,包括它所负责的槽、节点的健康状态等。通过 Gossip 协议,集群中的节点能够动态地了解其他节点的状态。
4. 故障检测和自动故障转移
- 当一个节点宕机时,其他节点通过 Gossip 协议感知到故障。Redis 集群使用 PFAIL 和 FAIL 两个状态来表示节点的健康状态。PFAIL 表示节点短暂不可用,而 FAIL 表示节点被判定为不可用。
- 当一个主节点被标记为 FAIL 时,集群会选择一个从节点晋升为新的主节点,以确保数据的可用性。这个过程称为自动故障转移(Automatic Failover)。
5. 客户端路由
- 客户端与 Redis 集群通信时,需要根据 Key 的哈希值将请求路由到正确的分片。Redis 集群使用哈希槽来映射 Key 到分片,客户端根据哈希槽的信息将请求发送到相应的节点。
6. 添加和移除节点
- Redis 集群支持动态添加和移除节点。当添加新节点时,集群会根据哈希槽重新分配数据,使得新节点能够负责一部分分片。移除节点时,集群会将节点上的数据迁移到其他节点上,以保持数据的平衡。
7. 节点握手
- 在节点加入或离开集群时,需要进行握手操作。新节点需要向集群中的其他节点发送握手请求,以获取集群的信息。握手操作确保节点能够正确地加入或离开集群。
通过这些机制,Redis 集群能够提供高可用性、横向扩展性和动态调整的特性。它允许在运行时动态地添加或移除节点,以适应不同的负载和故障场景。
说一下redis的数据落地机制
在Redis中,可以通过设置持久化(Persistence)机制来控制数据的落地(持久化)时间。Redis支持两种主要的持久化方式:RDB快照(Snapshotting)和AOF日志(Append-Only File)。
1、RDB快照方式:
打开Redis配置文件(通常是 redis.conf)。
找到以下配置项:
save 900 1
save 300 10
save 60 10000
这些配置项定义了在多久时间内(单位是秒)有多少次写操作时执行一次RDB快照。上述配置表示:
- 每900秒(15分钟)内,至少有1个键被修改时,执行一次快照。
- 每300秒(5分钟)内,至少有10个键被修改时,执行一次快照。
- 每60秒内,至少有10000个键被修改时,执行一次快照。
根据需要调整这些配置项。如果你希望降低数据落地的频率,可以增加时间间隔或者减少操作次数。
保存并关闭配置文件,然后重启Redis以使更改生效。
2、AOF日志方式:
打开Redis配置文件。
找到以下配置项:
appendonly no
将no 改成yes
3、通过以下配置项设置AOF的持久化方式:
appendfsync everysec
这表示每秒将AOF缓冲区的内容同步到磁盘一次。你也可以选择其他选项,如 always(每次有写操作时同步) 或 no(完全依赖操作系统)。
4、保存并关闭配置文件,然后重启Redis。
redis 是如何保证incr 操作是原子性的
单线程执行: Redis 主进程是单线程执行的,每个命令都会按照顺序依次执行,不会被其他命令打断。
事务队列: Redis 使用一个事务队列,将所有的命令请求按顺序排队。在执行命令时,Redis 会锁住整个事务队列,确保每个命令的执行不会被其他线程插入。
没有评论
博主关闭了评论...