当前位置: 首页 > news >正文

Redis学习(四)——主从复制、哨兵模式、缓存击穿、穿透、雪崩

文章目录

  • 1. 主从复制
    • 1.1 概述
    • 1.2 作用
  • 2. 哨兵模式
  • 3. 缓存穿透
    • 3.1 描述
    • 3.2 解决方案
  • 4. 缓存击穿
    • 4.1 描述
    • 4.2 解决方案
  • 5. 缓存雪崩
    • 5.1 描述
    • 5.2 解决方案

1. 主从复制

1.1 概述

主从复制,是指将一台 Redis 服务器的数据,复制到其他的 Redis 服务器。前者称为主节点(master / leader),后者称为从节点(slave / follower)。数据的复制是单向的,只能由主节点到从节点。Master 以写为主,Slave 以读为主。一个主节点可以有多个从节点(或没有从节点),但一个从节点只能有一个主节点。默认情况下,每台 Redis 服务器都是主节点。

1.2 作用

  1. 数据冗余
    主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式。

  2. 故障恢复
    当主节点出现问题时,可以由从节点提供服务,实现快速的故障恢复。这也是一种服务的冗余。

  3. 负载均衡
    在主从复制的基础上,配合读写分离,可以由主节点提供写服务,由从节点提供读服务,分担服务器负载。尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高 Redis 服务器的并发量。

  4. 高可用
    主从复制是哨兵和集群能够实施的基础,因此说主从复制是 Redis 高可用的基础。
    一般来说,要将 Redis 运用于工程项目中,只使用一台 Redis 是万万不能的,原因如下:
    结构上:单个 Redis 服务器会发生单点故障,并且一台服务器需要处理所有的请求负载,压力较大。
    容量上:单个 Redis 服务器内存容量有限,一般来说,单台 Redis 最大使用内存不应该超过 20G。

2. 哨兵模式

主从切换技术的操作是:当主机宕机后,需要手动把一台从机切换为主机。这就需要人工干预,费事费力,还会造成一段时间内服务不可用。

这不是一种推荐的方式,更多时候,我们优先考虑哨兵模式。Redis 从 2.8 开始正式提供了 Sentinel(哨兵) 架构来解决这个问题。它能够后台监控主机是否故障,如果故障了根据投票数自动将从机转换为主机。

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

这里的哨兵有两个作用:

  1. 通过发送命令,让 Redis 服务器返回监控其运行状态,包括主机和从机。

  2. 当哨兵监测到 master 宕机,会自动将 slave 切换成 master,然后通过发布订阅模式通知其他的从机,修改配置文件,让它们切换主机。

然而一个哨兵进程对 Redis 服务器进行监控,可能会出现问题,为此,我们可以使用多个哨兵进行监控。

各个哨兵之间还会进行监控,这样就形成了多哨兵模式。

假设主机宕机,哨兵 1 先检测到这个结果,系统并不会马上进行 failover(故障转移) 过程,仅仅是哨兵 1 主观的认为主机不可用,这个现象称为主观下线。

当后面的哨兵也检测到主机不可用,并且数量达到一定值时,哨兵之间就会进行一次投票,投票的结果由一个哨兵发起,进行 failover 操作。

切换成功后,就会通过发布订阅模式,让各个哨兵把自己监控的从机实现切换主机,这个过程称为客观下线。

3. 缓存穿透

3.1 描述

Redis 缓存的使用,极大的提升了应用程序的性能和效率,特别是数据查询方面。但同时,它也带来了一些问题。其中,最要害的问题,就是数据的一致性问题,从严格意义上讲,这个问题无解。如果对数据的一致性要求很高,那么就不能使用缓存。

一般的使用缓存的系统逻辑如下:

  1. 查询一个数据,先到缓存中查询。

  2. 如果缓存中存在,则返回。

  3. 如果缓存中不存在,则到数据库查询。

  4. 如果数据库中存在,则返回数据,且存到缓存。

  5. 如果数据库中不存在,则返回空值。

缓存穿透出现的情况就是数据库和缓存中都没有。这样缓存就不能拦截,数据库中查不到值也就不能存到缓存。这样每次这样查询都会到数据库,相当于直达了,即穿透。这样会给数据库造成很大的压力。

3.2 解决方案

  1. 布隆过滤器
    布隆过滤器是一种数据结构,对所有可能查询的参数以 hash 形式存储,在控制层先进行校验,不符合则丢弃,从而避免了对底层存储系统的查询压力。
  2. 缓存空对象
    当存储层不命中后,即使返回的空对象也将其缓存起来,同时会设置一个过期时间,之后再访问这个数据将会从缓存中获取,保护了后端数据源。

4. 缓存击穿

4.1 描述

