redis终章

1. 缓存(cache)

        Redis最主要的用途,三个方面1.存储数据(内存数据库);2.缓存[redis最常用的场景];3.消息队列。

        缓存(cache)是计算机中的⼀个经典的概念.核⼼思路就是把⼀些常⽤的数据放到触⼿可及(访问速度更快)的地⽅,⽅便随时读取.

        对于硬件的访问速度来说,通常情况下: CPU寄存器>内存>硬盘>⽹络,速度快的设备,可以作为速度慢的设备的缓存。

1.1 使用redis作为缓存

为什么说关系型数据库性能不⾼?

        1. 数据库把数据存储在硬盘上,硬盘的IO速度并不快.尤其是随机访问.

        2. 如果查询不能命中索引,就需要进⾏表的遍历,这就会⼤⼤增加硬盘IO次数.

        3. 关系型数据库对于SQL的执⾏会做⼀系列的解析,校验,优化⼯作.

        4. 如果是⼀些复杂查询,⽐如联合查询,需要进⾏笛卡尔积操作,效率更是降低很多.

        因为mysql等数据库,效率比较低,所以承担的并发量就有限一旦请求数量多了,数据库的压力就会很大,甚至很容易就宕机了
        服务器每次处理一个请求,一定都要消耗一些硬件资源(cpu,内存,硬盘,网络...)任意一种资源的消耗超出了机器能提供的上限,机器就很容易出现故障了
        如何提高mysl能承担的并发量?(客观需求)

        1.开源:引入更多的机器.构成数据库集群
        2.节流:引入缓存,就是典型的方案.把一些频繁读取的热点数据,保存到缓存上,后续在查询数据的时候,如果缓存中已经存在了,就不再访问mysal了.

        数据访问流程逻辑:

1.2 缓存的更新策略

        缓存的更新策略可以知道redis中应该存储哪些数据,依旧哪些数据是热点数据。

1.定期生成

      会把访问的数据,给以日志的形式记录下来。日志记录和分析的过程如下所示:

        此处的数据,就可以根据当前这里统计的维度,来定期更新,按照天级别统计,就每天更新一次或者按照月级别统计,就每个月更新一次。

        写一套离线的流程(往往使用shell,python写脚本代码....),可以通过定时任务来触发
        a)完成统计热词的过程
        b)根据热词,找到搜索结果的数据
        c)把得到缓存数据同步到缓存服务器上
        d)控制这些缓存服务器自动重启
        优点:上述过程,实际上实现起来比较简单的.过程更可控.(缓存中有啥是比较固定的),方便排查问题。
        缺点:实时性不够.如果出现一些突发性事件,有一些本来不是热词的内容,成了热词了。新的热词就可能给后面的数据库带来较大的压力 。

2. 实时⽣成

        如果在Redis查到了,就直接返回.

        如果Redis中不存在,就从数据库查,把查到的结果同时也写⼊Redis.

        这样不停的写redis,就会使redis的内存占用越来越多,逐渐达到内存上限.(不一定是机器内存上限.redis中也可以配置,最多使用多少内存),此时如果继续往里插入数据,就会触发问题
为了解决上述情况,redis就引入了“内存淘策略”。

        redis里面,有一个配置项,就可以设置redis采取上述哪种策略淘汰内存数据:

1.3  缓存预热,缓存穿透,缓存雪崩 和缓存击穿

1. 关于缓存预热(Cachepreheating)

        缓存预热,就是用来解决上述问题的:
        定期生成和实时生成,结合一下。先通过离线的方式,通过一些统计的途径,先把热点数据找到一批,导入到redis中。此时导入的这批热点数据,就能帮mysal承担很大的压力了.随着时间的推移,逐渐就使用新的热点数据淘汰掉旧的数据。

