Redis八股文(一)

news2024/11/24 3:09:33

目录

1.什么是Redis?

2.Redis和Memcached有什么区别?

3.为什么Redis作为MySQL的缓存?

4.Redis数据类型及其使用场景分别是什么?

5.五种常见数据类型是怎么实现的?

6.Redis是单线程吗?

7.Redis单线程模式是怎样的?

8.Redis采用单线程为什么还这么快?

9.Redis 6.0之前为什么采用单线程?

10.Redis 6.0之后为什么采用多线程?

11.Redis如何持久化?

12.AOF日志如何实现?

13.AOF日志为什么先执行命令,再将该命令写入到文件中?

14.AOF的缺点?

15.AOF的写回策略有哪些?

16.AOF日志过大,会触发什么机制?        

17.重写AOF日志的过程是怎样的?

18.RDB快照是如何实现的?

19.RDB做快照时会阻塞线程吗?

20.为什么会有混合持久化?


1.什么是Redis?

        Redis 是一种基于内存的数据库,对数据的读写操作都是在内存中完成,因此读写速度非常快,常用于缓存,消息队列、分布式锁等场景

2.Redis和Memcached有什么区别?

        1)Redis支持的数据类型多,比如:string、list、set、zset、hash等;Memcached只支持最简单的key-value数据类型。

        2)Redis支持数据持久化,Memcached不支持持久化。

        3)Redis支持发布订阅模型、lua脚本、事务等,Memcached不支持。

        4)Redis原生支持集群模式,Memcached没有原生集群模式,需要靠客户端实现往集群中分片写入数据。

       

3.为什么Redis作为MySQL的缓存?

        1)Redis具备高性能:用户第一次访问的MySQL数据会缓存在Redis中,下次访问时直接访问缓存。

        2)Redis具备高并发:单台设备的Redis的QPS(Query Per Second,每秒钟处理完请求的次数)是MySQL的10倍,直接访问Redis能够承受的请求远大于MySQL。

4.Redis数据类型及其使用场景分别是什么?

        常见的有五种数据类型:String(字符串),Hash(哈希),List(列表),Set(集合)、Zset(有序集合),随着 Redis 版本的更新,后面又支持了四种数据类型: BitMap(2.2 版新增)、HyperLogLog(2.8 版新增)、GEO(3.2 版新增)、Stream(5.0 版新增)

数据类型应用场景
string缓存对象、分布式锁等
list消息队列(生产者需自行实现全局消息唯一ID,不能以消费组形式消费数据)等
hash购物车、缓存对象等
set点赞、共同关注等
zset排行榜、电话等
bitmap签到、用户登录状态等
hyperloglog百万级网页UV计数等
GEO存储地理位置信息的场景,滴滴叫车等
stream消息队列(自动生成全局唯一消息ID,支持以消费组形式消费数据)

5.五种常见数据类型是怎么实现的?

        Tips:SDS(简单动态字符串)。SDS相比C语言的原生字符串:

        SDS不仅可以保存文本数据,还可以保存二进制数据,SDS使用len属性的值而不是以空字符串判断字符串结束;

        SDS使用len记录了字符串长度,获取字符串长度的时间复杂度是O(1),而C语言需要O(n);

        Redis的SDS API是安全的,拼接字符串不会发生缓冲区溢出,因为底层会自动扩容。

6.Redis是单线程吗?

        Redis 单线程指的是「接收客户端请求->解析请求 ->进行数据读写等操作->发送数据给客户端」这个过程是由一个线程(主线程)来完成的,这也是我们常说 Redis 是单线程的原因。

        但是,Redis不是单线程的,Redis启动的时候,会启动后台线程(BIO):

        Redis 2.6版本之前,会启动处理关闭文件、AOF刷盘两个线程;

        Redis 4.0版本之后新增了一个新的后台进程用来异步释放Redis内存,也就是lazyfree线程。例如执行 unlink key / flushdb async / flushall async 等命令,会把这些删除操作交给后台线程来执行,好处是不会导致 Redis 主线程卡顿。

        后台线程相当于一个消费者,生产者把耗时任务丢到任务队列中,消费者(BIO)不停轮询这个队列,拿出任务就去执行对应的方法即可。

  • BIO_CLOSE_FILE,关闭文件任务队列:当队列有任务后,后台线程会调用 close(fd) ,将文件关闭;
  • BIO_AOF_FSYNC,AOF刷盘任务队列:当 AOF 日志配置成 everysec 选项后,主线程会把 AOF 写日志操作封装成一个任务,也放到队列中。当发现队列有任务后,后台线程会调用 fsync(fd),将 AOF 文件刷盘,
  • BIO_LAZY_FREE,lazy free 任务队列:当队列有任务后,后台线程会 free(obj) 释放对象 / free(dict) 删除数据库所有对象 / free(skiplist) 释放跳表对象;

