Redis知识(一)

news/2024/11/20 19:46:52/

目录

Redis过期删除和内存淘汰策略:

过期删除策略:

内存淘汰策略(解决内存过大问题):

LRU和LFU以及他们在Redis里的实现

主从复制

哨兵模式

缓存

缓存雪崩

缓存击穿

缓存穿透

数据库和缓存一致性问题


Redis过期删除和内存淘汰策略:

过期删除策略:

当对一个key设置过期时间之后,Redis会将其加入到过期字典中,Redis里使用的是惰性删除和定期删除相结合的方式,惰性删除是当查询key的时候,先判断是否在过期字典中存在,如果存在,则判断过期时间和当前时间的大小,如果还未过期,返回查询的结果,如果过期,就删除。定期删除每过一段时间在过期字典中随机抽查一些key,判断是否过期,如果过期的key占抽查的key25%以上,就会继续抽查,直到小于25%。然后再过一段时间之后继续抽查。

内存淘汰策略(解决内存过大问题):

当Redis的内存超过最大运行内存时,会触发内存淘汰策略,第一种不进行数据淘汰策略,是Redis3.0版本之后的默认内存淘汰策略,当超过最大内存限制之后,不能再添加key,但是可以查询。

两大种:在设置了过期时间的数据中进行淘汰,1.随机淘汰。2.优先淘汰更早的键值对。3.LRU淘汰算法(最近最少使用)。4.LFU淘汰算法(最近最不常用)。

在所有数据种进行淘汰,1.随机淘汰。2.LRU。3.LFU

LRU和LFU以及他们在Redis里的实现

LRU算法是基于链表的结构,链表中的元素按照操作顺序从后往前排列,最新的操作会被移动到链表头部,淘汰时只需要删除链表尾部的元素。

因为,传统LRU算法需要涉及很多链表的移动操作,会耗时间,影响Redis缓存的性能,所以Redis用的是近似的LRU算法。是在Redis的对象结构体中添加一个额外字段,用于记录此数据的最后一次访问时间。当Redis进行内存淘汰时,会随机采样来淘汰数据,淘汰最久没使用的那个。缺点 无法解决缓存污染问题,比如某一次读取了大量的数据,一下就把内存占满了,那之前的数据就会被清除掉,而这个数据如果只用一次,就会在Redis留存很长的时间,会造成缓存污染。

为了解决问题,Redis 4.0之后引入了LFU算法(最近最不常用),根据访问次数来淘汰数据。Redis里用的是,在Redis的对象结构体中添加了数据的访问频次字段lru,lru 24bits,高16bit存储ldt,记录访问时间戳,低8bit存储 logc,记录访问频次。然后根据这两个值来判断是否淘汰。

主从复制

为了解决单点故障的问题,Redis提供了主从复制模式,并且主从服务器采用的是读写分离方式,主服务器可以读写,当发生写操作时自动把写操作同步给从服务器,从服务器一般是只读,并且接收主服务器同步过来的写操作命令,然后执行命令。

第一次同步:

1.建立连接(replicaof 命令),确定主从。主服务器会返回FULLRSYNC响应命令,表示采用全量复制,把所有数据都同步给从服务器。

2.将主服务器同步数据给从服务器。主服务器生成RDB快照(异步操作,不会影响Redis处理命令)并发送给从服务器,从服务器清空所有数据然后载入RDB文件。但是同步期间发生的操作命令,主服务器会将命令写入到 replication buffer 中,会通过第三步发送给从服务器

3.主服务器发送新写操作给从服务器,将replication buffer中的写操作命令发送给从服务器。

命令传播:TCP连接,长连接。传输写操作命令

分摊主服务器压力:服务器B可以是服务器A的从服务器,也可以是服务器C的主服务器。这样减少了主服务器生成RDB文件和传输文件的消耗。

增量复制:由于网络问题,如果主从服务器间的网络连接断开,无法保持主从一致,Redis采用了增量复制的方式继续同步,只会把网络断开期间主服务器收到的写操作命令同步给从服务器。

首先从服务器会发送自己读的位置,然后主服务器会在 环形缓冲区内查找位置,若找到,主服务器根据当前写的位置和从服务器读的位置,会将之间的增量写入到replication buffer ,然后发送给从服务器。若未找到,主服务器会采用全量同步方式。

哨兵模式

主从架构中,当主节点挂了,那就没有主节点来执行客户端写操作的请求,也不能给从节点进行数据同步了。哨兵机制能实现主从节点故障转移(监控,选主,通知),会检测主节点是否存活,如果发现挂了,就会选举一个从节点切换为主节点,并且把主节点的相关信息通知给各从节点和客户端。

监控:主观下线,哨兵每隔一秒ping所有主从节点,如果有主从节点没有在规定的时间响应哨兵的ping命令,哨兵就会标记为主观下线,此时会通知所有的哨兵,其他哨兵根据自身和主节点的网络状况来投赞成或拒绝票。如果赞成票数到达要求后 quorum(建议为哨兵个数的二分之一加一),此时会被哨兵标记为客观下线

选哨兵进行主从故障转移:哨兵标记主节点客观下线后,该哨兵就会发起投票,其他哨兵投赞成或拒绝票。拿到半数以上赞成并且大于等于配置文件中quorum值,才能做leader。

选主:第一步:在已下线主节点(旧主节点)属下的所有「从节点」里面,挑选出一个从节点,并将其转换为主节点,选择的规则:

  • 过滤掉已经离线的从节点;
  • 过滤掉历史网络连接状态不好的从节点;
  • 将剩下的从节点,进行三轮考察:优先级、复制进度、ID 号。在每一轮考察过程中,如果找到了一个胜出的从节点,就将其作为新主节点。