缓存击穿,是指一个 key 非常热点,在不停的扛着大并发,大并发集中对这一个点进行访问。当这个 key 在失效的瞬间,持续的大并发就穿破缓存,直接请求数据库,就像在一个屏障上凿开了一个洞。当某个 key 在过期的瞬间,有大量的请求并发访问,这类数据一般是热点数据。由于缓存过期,会同时访问数据库来查询最新数据,并且回写缓存,会导使数据库瞬间压力过大。

4.2 解决方案

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

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

5. 缓存雪崩

5.1 描述

缓存雪崩,是指在某一个时间段,缓存集中过期失效。产生雪崩的原因之一,比如马上就要到双十一零点,很快就会迎来一波抢购。这波商品时间比较集中的放入了缓存,假设缓存一个小时。那么到了凌晨一点钟的时候,这批商品的缓存就都过期了。而对这批商品的访问查询,都落到了数据库上,对于数据库而言,就会产生周期性的压力波峰。于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会挂掉的情况。缓存服务节点的宕机,对数据库服务器造成的压力是不可预知的,很有可能瞬间就把数据库压垮。

5.2 解决方案

  1. 搭建集群
    实现 Redis 的高可用,既然一台服务有可能挂掉,那就多增设几台服务。这样一台挂掉之后其他的还可以继续工作,其实就是搭建的集群。

  2. 限流降级
    在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个 key 只允许一个线程查询数据和写缓存,其他线程等待。

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

相关文章:

  • C++语法——详细剖析类成员函数在内存中存储形式(包括静态)
  • 解决gitlab太占内存问题
  • 基于神经网络的传递函数控制器matlab实现,神经网络自己编程实现不使用matlab的工具箱
  • 超声波测距(避障)材质检测
  • GPIO 模拟SPI
  • 【云原生 · Kubernetes】Taint和Toleration(污点和容忍)
  • 10.20复习
  • 自动化测试项目实战笔记(三):测试用户注册(验证码错误,成功,出现弹框时处理)
  • Pygame实战(一):随机抽位置
  • vue支付项目-APP微信支付功能
  • 新手如何自学python?
  • Java的日期与时间之java.time.ZonedDateTime简介说明
  • Vue整合Markdown组件+SpringBoot文件上传+代码差异对比
  • MySQL高级篇——索引简介
  • C-内存函数(大量图解,函数实现)
  • [分享]iOS开发-关于在xcode中引用文件夹右边出现问号的解决办法
  • 2019.2.20 c++ 知识梳理
  • css选择器
  • docker容器内的网络抓包
  • Flex布局到底解决了什么问题
  • JAVA SE 6 GC调优笔记
  • Linux gpio口使用方法
  • Python socket服务器端、客户端传送信息
  • Xmanager 远程桌面 CentOS 7
  • 成为一名优秀的Developer的书单
  • 纯 javascript 半自动式下滑一定高度,导航栏固定
  • 二维平面内的碰撞检测【一】
  • 回流、重绘及其优化
  • 前端每日实战:70# 视频演示如何用纯 CSS 创作一只徘徊的果冻怪兽
  • 适配iPhoneX、iPhoneXs、iPhoneXs Max、iPhoneXr 屏幕尺寸及安全区域
  • 通过npm或yarn自动生成vue组件
  • 字符串匹配基础上
  • 阿里云重庆大学大数据训练营落地分享
  • 微龛半导体获数千万Pre-A轮融资,投资方为国中创投 ...
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • # 睡眠3秒_床上这样睡觉的人,睡眠质量多半不好
  • ## 临床数据 两两比较 加显著性boxplot加显著性
  • ###项目技术发展史
  • #vue3 实现前端下载excel文件模板功能
  • $.type 怎么精确判断对象类型的 --(源码学习2)
  • (20050108)又读《平凡的世界》
  • (8)STL算法之替换
  • (java版)排序算法----【冒泡,选择,插入,希尔,快速排序,归并排序,基数排序】超详细~~
  • (论文阅读26/100)Weakly-supervised learning with convolutional neural networks
  • (篇九)MySQL常用内置函数
  • (强烈推荐)移动端音视频从零到上手(上)
  • (三十五)大数据实战——Superset可视化平台搭建
  • (四)图像的%2线性拉伸
  • (学习日记)2024.01.09
  • (一)python发送HTTP 请求的两种方式(get和post )
  • (转)nsfocus-绿盟科技笔试题目
  • (转)从零实现3D图像引擎:(8)参数化直线与3D平面函数库
  • (转)利用PHP的debug_backtrace函数,实现PHP文件权限管理、动态加载 【反射】...
  • ***测试-HTTP方法
  • ***微信公众号支付+微信H5支付+微信扫码支付+小程序支付+APP微信支付解决方案总结...