7.Redis单线程模式是怎样的?

        Redis 6.0版本之前的单线程模式如下:

        Redis初始化时,创建epoll对象,调用socket()、bind()、listen()创建服务端并监听,然后将监听socket加入到epoll()中,同时注册连接事件处理函数。

        Redis初始化后,主线程进入事件循环,主要做以下事情:

        1)首先调用处理发送队列的函数,判断发送队列是否有任务,如果有,就调用write函数将客户端缓存里的数据发送出去,如果没有发送完,就注册写事件处理函数,等待epoll_wait发现可写后处理。

        2)接着调用epoll_wait等待事件到来

                i)连接事件到来,调用连接事件处理函数,调用accept获取已连接的socket -> 将socket加入到epoll中 -> 注册读事件处理函数;

                ii)读事件到来,调用读事件处理函数,调用read处理客户端发来的数据 -> 解析命令 -> 处理命令 -> 将客户端对象添加到发送队列 -> 将执行结果写到发送缓存区等待发送;

                iii)写事件到来,调用写事件处理函数,通过write将客户端缓存区的数据发送出去,如果没有发送完,则会注册写事件处理函数,等待epoll_wait发现可写后处理。

        

8.Redis采用单线程为什么还这么快?

        1)大部分操作都在内存中完成;

        2)单线程模式避免了多线程之间的竞争;        

        3)采用了I/O多路复用处理大量请求。

9.Redis 6.0之前为什么采用单线程?

        单线程可维护性高,多线程会导致一系列问题,如增加系统复杂性、存在线程切换、加锁解锁、死锁造成的性能损耗。

10.Redis 6.0之后为什么采用多线程?

        Redis的主要工作是网络I/O执行命令,随着网络硬件性能的提升,Redis在网络I/O的处理上会出现性能瓶颈。为了提高网络I/O的并行度,所以对网络I/O采用多线程来处理。但是对于命令的执行,还是采用单线程。

        默认情况下,I/O多线程用来处理写数据,不用来处理读数据

        Redis 6.0版本后,默认会额外启动6个线程

  • Redis-server : Redis的主线程,主要负责执行命令;
  • bio_close_file、bio_aof_fsync、bio_lazy_free:三个后台线程,分别异步处理关闭文件任务、AOF刷盘任务、释放内存任务;
  • io_thd_1、io_thd_2、io_thd_3:三个 I/O 线程,io-threads 默认是 4 ,所以会启动 3(4-1)个 I/O 多线程,用来分担 Redis 网络 I/O 的压力

11.Redis如何持久化?

        1)AOF日志:每执行一条写命令,就把该命令以追加的方式写入到一个文件中;

        2)RDB快照:将某一时刻的内存数据,以二进制的方式写入磁盘;

        3)混合持久化:AOF和RDB混合的方式。

12.AOF日志如何实现?

        Redis在执行完一条写命令操作后,就将该命令以追加的方式写入一个文件中,Redis重启后,会先读取该文件里的命令,然后逐一执行,恢复数据。

 

13.AOF日志为什么先执行命令,再将该命令写入到文件中?

        1)避免该命令的额外的检查开销:防止语法错误的命令写入到日志文件中,在恢复数据时会出错。

        2)不会阻塞当前写操作的执行

