Redis面试汇总笔记

news/2024/5/17 21:03:15/文章来源:https://blog.csdn.net/xuguoxing123/article/details/127149034

       在两个月前的学习中,我看过一个redis相关的讲解视频,是一个叫诸葛的老师,其中分为几层进行讲述,分别是数据类型、分布式锁、redis常见问题等。当时有记录一些内容,下面将按照顺序进行分享。

(一)常见的数据类型

       结合视频的内容,通过一张结构图来展示各个数据类型之间的关系:
在这里插入图片描述
       常见的数据类型一般都是图上的几种:String、Hash、List、Set、有序集合Set。

(1)String

常用操作
1)字符串常用操作

set key value;
mset key valye [key value …]; //批量存储字符串键值对
setnx key value; //存入一个不存在的字符串键值对
get key [key …];
del key [key …];
expire key seconds //设置一个键的过期时间

2)原子加减

incr key //将key中存储的数字加1
decr key //将key中存储的数字减1
incrby key increment //将key所存储的值加上increment
decrby key decrement //将key所存储的值减去decrement

3)分布式锁

setnx [key] true //返回1代表取锁成功,返回0代表获取锁失败
del [key] //释放锁,即删除锁
set [key] true ex 10nx //防止程序意外终止导致死锁,即设置过期时间

同时还可以存储对象数据,不过需要将对象数据转Json数据格式。

应用场景
1)计数器

incr article:readcount:{文章id} //针对文章id的阅读值,做原子性的+1操作
get article:readcount:{文章id} //获取阅读数

2)分布式系统全局序列号

increby orderid 100 //redis批量生成序列号提升性能
解释:一次操作取100个编号,利用自增部分来使用编号。从性能角度分析,原来是操作100次redis进行取值,现在只需要操作一次,从而实现性能提升。

(2)Hash

常用操作:

hset key field value //存储一个hash表key的值
hsetnx key key field value //存储一个不存在的hash表的值
hmset key field value [field value …] //在一个哈希表中存储多个键值对
hget key field //获取哈希表中key对应的field键值
hmget key field [key field …] //批量获取哈希表中的key对应的多个field键值
hdel key field [field …] //删除
hlen key //返回哈希表中key对应的field的数量
hgetall key //返回哈希表中key中所有的键值
hincrby key field increment //为哈希表中的key的field键的值加上增量increment

应用场景:
1)电商购物车

①以用户id为key
②商品id为field
③商品数量为value

2)购物车操作

①添加商品->hset cart:1001 10088 1
②增加数量->hincrby cart:1001 10088 1
③商品总数->hlen cart:1001
④删除商品->hdel cart:1001 10088
⑤获取购物车所有商品->hgetall cart:1001

(3)List

常用操作:

lpush key value [value …] //将一个或多个值value插入key列表的表头(最左边)
rpush key valye [value …] //将一个或多个值value插入key列表的表胃(最右边)
lpop key //移除并返回key列表的头元素
rpop key //移除并返回key列表的尾元素
lrange key start top //返回列表key中指定区间内的元素,区间以偏移量start和stop指定。(分正向索引和负向索引)
blpop key [key …] timeout //从key列表表头弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待
brpop key [key …] timeout //从key列表表尾弹出一个元素,若列表中没有元素,阻塞等待timeout秒,如果timeout=0,一直阻塞等待

常用的分布式数据结构:

Stack(栈) = lpush + lpop = FILO
Queue(队列) = lpush + rpop = FIFO
Blocking MQ(阻塞队列) = lpush + brpop

应用场景:
1)微博和微信公众号消息流
       诸葛老师关注了Caoz,备胎说车等大V。
①CaoZ发微博,消息id为10018

lpush msg:{诸葛老师-ID} 10018

②备胎说车发微博,消息id为10086

lpush msg{诸葛老师-id} 10086

③查看最新微博消息

lrange msg:{诸葛老师-id} 0 4

解释:可能存在关注同一个人,但是接收到新推送的消息存在延迟,因为底层实现排队发送,比如优先发送在线人员,在发送不在线的。

(4)Set

常用操作:
(后续补充)

应用场景:
1)抽奖程序(微信小程序等)

2)微信微博点赞、收藏、标签

3)集合操作实现电商商品筛选

集合的运算(实现关注模型)
1)交集
{a,b,c} {a,c} => {a,c}
2)差集
{a,b,c} {b,d,f,g} => {a,c}
3)并集
{a,b,c} {c,d,f,g} => {a,b,c,d,f,g}

(5)有序Set

常用操作:
(后续补充)

应用场景:
1)实现热榜排行前十等

底层实现结构:
1)压缩列表
(后续补充)

2)跳表
       当压缩列表达到一个大小时,会从压缩列表转化为跳表。跳表结构有点类似mysql底层数据结构,B+tree,即冗余排好序的序号作为结点头部,利用多路查询树的结构进行设计。

(二)分布式锁

(1)基于原生的redis命令setnx

       在redis中,基于setnx命令的操作,就可以实现分布式锁相关业务,与在Java中的redistemplate中是使用setIfAbsent是一致的。

