分布式缓存Redis 面试突击

news2024/10/6 8:30:39

Redis分布式锁

单机版  关于 synchronized 和trylock的区别

前者 是  不见不散  我一定要等到你

后者是   过时不候  我尝试一下  获取不到就算了 可以设置一个时间  这个时间范围内获取不到就算了

用缓存两个目的:高性能与高并发

高性能:减少了查询时间,比如一些热点数据就可以放进缓存中。

高并发:数据库承载的请求过多可能会宕机, 我们可以把一些热点数据放进缓存中,用户查询 某条数据,如果缓存中有,就直接从缓存中拿,没有再查数据库,这样就为数据库分担了很多请求

缓存天然就可以支撑高并发  因为缓存是基于内存的

Redis与Memcached有什么区别?为什么单线程的redis比多线程的memcached效率高得多?

1.redis拥有的数据类型和操作更多

2.内存使用效率,redis更高,他是基于key-value来存储的

3.集群模式  memcached没有原生的集群模式

4.redis是单线程 memcached是多线程

Redis线程模型:

文件事件处理器:

客户端与redis通信的流程:就是每个客户端都通过一个soket来与redis建立通信,通过IO多路复用程序来将请求压入队列,然后redis一个个去处理这些请求

为什么能支撑高并发? 一秒钟可以处理一万个请求

1.是非阻塞的IO多路复用模型,它监听到请求并不直接处理,而是将请求压入队列

2.文件事件分派器是基于纯内存的 单线程反而避免了多线程的频繁上下文切换问题

 Redis分别在哪些场景下比较合适?

比如他的list数据类型,可以用来存储  key为某个大V的名字,value为{zhangsan,lisi}他的粉丝

set 

可以玩交集并集这些  看两个人的共同好友

sorttedset  去重并且可以排序

可以做排行榜

redis的过期策略,能不能手写一个LRU代码?

内存中的数据过多,redis会自动把一些数据干掉。

定期删除与惰性删除

定期删除:他会每隔一段时间去检查哪些数据过期了  然后将其删除

惰性删除:不是key到时见就会被删除掉,而是你查询这个key的时候,redis再懒惰的检查一下

通过这两种来保证过期key一定被删除。

为什么会出现,很多键过期了但是内存依然被大量占用呢?

这就说明很多key没有靠定期删除给删除掉,还停留在内存中,占用着内存,除非你的系统去查一下那个key,才会被redis删除掉

如果定期删除漏掉了很多过期key,然后你也没有及时去查,也就没走惰性删除,此时可能会导致大量过期key堆积,导致redis内存块耗尽了

走内存淘汰机制!

如果redis内存占用过多,会进行内存淘汰,有以下机制:

比如  移除最近使用最少的key

手写lru(内存淘汰机制)算法:

 怎么保证Redis高并发与高可用?

Redos跟整个系统的高并发关联性是非常大的

redis不能支撑高并发的瓶颈是在哪?

单机redis最多承载的qps大概在上万到几万不等,如果说你单机模式下,你的客户量是上千万,那直接一下就把redis给打死了。

单机不太可能超过十万。

高可用(持久化)

Redis  replication->主从架构->读写分离->水平扩容支撑读高并发

master持久化:一个master是可以配置多个slave的  

redis会异步的复制数据到slave节点,slave会周期性的确认自己每次复制的数据量

slave 在做复制的时候  并不会阻塞maser的正常工作  也不会阻塞掉对自己的查询,他会用旧的数据集来提供服务,复制完成后会删除旧的数据集,加载新数据集,这个过程会暂停服务

slave主要是来做读写分离和横向扩容。

对于主从架构来说,master是必须要做持久化的,因为如果不做持久化,一但master宕机,是没有本地数据可以恢复的,会认为自己的数据是空的,然后slave也会在master上去拉取空数据

造成100%的数据丢失

slave复制master的过程:

第一次是生成一个RDB快照,slave会先将其写入磁盘,然后从磁盘中加载到内存中。