2. 关于缓存穿透 (Cachepenetration)

        查询的某个key,在redisS中没有,mysal中也没有,这个key肯定也不会被更新到redis中。这次查询,没有,下次查,仍然没有。如果像这样的数据,存在很多,并且还反复查询,一样也会给mysql带来很大的压力。

        缓存穿透产生的原因:

        •  业务设计不合理.⽐如缺少必要的参数校验环节,导致⾮法的key也被进⾏查询了.

        • 开发/运维误操作.不⼩⼼把部分数据从数据库上误删了.

        •  ⿊客恶意攻击

        解决方案:
           通过改进业务/加强监控报警(不靠谱)
        更靠谱的方案 (降低问题的严重性):
           1)如果发现这个key,在redis和mysal上都不存在,仍然写入redis中,value设成一个非法值(比如“”)
           2)还可以引入布隆过滤器,每次查询redis/mysal之前都先判定一下key是否在布隆过滤器上存在(把所有的key都插入到布隆过滤器中)
        布隆过滤器,本质上是结合了hash+bitmap,以比较小的空间开销和比较快的时间速度,实现针对key是否存在的判定 

3.关于缓存雪崩(Cache avalanche)

        由于在短时间内,redis上大规模的key失效,导致缓存命中率突然下降,并且mysql的压力迅速上升,甚至直接岩机,产生原因如下所示:
        1)redis直接挂了。redis岩机/redis集群模式下大量节点容机....
        2)redis好着呢,但是可能之前短时间内设置了很多key给redis,并且设置的过期时间是相同的。给redis里设置key作为缓存的时候,有的时候为了考虑缓存的时效性就会设置过期时间.(和redis内存淘汰机制,是配合使用的)

        解决方案:

        1)加强监控报警,加强redis集群可用性的保证
        2)不给key设置过期时间/设置过期时间的时候添加随机的因子(避免同一时刻过期)

4. 关于缓存击穿(Cache breakdown) 

        其实这个意思类似于缓存瘫痪。缓存雪崩的特殊情况针对热点key,热点key突然过期了,导致大量的请求直接访问到数据库上,甚至引起数据库宕机。

        解决方案:

2  分布式锁

2.1 认识分布式锁

        在⼀个分布式的系统中,也会涉及到多个节点访问同⼀个公共资源的情况.此时就需要通过锁来做互斥 控制,避免出现类似于"线程安全"的问题.

        ⽽java的synchronized或者C++的std::mutex,这样的锁都是只能在当前进程中⽣效,在分布式的这 种多个进程多个主机的场景下就⽆能为⼒了.

        此时就需要使⽤到分布式锁。

        在分布式系统中,是有很多进程的(每个服务器,都是独立的进程)。因此,之前的锁就难以对现在分布式系统中的多个进程之间产生制约。分布式系统中,多个进程之间的执行顺序也是不确定的。由于进程随机执行,引入“分布式锁”来解决上述问题。

2.2 分布式锁的基础实现

        上面这种情况就会出现超卖的情况。

        所谓的分布式锁,也是一个/一组单独的服务器程序.给其他的服务器提供“加锁”这样的服务