(2)基于redission组件

       该组件就是基于一系列的分布式场景设置了许多类型的锁,比如基础的同步锁,读写锁等,读者可以自行探讨。
分布式锁的设计理念:
①对缓存内存进行设置(单值设置,如果存在多个线程进行设置时,只有一个线程能设置成功,其他线程失败);
②设置缓存失效时间;(解决因程序出错,导致死锁的问题)
③通过lua代码实现一个锁续命操作,底层成为看门狗,负责检测当前锁是否失效,如果没有,则重新设置锁的过期时间;注:lua代码的执行是一个原子性操作,意味着有么就全部操作正常,要么就全部操作失败;(确保原子性)

(三)缓存问题

       当业务代码涉及到先查询缓存,如果存在,则取出redis中的缓存值,并且返回,否则查询数据库,取到对应内容,再设置到缓存中,并且返回,此时就会出现下述前三个问题。

(1)缓存击穿(缓存失效)

解释:也叫热点Key问题,就是一个被高并发访问并且缓存重建业务较复杂(意味着对数据库压力相对较大)的key突然失效了,无数的请求访问会在瞬间给数据库带来巨大的压力,导致数据库服务挂掉(可以理解为redis的缓存暂时没有,此时高并发情况下,所有线程进到接口时,都会判断当前redis缓存不存在,因此会有大量的请求访问数据库)。
解决方法:
1、互斥锁:当同个业务不同线程访问redis未命中时,先获取一把互斥锁,然后进行数据库操作,此时另外一个线程未命中时,拿不到锁,等待一段时间后重新查询缓存,此时之前的线程已经重新把数据加载到redis之中了,线程二就直接缓存命中。这样就不会使得大量访问进入数据库。

(2)缓存穿透

解释:有一个商品被删掉了,但是在高并发情况下,首先去检查缓存,此时发现缓存没有,就去查询数据库,此时还是查询不到,然后就返回不了任何数据。
解决方案:当查询到数据库发现不存在时,可以设置一个空值,就可以避免所有请求直接访问数据库,减轻数据库压力。

(3)缓存雪崩

解释:当缓存在同一时间内大部分失效,此时导致所有的请求访问接口时,会同时访问数据库,造成数据库服务访问压力过大。
解决方法:在设置过期时间时,利用固定时间+随机数时间进行设置,避免同一时间大面积缓存失效。

(4)缓存和数据库双写不一致的问题

(后续补充)

(5)缓存数据冷热分离

解释:由于redis的资源有限,不可能将所有的数据都防止缓存中,因此只需要装热数据缓存在redis中即可,冷数据失效。具体实现原理为设置缓存过期时间即可。

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

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

相关文章

Cherno的Cpp教程笔记002:C++是如何工作的

include需要找到一个叫iostream的文件,然后将内容拷贝到当前的文件中来 main函数是程序的入口,main中调用了std::cout , main函数不一定需要返回值,当没有返回值时默认返回0 #include是预处理语句,编译器优先处理这些语句&#…

橘子学Mybatis03之代理模式

一、什么是代理模式,为啥需要代理模式 1、问题 在JAVAEE的MVC分层开发中,哪个层级对我们来说最重要? DAO ------> Service --------> ControllerJAVAEE分层开发中,最为重要的是Service层。这个也可以理解,因为S…

Lesson 8 The best and the worst 最好的和最差的

1.原文 2. 参考译文 3. New words and expressions ★competition n. 比赛,竞赛(暗地里的竞争) race n. 比赛,竞赛 car racematch n. 比赛 football matchcontest n. 比赛(更广泛)baby contest 宝宝大赛;beauty contest 选美game : 游戏, 运…

Spring自学日志01-IOC(控制翻转)

目录一、IOC的基本概念和底层原理1.1、什么是IOC?1.1.1、Spring IOC容器1.2、IOC底层原理1.2.1、IOC容器1.2.2、IOC容器装配Bean的方式1.2.3、IOC容器装配Bean的操作1.2.3.1、基于XML1.2.3.2、基于注解1.2.4、IOC容器装配Bean的作用域 一、IOC的基本概念和底层原理 1.1、什么是…

MySQL:索引特性

索引 0. 预备知识 索引是一个“物美价廉”的特性,用来提高数据库的性能。不需要改程序、调SQL、只需要正确的创建索引,查询速度就能提高成百上千倍,但查询速度的提升也带来了插入、更新、删除速度的下降。 0.1 认识磁盘 MySQL对数据进行增…

大数据讲课笔记2.1 初探大数据

文章目录零、学习目标一、导入新课二、新课讲解(一)什么是大数据(二)大数据的特征1、数据体量大2、数据类型多3、处理速度快4、价值密度低(三)研究大数据的意义(四)拥抱大数据时代1、…

【数据结构初阶】第四话 —— 动态栈的基本操作

文章目录什么是栈栈的结构1. 初始化栈2. 入栈3. 出栈4. 获取栈顶元素5. 获取栈中有效元素个数6. 检测栈是否为空7. 销毁栈8. 总结接口函数贴图什么是栈 假如有⼀个⼜细⼜⻓的圆筒,圆筒⼀端封闭,另⼀端开⼝。往圆筒⾥放⼊乒乓球,先放⼊的靠近…