后面master收到一条写命令就会发一条给slave同步

主从复制的断点续传:可以接着上一次复制的地方,继续复制下去

因为master 会在内存中存储一个backlog,这里面记录了上次传到了哪个位置

如果找不到对应的offeset  也就是上次传到的位置,那么会执行一次全量复制

无磁盘化复制:master在内存中直接创建rdb,然后发送给slave,不会自己本地落地磁盘了

过期key处理:slave不会过期key,如果master过期了一个key,或者通过lru淘汰了一个key,那么会模拟一条del命令发送给slave

masternode与slaveNode之间有心跳检测机制

Redis怎么做到高可用?

sentinal node  哨兵 会自动监测master有没有挂  如果过了会将slave node变成master node

通过哨兵来完成redis高可用  是redis中一个很关键的组件

不能保证数据零丢失  但是可以保证redis集群的高可用性

经典的3节点哨兵集群

 Redis主备切换时数据丢失问题:异步复制、集群脑裂

异步复制:有部分数据还没有复制到slave master就宕机了,此时这部分数据就丢失了

集群脑裂:master其实并没有死,但是因为网络问题,哨兵很长时间没有检测到master,从而选举了新的master  导致此时存在两个master

大脑一分为二,都想指挥同一个人。

但是因为原本的masterNode是接收了客户端数据的,当网络恢复后,他变成了slave节点,所以这一块数据丢失了

怎么解决?

两个参数,要求至少有一个slave,数据复制和同步的延迟不能超过10秒,如果说一但所有slave 数据复制与同步的延迟超过十秒,那么这个时候master不会接收任何请求了

然后这些请求会放到一个地方暂存

这样就解决了异步复制和脑裂问题

Redis哨兵多个底层原理

Sdown  主观宕机  只有一个哨兵觉得一个master宕机了  

Odown 客观宕机  quorum数量的哨兵觉得一个master宕机了

slave->master选举算法

1跟master连接断开时长

2slave优先级

3复制offeset

4run  id

怎么保证redis持久化?

Redis持久化主要在于故障恢复

通过持久化搞一份儿在磁盘上,定期同步和备份到一些云存储服务器上去,那么就不会导致数据的全部丢失,只是丢失部分数据

RDB与AOF两种持久化机制的工作原理?

RDB是定期生成内存中的一份完整快照,有可能是几分钟也可能是几小时

AOF呢,redis中每拿到一条数据就往内存中写  首先是存到os cache  然后每隔一秒调用一次操作系统中fsync操作,强制将oscache中的数据刷到磁盘文件中

redis不是会有lru缓存清除算法么  可能redis中清除了50万 变成100w 但是此时AOF中还是150万

那么此时会执行rewrite操作  重新生成一个AOF,这个AOF存的是redis现在的100w条数据,而旧的AOF就废弃掉了

RDB是一次性   AOF是追加

AOF保存的数据更加完整 

-RDB容易导致几分钟到几小时的数据丢失  但是他可以保证Redis的性能是最高的

RDB每次写都是写进Redis内存的  只是在一定的时候才会将数据写入到磁盘中

AOF 每次都是要写文件的,虽然可以快速写进os cache中 但是速度还是比RDB慢  会导致Redis支持的写qps更低    存储的数据量太大了    比较大的缺点是做数据恢复的时候比较慢,还有做冷备,定期的备份不太方便,可能要自己手写复杂的脚本去做

RDB与AOF如何选择:可以两种都开启。AOF来保证数据不丢失,作为数据恢复的第一选择。RDB来做不同程度的冷备,在AOF文件都丢失或者损坏不可用的时候,还可以用RDB来进行快速数据恢复

Redis集群模式的工作原理

如果要支撑更大的数据量缓存,那就横向扩容更多master节点

如果数据量很大 就用redis cluster

数据量并没有那么大  那么 一主多从加上sentinal集群即可