Redis是一种典型的可以用来实现分布式锁的方案,但是不是唯一的一种。业界可能也会使用mysl /zookeeper这样的组件来实现分布式锁的效果。

        买票服务器,在进行买票操作的过程中,就需要先加锁。(往redis上设置一个特殊的key-value,完成上述买票操作,再把这个key-value删除掉.)其他服务器也想买票的时候,也去redis上尝试设置key-value,如果发现key-value已经存在,就认为“加锁失败”(是放弃/阻塞,就看具体的实现策略了),这样就可以保证第一个服务器执行“查询->更新”过程中,第二个服务器不会执行“查询”,也就解决了上述超卖”问题。

        刚才买票场景,使用mysal的事务也可以批量执行查询+修改操作,但是分布式系统中,要访问的共享资源不一定是mysql。也可能是其他的存储介质,没有事务。也可能是执行一段特定的操作,是通过统一的服务器完成执行动作。

        对于上面使用setnx在分布式系统上不能成功解锁,引入了过期时间。

        可以给set的key设置过期时间,一旦时间到,key就会自动被删除掉了。set ex nx这样的命令来完成设置。
         比如,设置key的过期时间,为1000ms,那么意味着即使出现极端情况,某个服务器挂了没有正确释放锁,这个锁最多保持1000ms也就会自动释放了。

        redis上的多个命令之间,无法保证原子性的,此时就可能出现,这两个命令一个成功一个失败情况, 相比之下,使用一条命令设置更加稳妥。

        所谓的加锁,就是给redis上设置一个key-value。所谓的解锁,就是给redis上这个key-value删除掉。所谓的锁,就是redis的普通键值对。

        是否可能会出现服务器1执行了加锁,服务器2执行了解锁。
         正常来说,肯定不是故意的,但是代码总会有bug。服务器2在服务器1进行加锁的同时,不小心就执行到了解锁操作.因此就可能进一步的给整个系统带来更严重的问题。

        为了解决上述问题,就需要引入一点校验机制:
        1.给服务器编号.每个服务器有一个自己的身份标识。

        2.进行加锁的时候,设置key-value.key对应着要针对哪个资源加锁(比如车次),value就可以存储刚才服务器的编号,标识出当前这个锁是哪个服务器加上的。后续在解锁的时候,就可以进行校验了。

        上述情况来说,看起来重复执行DEL好像问题不大,实则不然。
        主要是引入一个新的服务器,执行加锁,就可能出现问题了在线程A执行完DEL之后,B执行DEL之前,服务器2的线程C正好要执行加锁(set),此时由于A已经把锁释放了,C的加锁是能够成功的。但是紧接着,线程BDEL就到来了.就把刚刚服务器2的加锁操作给解锁了
        总的来说,就是因为get和set不是原子的。

         使用redis事务,能解决上述问题.(redis事务虽然弱但是能够避免插队),但是实践中往往使用的更好的方案,即lua脚本。lua是一个编程语言,作为redis内嵌的脚本,lua语言特别轻量.(实现一个lua解释器,消耗的体积是非常小的)。

        可以使用lua编写一些逻辑,把这个脚本上传到redis服务器上,然后就可以让客户端来控制redis执行上述脚本了。redis执行lua脚本的过程,也是原子的。相当于执行一条命令一样(实际上lua中可以写多个命令)redis官方文档,也明确说,lua就属于是事务替代方案。

2.3 引⼊过期时间

        过期时间的续约问题,要在加锁的时候,给key设定过期时间。但是过期时间,设置多少合适?
        如果设置的短,就可能在你的业务逻辑还没执行完,就释放锁了。

        如果设置的太长,就也会导致“锁释放不及时”问题。

        更好的方式,是“动态续约“,初始情况下,设置一个过期时间(比如设置1s)就提前在还剩300ms的时候(也不一定就是300ms,数值都灵活调整),如果当前任务还没执行完,就把过期时间再续上1s.等到时间又快到了,任务还没执行完,就再续.(无限续杯)
           但是如果服务器中途崩溃了,自然就没人负责续约了。此时锁就能在较短的时间内被自动释放。

        动态续约往往也需要服务器这边有一个专门的线程,负责续约这个事情。把这个负责的线程,叫做“看门狗(watch dog)。

2.4 引⼊Redlock算法

        使用redis作为分布式锁,redis本身就有可能挂了。要想保证“高可用”就需要通过这样一系列的“预案演习”。

        进行加锁,就是把key设置到主节点上,如果主节点挂了,有哨兵自动的把从节点升级成主节点,进一步的保证刚才的锁仍然可用。

        主节点和从节点之间的数据同步,是存在延时的。可能主节点收到了set请求,还没来得及同步给从节点呢,主节点就先挂了即使从节点升级成了主节点,但是,刚才的加锁对应的数据,也是不存在的。

        作为分布式系统,就需要随时考虑某个节点挂了的情况,需要保证某个节点挂不会影响到大局。

        此处加锁,就是按照一定的顺序,针对这些组redis都进行加锁操作。如果某个节点挂了(某个节点加不上锁,没关系,可能是redis挂了), 继续给下一个节点加锁即可。 如果写入key成功的节点个数超过总数的一半就视为加锁成功。同理,进行解锁的时候,也就会把上述节点都设置一遍解锁。