U盘插入自动读写/U盘插入自动复制/pythhttps://www.cnblogs.com/wawawa888/p/16749476.htmlon检测U盘的插入,以及进行自动复制文件并写入文件

U盘自动读写的小玩意 共有四种方法(我知道的方法,全是转载。转载也很不易,可望给个硬币) 方法一(vbs方法 全自动,转载自bilibili 点我跳转)文件下载链接(点我下载) 方法二(cmd方法 需手动,转载自bilibili 点我跳转)文件下载链接(点我下载) 方法三(python方法 全…

在DataFrame中根据索引值进行排序:sort_index()函数

【小白从小学Python、C、Java】 【Python-计算机等级考试二级】 【Python-数据分析】 在DataFrame中根据索引值进行排序: sort_index()函数 [太阳]选择题 对以下python代码表述有误的选项是? import numpy as np import pandas as pd data np.random.…

ElasticSearch_03_批量处理命令mget和bulk的使用

系列文章目录 文章目录系列文章目录前言一、批量处理命令mget方案1:body请求体中指定index和type方案2:url中指定index和type,body中仅指定ids方案2扩展:url中指定index和type,body中仅指定id数组二、基于bulk的增删改…

C++开发坦克大战--补充(加入传送门)--附完整代码

目录 素材整理 穿越草地 坦克穿越草地 子弹穿越草地 传送门 判定形式 生成传送门 传送坦克 关卡模式 效果展示 ​总结 完整代码 上一篇坦克大战居然意外获得了一些关注,正好最近也完善了一些功能,同时也加入了一些自己想到的新元素,主要是…

python requests cookie的获取和使用

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、cookie是什么?二、使用步骤开始代码实现会话是什么然后写入我们的账号信息使用session访问登陆账号的url获取账号的书架上的数据完整的代码补充比…

基于javaweb在线投票管理系统ssm

基于SSM的在线投票系统以XXX学院为背景,运用在校所学习的软件开发原理,采用SpringSpringMVCMyBatis技术和MySQL数据库构建一个基于B/S模式的在线投票系统。 传统的投票模式都是通过人工手动填写问卷的方式来进行,这在很大程度上会造成人力和…

1.1 Ryu 的安装部署

What is Ryu Ryu是轻量级的、开源的SDN控制器Ryu是由日本NTT公司在2012年推出其名字在日文中的意思是“Flow”和“Dragon”的意思 Ryu架构 Ryu安装 在Ubuntu上装Ryu和Mininet,CSDN上搜教程,这一部分正确做法是对着视频敲代码如果有问题去CSDN上找解决办…

滤波器基础01——滤波器的种类与特性

滤波器是一种选频装置,它能够保留某一频段的信号,将此频段之外的信号消除。以下介绍不同分类依据下滤波器的特点。 一. 模拟滤波器与数字滤波器 根据滤波器的作用对象是模拟信号还是数字信号可将滤波器分为模拟滤波器和数字滤波器。 模拟滤波器处理模…

创建并运行一个 Spring Boot 项目

创建并运行一个 Spring Boot 项目引言第一个 Spring Boot 项目1. 创建一个 spring boot 项目第一步第二步第三步第四步2. 验证第一步第二步3. 写一个 hello world第一步解析代码第二步注意事项网页创建一个 Spring Boot 项目Spring Boot 的优点引言 Spring Boot 是 Spring 框架…

升级迭代:让我的颜色控制打印工具mypycolor更聪明,参数可以任意接收颜色控制码、颜色描述英文单词的任意组合。

【点击此处跳转笔记正文】Python 官网:https://www.python.org/ Free:大咖免费“圣经”教程《 python 完全自学教程》,不仅仅是基础那么简单…… My CSDN主页、My HOT博、My Python 学习个人备忘录好文力荐、 老齐教室 自学并不是什么神秘的…

YOLOV+pytorch+win10+CPU环境配置

Step 1:下载github YOLOV3源码 链接:https://github.com/ultralytics/yolov3 Step 2:配置CPUpytorch版本环境 WinR启动cmd,在命令提示符内输入以下命令,创建一个新环境: conda create –n yolov-pytorc…

记录自学的学习路线(详细)

目录 HTML css javaScript javaScript高级 jQuery(快速过一遍) bootstrap 移动端适配 ajax ES6 Vue2vue3全家桶(vue3暂时不学,后面会解释原因) axios promise vue2结束后 Vue3 Ts 依我而言 曾经我也迷茫过,如何学习…

JWT 和 JJWT 还傻傻的分不清吗

JWTs是JSON对象的编码表示。JSON对象由零或多个名称/值对组成,其中名称为字符串,值为任意JSON值。 JWT有助于在clear(例如在URL中)发送这样的信息,可以被信任为不可读(即加密的)、不可修改的(即签名)和URL - safe(即Base64编码的)。 JSON Web Token (JWT) 作为一个开放的标准…