那么现在如果有三个master  那数据要如何分布呢?

数据分布算法:最简单的就是取模   会导致大部分请求全部无法拿到有效缓存

一致性hash算法(自动缓存迁移->某个master如果宕机 顺时针找完所有master节点后,那些请求会涌入数据库中来处理)+虚拟节点(自动负载均衡 )

缓存热点问题:涌入某个master的数据特别多  ->解决:可以给每个master都做均匀分布的虚拟节点比如 1附近有2和3的虚拟节点  这样就保证了123是平均承载请求的。在每个区间内,都会均匀的分布到不同的节点上,而不是按照顺时针的顺序去走,全部涌入同一个master内

hash slot算法  总共有一万六千多个slot  然后三个master的话 可能每个会有五千多个slot  一个key来了之后  取模之后其实是去找对应的hashslot    任何一台机器宕机,另外两个节点不受影响,因为key找的是hash slot,找的不是机器      如果某个master宕机,客户端发请求时,另外两个master会完成slot迁移,会在某个master上重新生成该slot

Redis cluster核心原理

redis cluster节点间通信采取gossip协议,小道流言

所有节点都持有一份元数据,不同的节点如果出现了元数据的变更之后,会不断将元数据发送给其他节点,让其他节点也进行元数据的变更

集中式的优点是  时效性非常好,一但元数据发生变更,立即就会更新到集中式的存储中,其他节点读取的时候立刻就可以感知到  缺点是所有元数据更新压力都集中在一个地方,可能会导致元数据的存储有压力

gossip  小道流言的好处是元数据更新比较分散,更新请求陆陆续续,打到所有节点上去更新,有一定延迟,降低了压力。 缺点:元数据更新有延迟,可能导致集群一些操作滞后

面向集群的jedis内部实现原理:

jedis就是redus的java  client客户端 

基于重定向的客户端,客户端可能会挑选任意一个redis实例去发送命令,如果计算key对应的hashslot  如果有  就在本地处理  找不到就重定向  同一个hashtag  会在同一个hashslot中

想Jedis这种客户端一般用的都是smart模式  因为重定向很耗费网络IO,所以它会在本地维护一个hashslot ->node的映射表  大部分情况下  只需要直接走本地缓存就可以找到对应的 node  不需要进行moved重定向

jedis cluster初始化的时候,首先会随机选择一个node,初始化hashslot表,同时为每个节点创建一个jedispool连接池,每次基于jedisCluster执行操作

反正它会不断更新它所维护的映射表 ,以保证下一次查询的准确性

高可用与主备切换原理:

判断节点宕机:与哨兵非常相似,有主观宕机和客观宕机  一个认为是主观宕机,多个认为是客观宕机,如果一个节点认为某个节点宕机了,就会在gossip ping命令中,ping给其他节点,如果超过半数认为其宕机了,那么他就会变成fail

从节点过滤:断开连接时间过长就没有资格切换成主节点

从节点选举:根据对自己master复制数据的offset来,offeset越大,选举时间越靠前,优先进行选举。所有的master来对slave进行选举,如果大部分(N/2+1)都投给了投个节点,那么通过

如何应对缓存雪崩与缓存穿透?

雪崩:缓存宕机,请求全落到数据库 数据库瞬间挂掉

解决不了 ,只能缓解:1.缓存必须是高可用    配置高可用缓存架构 redis cluster 多主多从

                                     2.系统内部做一个缓存 ehcache

                                     3.做限流与降级限流:本来每秒5000  现在只有2000个进来 进入数据库                                                                      降级:返回一些默认的值  至少保证系统不死

                                     4.Redis必须做持久化

穿透:发来5000请求,这5000个请求只有1000个是正常请求,另外四千个缓存中找不到,直接穿透了缓存 就发给数据库里,而数据库中也没有,  那么一下就把数据库打死了

解决:只要数据库中没查到值,就在缓存中写一个key相同,而值为undefined的这样一个值