通知:让已下线主节点属下的所有「从节点」修改复制目标,修改为复制「新主节点」;

将新主节点的 IP 地址和信息,通过「发布者/订阅者机制」通知给客户端;

继续监视旧主节点,当这个旧主节点重新上线时,将它设置为新主节点的从节点;

缓存

用户请求时,利用Redis做MySQL的缓存层,Redis是内存数据库,相当于数据缓存在内存中。虽然速度比磁盘提升几个等级,但引入缓存层后,会出现缓存穿透、击穿、雪崩问题。

缓存雪崩

大量缓存数据在同一时间过期,或者Redis故障宕机,此时如果有大量的用户请求,都无法在Redis中处理,于是全部请求都直接访问数据库,导致数据库宕机,造成系统崩溃。

解决办法:

针对大量缓存数据在同一时间过期:

1.随机设置过期时间,保证数据不会在同一个时间过期。

2.添加互斥锁,如果发现访问的数据不在Redis里,就加一个互斥锁(设置过期时间。防止出现意外不释放锁,其他请求拿不到锁),保证同一时间内只有一个请求来构建缓 存,当缓存构建完成后,再释放。

Redis故障宕机

1.通过主从节点的方式构建Redis集群。当主节点宕机,可以通过哨兵选主,避免了宕机带来的问题。

2.启动服务熔断(限流。只能少部分请求)机制,暂停业务应用对缓存服务的访问,直接返回错误,不用再继续访问数据库,降低了对数据库访问的压力,等Redis恢复正常后,再允许业务访问。

缓存击穿

热点数据过期了,但是大量请求访问这个热点数据。缓存中没了,就要去数据库查询。数据库很容易发生崩溃。

解决方法:

1.添加互斥锁

2.不给热点数据添加过期时间。或者在热点数据将要过期前,提前通知后台更新缓存以及重新设置过期时间。

缓存穿透

请求到来时,访问缓存没有数据,访问数据库也没有数据,无法构建缓存数据。大量的请求,导致数据库压力激增。

解决方法:

1.非法请求的限制。

2.发现缓存穿透现象时,可以针对查询的数据,在缓存中设置一个空值或默认值。

3.布隆过滤器。在写入数据时,先在布隆过滤器中做标记。等请求来时,判断是否标记过。

数据库和缓存一致性问题

并发情况下,先更新数据库,再删除缓存可以解决数据库和缓存一致性问题。但是如果第二步操作没有成功执行,那末还是没作用。

解决办法:

1.给缓存设置较短的过期时间,勉强可以解决一些问题。

2.利用消息队列,将第二个操作加入到消息队列。如果删除缓存失败,那就可以从消息队列中重新读取数据,然后再次删除缓存。这个就是重试机制。


http://www.ppmy.cn/news/1044157.html

相关文章

WebGL和OpenGL之间的差异

推荐:使用 NSDT场景编辑器助你快速搭建可二次编辑的3D应用场景 WebGL和OpenGL是与图形处理有关的技术标准,它们在计算机图形中扮演着重要的角色。本文将介绍WebGL和OpenGL的区别,并重点介绍"WebGL"和"OpenGL"的特点。 一…

Flask-SQLAlchemy

认识Flask-SQLAlchemy Flask-SQLAlchemy 是一个为 Flask 应用增加 SQLAlchemy 支持的扩展。它致力于简化在 Flask 中 SQLAlchemy 的使用。SQLAlchemy 是目前python中最强大的 ORM框架, 功能全面, 使用简单。 ORM优缺点 优点 有语法提示, 省去自己拼写SQL,保证SQL…

如何用输入函数为数组赋值

在编写程序时我们经常使用数组,而数组的大小可能是很大的但是我们并不需要为每个元素都自己赋值,我们可能会自定义输入数组元素个数,我们应该如何实现通过输入函数为数组赋值呢? 目录 第一种: 第二种: 第一…

element表格多选实现

表格实现多选 实现表格多选很简单&#xff0c;只需要在表格里加上一列即可&#xff0c;加完之后就会在表格里出现一列白色的四方块按钮&#xff0c;可以多选&#xff0c;也可以单选 <el-table-columntype"selection"width"55"align"center"&…

Android AlarmManager设置闹钟

官网镇楼&#xff1a;设置重复闹铃时间 闹钟具有以下特征&#xff1a; 它们可让您按设定的时间和/或间隔触发 intent。您可以将它们与广播接收器结合使用&#xff0c;以启动服务以及执行其他操作。它们在应用外部运行&#xff0c;因此即使应用未运行&#xff0c;或设备本身处…

17-工程化开发 脚手架 Vue CLI

开发Vue的两种方式: 1.核心包传统开发模式: 基于 html/css /js 文件&#xff0c;直接引入核心包&#xff0c;开发 Vue。 2.工程化开发模式: 基于构建工具 (例如: webpack)的环境中开发 Vue。 问题: 1. webpack 配置不简单 2. 雷同的基础配置 3. 缺乏统…

el-popover弹窗修改三角样式或者位置

el-popover中设置类名 popper-class"filepopver"&#xff0c;我这位置是placement"top-start" <el-popover placement"top-start" popper-class"filepopver" class"filename" width"300" trigger"hover&q…

如何大幅提高遥感影像分辨率(Python+MATLAB)

前言: 算法:NSCT算法(非下采样变换) 数据:Landsat8 OLI 遥感图像数据 编程平台:MATLAB+Python 论文参考:毛克.一种快速的全色和多光谱图像融合算法[J].测绘科学,2016,41(01):151-153+98.DOI:10.16251/j.cnki.1009-2307.2016.01.028. 左图:未进行融合的多光谱真彩色合…