Redis面试

embedded/2024/9/23 1:57:36/

数组结构

String、Map、Set、ZSet、List

持久化

AOF:追加日志持久化操作,将写命令追加到一个文件的末尾。redis重启时,执行这些操作。更可靠。不会出现数据丢失的问题。写入硬盘的频率配置:每秒同步、每写入命令同步、禁止同步
RDB:快照持久化,将某个时间点的数据以二进制的形式保存到硬盘上。可以定时/手动触发/自动触发。生产的文件比AOF小,恢复速度快,适合备份和灾难恢复。操作的是虚拟内存的页表,只拷贝页表,两份页表指向同一个物理内存。
AOF优先级更高,重启时会优先AOF,如果AOF文件损坏,使用RDB

主从复制

主从复制包括全量复制,增量复制两种。一般当slave第一次启动连接master,或者认为是第一次连接,就采用全量复制,
全量复制流程如下:
1.slave发送sync命令到master。
2.master接收到SYNC命令后,执行bgsave命令,生成RDB全量文件。
3.master使用缓冲区,记录RDB快照生成期间的所有写命令。
4.master执行完bgsave后,向所有slave发送RDB快照文件。
5.slave收到RDB快照文件后,载入、解析收到的快照。
6.master使用缓冲区,记录RDB同步期间生成的所有写的命令。
7.master快照发送完毕后,开始向slave发送缓冲区中的写命令;
8.salve接受命令请求,并执行来自master缓冲区的写命令

增量复制
主从服务器在完成第一次同步后,就会基于长连接进行命令传播。
连接可能断开,
重新连接上后slave会发送自己的复制偏移量和环形缓冲区给master
在主服务器进行命令传播时,不仅会将写命令发送给从服务器,还会将写命令写入到 repl_backlog_buffer 缓冲区里,因此 这个缓冲区里会保存着最近传播的写命令。
如果判断出从服务器要读取的数据还在 repl_backlog_buffer 缓冲区里,那么主服务器将采用增量同步的方式;
相反,如果判断出从服务器要读取的数据已经不存在
repl_backlog_buffer 缓冲区里,那么主服务器将采用全量同步的方式。

哨兵模式

哨兵模式,在独立的哨兵节点上运行哨兵进程
sentile 主进程,监控各个节点的状态,执行故障转移
monitor 哨兵进程,监控主节点和从节点的情况,并通知其他哨兵进程
judge 哨兵进程 根据预设的阈值,判断是否要将主节点下线
failover 哨兵进程,将选举出来的从节点设置为主节点,并通知其他节点更新配置信息

工作原理
启动时,哨兵会选举出一个主节点,每个哨兵节点向其他节点发出命令,当票数大于一半时就成为领导者。
节点监控,发送命令周期性的检查主从节点的状态,如果发现主节点不可用,触发一次故障转移。
故障转移:
1、过滤已下线的从节点
2、选择优先级最高
3、选择和主节点复制最完整的从节点
联系客户端新的主节点位置,让客户端能和新的主节点建立连接。
监控从节点,有问题就下线,没问题再上线。

缓存一致性

1、延时双删:先删除redis、再更新mysql,过几百毫秒后又删除一次redis。保证将第一次删除redis和更新mysql之间产生的脏数据删除
2、队列+重试机制
先更新mysql,如果删除redis失败,将删除操作发送到mq,过一会再删除,重试删除操作。这样做对业务代码侵入大。
3、基于订阅binlog的同步机制,
1、更新mysql,mysql将操作写入binlog
2、提取binlog,发送到mq,mq发送后再操作一次redis

缓存击穿、缓存穿透、缓存雪崩

缓存击穿redis热点数据过期,请求直接打到mysql
解决:热点数据不设置过期时间,防止缓存击穿

缓存穿透redis没有这个key,数据库也没有,导致数据库负载过大
如果数据库也没有的数据,在缓存做一个空的值,防止缓存穿透
布隆过滤器:它由初始值为0的位图数组和N个哈希函数组成。一个对一个key进行N个hash算法获取N个值,在比特数组中将这N个值散列后设定为1,然后查的时候如果特定的这几个位置都为1,那么布隆过滤器判断该key存在。
缓存雪崩:缓存在某个时间点失效/崩溃,大量请求打到后端服务器,后端数据库也崩溃。导致服务不可用

热key

可预知的:凭借业务经验,进行预估哪些是热key,通过批量加载和预先访问热门数据,将热key提前加载到内存中。

不可预知的:通过Daas平台查看热点key的分析和监控。一般不用monitor命令什么的,因为公司不让。

热key的危害
1、流量集中,可能使某台机器宕机
2、缓存击穿,引起db雪崩