所以下次来查的时候就可以直接在缓存中拿到

如何保证数据库和缓存双写的一致性问题?

cache aside pattern 

读的时候先读缓存,再读数据库,取到后放入缓存

更新的时候先更新

读写并发情况也可能导致缓存出现问题:解决  让读写异步     :让读请求串行化,首先是在更新数据库的之前会删掉缓存嘛,然后删的同时也有人在读,此时我让读现在库存服务里面排队,等数据库里面数据更新了以后再去读并且更新缓存中的数据

队列排重优化   ---------------  超时(TP99 200ms)直接返回数据库请求

Redis并发竞争:

分布式锁,一个一个来获取锁

你要写入缓存的数据,都是从mysql中查出来的,都得写入mysql中,写入mysql中的时候必须保存一个时间戳,从mysql查出来的时候,时间戳也查出来。 每次在写之前,先判断当前value的时间戳是否比缓存中的value要新,更新的话就可以写  如果更旧,就不能用旧数据覆盖新数据

Redis集群架构师怎么部署的?

说一下线上的情况

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

使用Linkage Mapper制作环境连接图

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Linkage Mapper解密数字世界链接 文章目录 引言一. 简介1.1 Linkage Mapper 概述1.2 环境连接…

基于html+css的图展示55

准备项目 项目开发工具 Visual Studio Code 1.44.2 版本: 1.44.2 提交: ff915844119ce9485abfe8aa9076ec76b5300ddd 日期: 2020-04-16T16:36:23.138Z Electron: 7.1.11 Chrome: 78.0.3904.130 Node.js: 12.8.1 V8: 7.8.279.23-electron.0 OS: Windows_NT x64 10.0.19044 项目…

DJ5-8 磁盘存储器的性能和调度

目录 5.8.1 磁盘性能简述 1、磁盘的结构和布局 2、磁盘的类型 3、磁盘数据的组织和格式 4、磁盘的访问过程 5、磁盘访问时间 5.8.2 磁盘调度算法 1、先来先服务 FCFS 2、最短寻道时间优先 SSTF 3、扫描算法(电梯算法)SCAN 4、循环扫描算法 …

4 IK分词器

4 IK分词器 4.1测试分词器 在添加文档时会进行分词,索引中存放的就是一个一个的词(term),当你去搜索时就是拿关键字去匹配词,最终 找到词关联的文档。 测试当前索引库使用的分词器: post 发送&#xff…

Python计算语义分割模型的评价指标

目录 一、混淆矩阵 二、分类指标 1、Accuracy(准确率) 2、Precision(查准率) 3、Recall (查全率) 4、F1-score 三、语义分割的评价指标 1、MPA(类别平均像素准确率) 2、IoU(交并比) 3、MIoU(平均交并比) 4…

STL-stack容器和queue容器

stack概念:stack是一种先进后出(First In Last Out,FILO)的数据结构,它只有一个出口 栈中只有顶端的元素才可以被外界使用,因此栈不允许有遍历行为 与queue相似,stack也是一个适配器类,它给底层vector提供了典型的栈接…

C语言——数组

哈喽,大家好,今天我们要学习的是数组的相关知识。 目录 1.什么是数组 2.一维数组 2.1一维数组的创建和初始化 2.2一维数组的使用 2.3一位数组在内存中的存储 3.二维数组 3.1二维数组的创建和初始化 4.2二维数组的使用 4.3二位数组在内存中的存储…

java安全编码规范(0)

JAVA安全编码标准 有这么一指导书,新手可以去看看,这里主要从实践总结,随时会更新。 主要从十个方面去了解下,实际上远远不只这些哦。 ​​​​​​​ 1、引用java security library 环境需求 Java 8Maven 3 a、编译jar包&a…

「锂」清思绪,触达未来 | 锂电池企业如何实现数字化破局?