14.AOF的缺点?

        1)数据可能会丢失:执行命令和将命令写入日志是两个过程,可能还没有将命令写入日志文件中,服务器就发生了宕机,写命令没有写入到文件中,造成数据丢失。

        2)可能会阻塞其他操作:因为AOF日志是在主线程中执行的,所以当Redis把日志文件写入磁盘的时候,会阻塞后续的操作。

15.AOF的写回策略有哪些?

        AOF写入日志的过程:

        Always:每次写操作完成后,都将AOF日志数据写入到磁盘。

        Everysec:每次写操作完成后,先将命令写入到AOF的内核缓存区,每隔一秒将缓存区的数据写到磁盘里。

        No:不由Redis控制写回磁盘的时间。每次写操作完成后,先将命令写入到AOF的内核缓存区,由操作系统决定什么时候将数据写到磁盘。

 

16.AOF日志过大,会触发什么机制?        

       当AOF日志文件大小超过设定的阈值后,触发AOF重写机制,来压缩AOF文件。

        AOF重写机制:读取当前数据库中的所有键值对,每个键值对都用一条命令记录到新的AOF文件中,全部键值对记录完成后,会用新的AOF文件替换掉现有的AOF文件。

17.重写AOF日志的过程是怎样的?

        Redis的重写AOF的过程是由后台子进程bgrewriteaof完成的。

        触发重写机制后,会创建子进程bgrewriteaof,该子进程会读取当前数据库中的所有键值对,每个键值对都用一条命令记录到新的AOF文件中。

        在重写过程中,主进程可以正常处理命令。

        Tips:

                i)为什么是子进程来完成重写AOF日志,而不是子线程?

                子进程重写AOF文件,避免阻塞主进程处理命令;

                如果是子线程来处理重写AOF,子线程和主线程共享内存数据,当修改内存数据的时候需要加锁来保证数据安全,降低性能。而使用子进程,虽然父子进程共享内存数据,但是子进程对该共享区域的数据只能可读,当主进程对内存执行写操作时,会进行写时复制,于是父子进程各自拥有独立的数据副本,不需要加锁来保证数据安全。

                ii)如果在重写过程中,主进程执行写命令更改一个已存在的key-value,会触发写时复制,那么该key-value在子进程和主进程中的内存数据不一致了,这时要怎么办?

                为解决这种数据不一致问题,Redis设置了一个AOF重写缓冲区,在bgrewriteaof执行重写AOF的过程中,如果主进程进行了写操作,那么就会将写命令同时写入AOF缓冲区AOF重写缓冲区

                当子进程完成重写工作后,会给主进程发送一个信号,主进程收到信号后,调用一个信号处理函数,该函数的作用是:将AOF重写缓存区中的内容追加到新的AOF文件中,保证数据一致性;新的AOF进行改名,覆盖现有的AOF文件

18.RDB快照是如何实现的?

        记录某一时刻的所有内存数据到RDB文件中,恢复数据时,将RDB文件中的数据写入到内存。

19.RDB做快照时会阻塞线程吗?

        Redis提供save和bgsave来生成RDB文件。

        save:在主线程中执行该命令,生成RDB文件,如果RDB文件太大,会阻塞主线程

        bgsave:会创建一个子进程来生成RDB,不会阻塞主进程

20.为什么会有混合持久化?

        RDB优点是恢复数据快,但是快照的频率太低会丢失大量数据,频率太高会影响性能;AOF文件优点是丢失数据少,但是恢复数据慢。为了集合两者的优点,所以有了混合持久化。

        混合持久化的过程:

        混合持久化工作在AOF日志重写的过程,当开启了混合持久化,重写AOF日志时,fork出来的子进程会先将与主进程共享的数据以RDB的方式写入到新的AOF文件中,然后主线程的操作命令会被记录到重写缓冲区中,重写缓冲区里的增量命令会以AOF方式写入到AOF文件中,写入完成后通知主进程将含有RDB格式和AOF格式的AOF文件替换旧的AOF文件。

        使用了混合持久化,AOF文件里的前半部分是RDB格式的全量数据,后半部分是AOF格式的增量命令

混合持久化的AOF文件内容

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

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

相关文章

iterm2工具的使用|MAC电脑终端实现分屏|iterm2开启滚动操作