热key的方案
1、使用二级缓存,GuavaCache等,但是会有缓存一致性问题需要维护。
2、让热key分散到不同机器上
3、热key拆分,把热key再根据业务细分。

在生成 RDB期间,Redis 可以同时处理写请求么?
可以的,Redis提供两个指令生成RDB,分别是save和bgsave。

如果是save指令,会阻塞,因为是主线程执行的。
如果是bgsave指令,是fork一个子进程来写入RDB文件的,快照持久化完全交给子进程来处理,父进程则可以继续处理客户端的请求。

redis_86">redis哈希冲突

redis对哈希冲突的处理方式类似hashmap,相同hash值的放在一个链表里

为什么Redis 6.0 之后改多线程呢?

Redis6.0之前,Redis在处理客户端的请求时,包括读socket、解析、执行、写socket等都由一个顺序串行的主线程处理,这就是所谓的“单线程”。
Redis6.0之前为什么一直不使用多线程?使用Redis时,几乎不存在CPU成为瓶颈的情况, Redis主要受限于内存和网络。例如在一个普通的Linux系统上,Redis通过使用pipelining每秒可以处理100万个请求,所以如果应用程序主要使用O(N)或O(log(N))的命令,它几乎不会占用太多CPU。
redis使用多线程并非是完全摒弃单线程,redis还是使用单线程模型来处理客户端的请求,只是使用多线程来处理数据的读写和协议解析,执行命令还是使用单线程。

这样做的目的是因为redis的性能瓶颈在于网络IO而非CPU,使用多线程能提升IO读写的效率,从而整体提高redis的性能。

Redisson

要线程一加锁成功,就会启动一个watch dog看门狗,它是一个后台线程,会每隔10秒检查一下,如果线程1还持有锁,那么就会不断的延长锁key的生存时间。因此,Redisson就是使用Redisson解决了锁过期释放,业务没执行完问题。


http://www.ppmy.cn/embedded/3595.html

相关文章

蓝桥杯 — — 纯质数

纯质数 题目: 思路: 一个最简单的思路就是枚举出所有的质数,然后再判断这个质数是否是一个纯质数。 枚举出所有的质数: 可以使用常规的暴力求解法,其时间复杂度为( O ( N N ) O(N\sqrt{N}) O(NN ​)&…

20240419,继承,多态

土豆的老家陕西安康!怪舒服的咯,广西一眼望去全是房子啦,小时候一眼开敞水田再也回不来啦 目录 五,继承 5.1 基本语法 5.2 继承方式 5.3 继承中的对象模型 5.4 构造和析构顺序 5.5 同名成员处理 5.6 同名静态成员处理 5.…

javax.net.ssl.SSLHandshakeException: No appropriate protocol

cd /Library/Java/JavaVirtualMachines/jdk-1.8.jdk/Contents/home/jre/lib/security sudo vi java.security 删掉下面的三个配置,然后重启应用即可

YOLOv5 / YOLOv7 / YOLOv8 / YOLOv9 / RTDETR -gui界面-交互式图形化界面

往期热门博客项目回顾:点击前往 计算机视觉项目大集合 改进的yolo目标检测-测距测速 路径规划算法 图像去雨去雾目标检测测距项目 交通标志识别项目 yolo系列-重磅yolov9界面-最新的yolo 姿态识别-3d姿态识别 深度学习小白学习路线 AI健身教练-引体向上…

深入理解SOAP协议:基于XML的分布式通信协议

文章目录 目录 文章目录 前言 一、SOAP协议的基本概念 1. 基本概念 2. SOAP消息结构 3. SOAP的通信模式 4. SOAP协议的扩展性 5. SOAP的传输协议独立性 6. SOAP的安全性 7. SOAP协议的应用场景 二、具体格式和应用 1. SOAP消息结构示例 2. SOAP的通信模式示例 请求…

【Java集合进阶】数据结构(平衡二又树旋转机制)数据结构(红黑树、红黑规则、添加节点处理方案详解)

🍬 博主介绍👨‍🎓 博主介绍:大家好,我是 hacker-routing ,很高兴认识大家~ ✨主攻领域:【渗透领域】【应急响应】 【Java】 【VulnHub靶场复现】【面试分析】 🎉点赞➕评论➕收藏 …

如何用Redis高效实现12306的复杂售票业务

12306的售票业务是一个复杂的系统,需要考虑高并发、高可用、数据一致性等问题。使用Redis作为缓存和持久化存储,可以提高系统的性能和可扩展性,以下是一些可能的实现方式: 1 票源信息缓存:将票源信息(如车次…

模板函数小结

一、用法举例 举个例子说明。 #include <iostream> using namespace std;template <class T>//class也可以替换为typename T Max(T a, T b) {return a > b? a : b; }int main() {//隐式调用cout << Max(1, 2) << endl;cout << Max("d…