锂电池制造的困局与破局 锂电池行业产业链的上游主要为正负极材料、电解液、电极基材、隔膜等领域的供应商;中游为电芯制造及封装行业;下游则主要是动力电池、消费电子等锂电池的应用领域。 图1:锂电池行业产业链 近年来,随着相…

虹科方案 | 适用于高压环境或潜在爆炸性环境的加速度计系统

PART 1 加速度系统 加速度计系统通常用于测量振动或运动。测量系统能够记录一个、两个或三个空间方向的运动。所实际使用的传感器是光纤传感器,可提供不受电磁干扰影响的可靠测量值。当然,这样的系统具有高可靠性,即使在不断变化的天气条件下…

转置卷积(Transposed Convolution)可视化过程

目录 1. 介绍2. 标准卷积3. 转置卷积4. 总结 1. 介绍 转置卷积(Transposed Convolution)经常也被称作反卷积,所谓反卷积即为通过标准卷积层生成的输出被反卷积,将得到原始输入。而转置卷积不按值反转标准卷积,而仅按维…

STM32F4_待机唤醒详解

目录 1. 低功耗模式 1.1 降低系统时钟速度 1.2 外设时钟门控 2. 睡眠模式 2.1 进入睡眠模式 2.2 退出休眠模式 3. 停止模式 3.1 进入停止模式 3.2 退出停止模式 4. 待机模式 4.1 进入待机模式 4.2 退出待机模式 4.3 电源控制寄存器:PWR_CR 4.4 电源控…

‘OpenpyxlWriter‘ object has no attribute ‘save‘

使用read_sql(sql,conn)来获取数据库查询的结果, 在将处理完成的表格保存下来时,可能会显示如下错误: 将writer.save()改成writer._save()就可以解决这个问题了。

必须了解的mysql三大日志-binlog、redo log和undo log

目录 一,前言二,binlog-备份日志1,作用2,使用场景3,日志形式4,binlog刷盘时机 三,redo log-重做日志1,概念2,为什么需要redo log3,日志形式4,redo…

数据结构之树(一)

一.概念 边:一棵n个结点树有n-1条边 结点深度:从根到当前结点的路径的深度。 结点高度:从当前结点到叶子结点最长路径的长度。 树的性质 树中的结点总数等于所有结点的度1;m叉树中第i(i>1)层上至多可以有m^(i-1)个节点; 高…

互联网大厂手把手教你搭建数据服务中台(附下载链接)

摘要: 随着公司业务的发展,对于数据的需求会越来越多。怎么在业务系统中高效的使用数据,让业务系统处理大数据时化繁为简,数据服务化基本是必经之路。那么什么是数据服务化,简单理解就是数据SaaS,通过一些数据库语言把…

true or false?

有同学在星球问了这样一个问题。 代码是这样的: public class Main {private static final Main instance new Main();private boolean b a;private static boolean a initA();private static boolean c a;private static boolean initA() {return true;}priva…

洛谷B2099 矩阵交换行

矩阵交换行 题目描述 给定一个 5 5 5 \times 5 55 的矩阵(数学上,一个 r c r \times c rc 的矩阵是一个由 r r r 行 c c c 列元素排列成的矩形阵列),将第 n n n 行和第 m m m 行交换,输出交换后的结果。 输入格式 输入共 6 6 6 …

DataEase 本地源码启动详细教程

本教程将引导你通过本地源码部署的方式启动 DataEase,同时我还录制了相应的视频教程,你可以跟随视频进行操作: DataEase 本地源码启动_哔哩哔哩_bilibili 1、下载并安装IDEA开发工具 2、下载安装Mysql 5.7 以及 JDK 1.8 如果你使用的是wi…

使用pdf.js展示pdf文件(亲测可用)

简单的实现方式 如果只是电脑端,可通过 iframe 标签嵌套预览 ios手机端可通过 a 标签包裹点击跳转预览(安卓端不行) 安卓电脑ios的通用方法 资料 老版本github地址 全版本地址 获取当前客户端类型 judgeClient() {let client if (/(iPh…