iterm2 工具概括 iTerm2 是一款非常强大的终端工具。 iTerm2 最初是为 macOS 开发的,但也有 Windows 、Linux 发行版(Ubuntu、centos…)可用。 应用场景 Mac操作系统中想实现终端分屏 iterm2 工具特点 多标签和分屏: 可以在同一个窗口中打开多个标签…

【css】实现扫光特效

对于要重点突出的元素,我们经常可以看到它上面打了一个从左到右的斜向扫光,显得元素亮闪闪的!类似于下图的亮光动效 关键步骤 伪元素设置position :absolute【也可以不用伪元素,直接创建一个absolute元素盖在上面】设置渐变line…

基于jeecgboot-vue3的Flowable流程仿钉钉流程设计器-抄送服务处理

因为这个项目license问题无法开源&#xff0c;更多技术支持与服务请加入我的知识星球。 1、因为仿钉钉设计器里抄送人是一个服务任务&#xff0c;所以要根据这个服务任务进行处理 2、前端就是一个抄送&#xff0c;选择人 3、这里用了jeecg的选择人组件 <el-form-item prop…

Java开发之Redis

1、非关系型数据库、快、高并发、功能强大 2、为什么快&#xff1f;内存单线程 非阻塞的IO多路复用有效的数据类型/结构 3、应用&#xff1a;支持缓存、支持事务、持久化、发布订阅模型、Lua脚本 4、数据类型&#xff1a; 5 种基础数据类型&#xff1a;String&#xff08;字…

【深度学习】LDA线性判别分析

date:2024/07/23 author:sion tag:Deeping Learn LDA(线性判别分析) 文章目录 LDA(线性判别分析)1.LDA是什么LDA是一种解决二分类问题的线性方法。它描述&#xff0c;对于给定样例集&#xff0c;将样例点投影到一条直线上&#xff0c;这条直线能使异样的样例相距远&#xff0c;…

three完全开源扩展案例05-围栏着色器

https://www.threelab.cn/three-cesium-examples/public/index.html#/codeMirror?navigationThree.js%E6%A1%88%E4%BE%8B[r166]&classifyshader&idfenceShader 更多案例 import * as THREE from three import { OrbitControls } from three/examples/jsm/controls/O…

【分布式锁】Redission实现分布式锁

接着上一节&#xff0c;我们遇到了超卖的问题&#xff0c;并通过Redis实现分布式锁&#xff0c;进行了解决。本节 我将换一种方式实现分布式锁。 前提&#xff1a; nginx、redis、nacos 模块1&#xff1a; provider-and-consumer 端口 8023 模块2 rabbitmq-consumer 端口 8021 …

PY32F071单片机,主频最高72兆,资源丰富,有USB,DAC,运放

PY32F071 系列单片机是基于32 位 ARM Cortex-M0 内核的微控制器&#xff0c;宽电压工作范围的 MCU。芯片嵌入高达 128 Kbytes flash 和 16 Kbytes SRAM 存储器&#xff0c;最高72 MHz工作频率。芯片支持串行调试 (SWD)。PY32F071单片机提供了包含了HAL和LL两种不同层次的驱动库…

Python 机器学习求解 PDE 学习项目——PINN 求解二维 Poisson 方程

本文使用 TensorFlow 1.15 环境搭建深度神经网络&#xff08;PINN&#xff09;求解二维 Poisson 方程: 模型问题 − Δ u f in Ω , u g on Γ : ∂ Ω . \begin{align} -\Delta u & f \quad & \text{in } \Omega,\\ u & g \quad & \text{on } \Gamma:\p…

【vue前端项目实战案例】之Vue仿饿了么App

本文将介绍一款仿“饿了么”商家页面的App。该案例是基于 Vue2.0 Vue Router webpack ES6 等技术栈实现的一款外卖类App&#xff0c;适合初学者进行学习。 项目源码下载链接在文章末尾 1 项目概述 该项目是一款仿“饿了么”商家页面的外卖类App&#xff0c;主要有以下功能…

electron 网页TodoList工具打包成win桌面应用exe