ps:本文只用来学习时,整理的笔记记录。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/34811.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Matlab 多输入系统极点配置

1、内容简介 略 Matlab 172-多输入系统极点配置 可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 clc close all clear A [-6.5727 1.1902 0 -53.4085;1.1902 -6.5727 0 -53.4085;0.5294 0.5294 0 17.7502;0 0 1 0]; B [1.3797 -0.2498;-0.2498 1.3797;-0.1111 -0.1…

国产编辑器EverEdit - 脚本(解锁文本编辑的无限可能)

1 脚本 1.1 应用场景 脚本是一种功能扩展代码,用于提供一些编辑器通用功能提供不了的功能,帮助用户在特定工作场景下提高工作效率,几乎所有主流的编辑器、IDE都支持脚本。   EverEdit的脚本支持js(语法与javascript类似)、VBScript两种编程…

Flutter 小技巧之通过 MediaQuery 优化 App 性能

许久没更新小技巧系列,温故知新,在两年半前的《 MediaQuery 和 build 优化你不知道的秘密》 我们聊过了在 Flutter 内 MediaQuery 对应 rebuild 机制,由于 MediaQuery 在 MaterialApp 内,并且还是一个 InheritedWidget &#xff0…

AI-医学影像分割方法与流程

AI医学影像分割方法与流程–基于低场磁共振影像的病灶识别 – 作者:coder_fang AI框架:PaddleSeg 数据准备,使用MedicalLabelMe进行dcm文件标注,产生同名.json文件。 编写程序生成训练集图片,包括掩码图。 代码如下: def doC…

【蓝桥杯每日一题】3.16

🏝️专栏: 【蓝桥杯备篇】 🌅主页: f狐o狸x 目录 3.9 高精度算法 一、高精度加法 题目链接: 题目描述: 解题思路: 解题代码: 二、高精度减法 题目链接: 题目描述&…

人工智能组第一次培训——deepseek本地部署和知识库的建立

deepseek本地部署的用处 减少对网络依赖性: 在断网环境下,依然可以使用预先下载的AI模型进行处理,避免因网络不稳定而无法完成任务。 提高响应速度: 数据和模型已经在本地设备上准备好,可以直接调用,不…

windows协议不再续签,华为再无windows可用,将于四月发布鸿蒙PC

大家好,我是国货系创始人张云泽,最近不少小伙伴在后台问:“听说Windows协议要到期了?我的电脑会不会变砖?”还有人说:“华为笔记本以后用不了Windows了?鸿蒙系统能用吗?”今天咱们就…

数据结构-----初始数据结构、及GDB调试

一、数据结构核心概念 相互之间存在一种或多种特定关系的数据元素的集合。 1. 数据结构定义 // 嵌入式场景示例:传感器网络节点结构 struct SensorNode {uint16_t node_id; // 2字节float temperature; // 4字节uint32_t timestamp; // 4字节struct Se…

HOT100(1)

目前想到的办法是暴力枚举,有什么更好的办法请多指教。。。。代码如下: 让数组第一个元素和后面的元素相加判断是否相等,让数组第二个元素与后面的元素相加判断是否相等,以此类推 /** * Note: The returned array must be mallo…

QuickAPI 和 DBAPI 谁更香?SQL生成API工具的硬核对比(一)

最近低代码开发火得不行,尤其是能把数据库秒变API的工具,简直是开发者的救星。今天咱就聊聊两款国内玩家:QuickAPI(麦聪软件搞出来的低代码神器)和 DBAPI(开源社区的硬核作品)。这两货都能靠SQL…

MySQL单表查询大全【SELECT】

山再高,往上攀,总能登顶;路再长,走下去,定能到达。 Mysql中Select 的用法 ------前言------【SELECT】0.【准备工作】0.1 创建一个库0.2 库中创建表0.3 表中加入一些数据 1.【查询全部】2.【查询指定列】2.1查询指定列…

开启云服务器ubuntu22.04的远程桌面,支持Windows远程连接 - 开启XRDP支持

效果图 环境 云服务器 Ubuntu 22.04 lsb_release -a No LSB modules are available. Distributor ID: Ubuntu Description: Ubuntu 22.04.5 LTS Release: 22.04 Codename: jammy 本地windows10 步骤 前置动作 # 远程登录 ssh rootx.x.x.x# 看看硬盘够不够空间&…

虚拟化数据恢复—重装系统服务器崩了的数据恢复过程

虚拟化数据恢复环境&故障: VMware虚拟化平台 vmfs文件系统 工作人员误操作重装操作系统,服务器崩溃。 重装系统会导致文件系统元文件被覆盖。要恢复数据,必须找到&提取重装系统前的文件系统残留信息,通过提取出来的元文件…

harmonyOS NEXT开发与前端开发深度对比分析

文章目录 1. 技术体系概览1.1 技术栈对比1.2 生态对比 2. 开发范式比较2.1 鸿蒙开发范式2.2 前端开发范式 3. 框架特性对比3.1 鸿蒙 Next 框架特性3.2 前端框架特性 4. 性能优化对比4.1 鸿蒙性能优化4.2 前端性能优化 5. 开发工具对比5.1 鸿蒙开发工具5.2 前端开发工具 6. 学习…

AI智能混剪工具:AnKo打造高效创作的利器!

AI智能混剪工具:AnKo打造高效创作的利器! 随着AI技术的迅速发展,AI智能混剪工具逐渐成为内容创作的利器,尤其是AnKo,作为一款免费的AI创作平台,提供了多模型AI聚合工具平台,能为用户带来更高效…

【Hestia Project 数据集】美国化石燃料 CO₂ 排放数据

Hestia Project™ 是一个革命性的研究项目,旨在帮助城市更精确地量化和管理与气候变化相关的碳排放问题。该项目提供了细粒度(建筑、街道、工厂级别)的化石燃料 CO₂ 排放数据,并通过直观的三维可视化系统向公众、政策制定者、科学家和工业界提供详细的时空信息,支持碳管理…

【TCP】三次挥手,四次挥手详解--UDP和TCP协议详解

活动发起人小虚竹 想对你说: 这是一个以写作博客为目的的创作活动,旨在鼓励大学生博主们挖掘自己的创作潜能,展现自己的写作才华。如果你是一位热爱写作的、想要展现自己创作才华的小伙伴,那么,快来参加吧&#xff01…

传感云揭秘:边缘计算的革新力量

在当今快速发展的科技时代,传感云和边缘计算系统正逐渐成为人们关注的焦点。传感云作为物联网与云计算的结合体,通过虚拟化技术将物理节点转化为多个服务节点,为用户提供高效、便捷的服务。而边缘计算则是一种靠近数据源头或物端的网络边缘侧…

Springboot中的 Mapper 无法找到的 可能原因及解决方案

目录 前言1. 问题所示2. 原理分析3. 解决方法前言 🤟 找工作,来万码优才:👉 #小程序://万码优才/r6rqmzDaXpYkJZF 1. 问题所示 执行代码的时候,出现如下问题: A component required a bean of type cn.iocoder.yudao.module.gate.dal.mysql.logger.GateOperateLogMap…

【c++】开发环境IDE、常见调试方法(gdb等)、基础c++语法特性、算法OJ刷题、入门c++项目【持续更新】

1 开发环境&IDE 基本就是如下3款,个人使用体验: vscode:优点-轻量化,插件多,便于远程调试,缺点-配置复杂 clion:优点-集成环境,最易于上手,缺点-商业软件,收费 visu…