参考&#xff1a; electron安装&#xff08;支持win、mac、linux桌面应用&#xff09; https://blog.csdn.net/weixin_42357472/article/details/140643624 TodoList工具 https://blog.csdn.net/weixin_42357472/article/details/140618446 electron打包过程&#xff1a; 要将…

RabbitMQ入门详解

前言 本篇文章将详细介绍rabbitmq的基本概念知识&#xff0c;以及rabbitmq各个工作模式在springboot中如何使用。 文章目录 介绍 简介 RabbitMQ 核心 生产者与消费者 Exchange Queue 工作模式 简单模式 工作队列模式 发布订阅模式 路由模式 主题模式 SpringBoot中…

uniapp从入坑到出土(2-初始化你的uniapp项目)

第2章:《初始化你的uniapp项目》 2.1 Vite:点燃魔法的火种魔法准备:环境搭建魔法施展:项目创建魔法测试:运行项目2.2 Vue CLI vs Vite:构建项目的魔法对决2.3 uniapp项目结构初探2.4 创建你的第一个uniapp页面创建你的第一个uniapp页面**魔法代码**(`pages/index/index.…

最新快乐二级域名分发系统重置版v1.7源码-最新美化版+源码+可对接支付

源码简介&#xff1a; 最新快乐二级域名分发系统重置版v1.7源码&#xff0c;它是最新美化版源码可对接支付。 快乐二级域名分发系统重置版v1.7源码&#xff0c;简单快捷、功能强大的控制面板。系统稳定长久&#xff0c;控制面板没任何广告&#xff0c;让网站更实用方便。 最…

ubuntu22.04 安装 NVIDIA 驱动

目录 目录 1、事前问题解决 2、安装 3、卸载 1、事前问题解决 在安装完ubuntu之后&#xff0c;如果进入ubuntu出现黑屏情况&#xff0c;一般就是nvidia驱动与linux自带的不兼容&#xff0c;可以通过以下方式解决&#xff1a; 1、启动电脑&#xff0c;进入引导菜单&#x…

PHP预约推拿按摩小程序系统源码

&#x1f486;‍♀️轻松享受&#xff0c;揭秘“预约推拿按摩小程序”的便捷之道&#x1f4f1; &#x1f308; 开篇&#xff1a;告别繁琐&#xff0c;一键预约舒适时光&#xff01; 在这个快节奏的生活中&#xff0c;找到片刻的宁静与放松成为了我们的奢望。而“预约推拿按摩…

探索BPMN—工作流技术的理论与实践|得物技术

一、前言 19世纪70年代&#xff0c;流程管理思想萌芽阶段。 怎样提高工作效率&#xff1f; 泰勒&#xff1a;标准化个人操作流程 亨利福特&#xff1a;规定标准时间定额 标准化、精简化、通用化、专业化。 20世纪70年代&#xff0c;工作流技术起源于办公自动化领域的研究。由于…

minio 服务docker配置

用minio docker配置了一个服务&#xff0c;分享链接始终是127.0.01开始的&#xff0c; 改成docker的host的ip则提示签名不匹配&#xff0c; 好在这个文件主要是用来下载的&#xff0c;所以可以通过设置bucket的匿名访问权限来实现下载&#xff1b; 这样不需要后面的地址参数就…

GeoHash原理介绍以及在redis中的应用

GeoHash将二维信息编码成了一个一维信息。降维后有三个好处&#xff1a; 编码后数据长度变短&#xff0c;利于节省存储。利于使用前缀检索当分割的足够细致,能够快速的对双方距离进行快速查询 GeoHash是一种地址编码方法。他能够把二维的空间经纬度数据编码成一个字符串。 1…

网站漏洞扫描软件Burp suite和Xray安装应用及联合使用

目录 1、网站漏洞扫描软件应用-Burp suite 01 burp 扫描工具使用介绍&#xff1a; 02 burp 扫描工具安装过程&#xff1a; 1&#xff09;获取扫描工具程序包 2&#xff09;安装部署扫描工具 3&#xff09;bp安装完毕的基础设置&#xff1a; 3.1&#xff09;抓取浏览器访…