Redis缓存何以一枝独秀?以及热门面试题中Redis的核心特性

news2025/7/6 22:15:03

​Redis的各种数据类型

作为缓存组件,Redis的数据结构整体而言就是key-value类型的键值对,但是Redis对于value类型的支持还是比较丰富的,提供了5种不同的数据结构,可以满足大部分场景的使用诉求。

​对几种类型的结构特点与使用注意点梳理汇总如下:

类型

说明

支持功能

string

普通字符串

字符串的基础增删改查能力,如果是整数或者浮点数,还支持自增自减能力。

list

链表内容,每个元素都是一个独立的字符串,内容可以相同

基础增删改查能力,从链表两端插入或者弹出元素,按照下标获取指定元素列表等等

set

无序集合,每个元素都是一个独立字符串,元素之间不允许重复

基础增删改查能力,判断元素是否存在,随机获取元素等等

hash

无序的key-value键值对集合

基础增删改查能力,获取所有的键值对

zset

可以理解为一种比较特殊的hash结构,含有member和score两个概念,对应到hash类型上分别是key与value的关系,其区别点在在于score是固定的double类型的value

基础增删改查能力,支持根据score排序并获取指定的排序个数的元素列表

实际的使用中,也会根据各自类型不同的特点,用来实现不同的业务诉求。

举个例子:

一个系统内的通知公告查看功能,可以将公告ID作为key,然后这边通知公告的阅读量作为score,在redis中存储为zset类型,然后每次读取详情操作的都累加更新下对应的score值,这样的话,就可以根据score进行降序排列,拉取到热门新闻公告的排行榜。

Redis的百变应用场景

基于Redis提供的基础能力,在项目中不同场景都有被广泛的使用,下面列举几个常见的使用场景。

  • 分布式锁

在分布式系统里面经常会需要用到分布式锁,实现分布式锁的方式有很多种,其中使用的比较广泛的一种策略,就是基于Redis来实现的。之所以采用Redis来作为分布式锁,可以有几方面理由:

  1. redis足够的快

  2. redis提供了setnx + expire的机制,完全契合分布式锁的实现要点

  3. Redisson客户端的流行,使得基于redis的分布式锁更加简单

  • 数据库扛压层

借助redis超高的处理性能,经常会被放置在数据库的前面,用于数据扛压场景使用。比如各种秒杀场景,可以将数据库中的库存信息缓存到redis中,然后利用redis来抗住秒杀期间洪水般的大并发量请求。

  • 登录验证码存储

这个场景也很常见,比如用户发送的短信验证码,一般都会要求5分钟内有效。这种情况下,可以将验证码信息存储在redis中并设定5分钟后自动过期。这样的话就可以实现超时失效的功能,而无需业务层面去维护过期信息。

  • 全局ID生成&全局限流

在分布式系统中,Redis作为一个可以被所有节点访问的集中节点,加上其具备的incrby原子命令,使得在多个场景下发挥价值:

  1. 将其用作全局唯一ID的生成,以保证各个节点之间生成的唯一ID不会冲突。

  2. incrby可以实现全局请求量的统计计数,结合expire一起可以实现定时重置计数器,进而实现限流能力。

  • bitmap方式存储每日签到数据

其实,Redis还支持位图(Bitmap)格式进行数据存储。前面我们说Redis支持五种数据结构里面并没有看到Bitmap类型的身影,其实Redis的bitmap数据最终存储的是string类型,但是Redis为Bitmap操作提供了配套的操作接口,比如setbit命令。

位图的存在就是为了服务于海量数据的存储场景的,比如系统里面有10亿用户,现在需要记录每个人每天的签到情况,每天10亿数据量,如果用普通String类型存储,每天10亿条数据量,时间一久任何的Redis也扛不住。而基于bitmap的方式存储,则可以极大的降低整体数据量。关于redis的bitmap操作与使用,后面文章会展开阐述。

  • 热门榜单生成

基于Redis的zset数据结构,可以将热门值作为score进行存储,这样可以根据需要,按照score进行排序并拉取榜单数据。

后端面试中的常客

这篇文章中,我们改变下以往的文章行文叙事风格。我们先不直接切入到Redis的具体特性或功能点的实现原理与使用层面,而是先从面试场景作为切入口,通过几个面试问题,来感受下Redis整体的“魅力”、引出Redis所具备的核心特性与常见使用注意事项。

因为Redis在项目中的广泛使用,也让其成为了后端面试中的热门嘉宾。很多小伙伴应该在面试中都被问过与Redis有关的问题吧?当然有很多的八股文背诵一下就可以应付很多简单的面试场景,但笔者作为面试官一般不太会直接去问八股文问题,经常会将问题稍作包装之后再去问。

下面举几个例子。

Q1. 很多人都说Redis处理快是因为它是单线程的,Redis进程中真的只有一个线程吗?为什么常规项目中为了提升并发量都会采用线程池等方式来多线程处理,而Redis却反其道而行之呢?

很多的面试八股文中都会提到说Redis是单线程的,这个说法其实不够严谨,因为Redis中并非是只有一个线程,整个进程中还有一些额外的线程负责做一些辅助的其他事务,比如管理与客户端的连接,比如队列中消息的维护等等。

Redis整体基于一种多路复用的机制来实现请求的接收与分配处理。整体简化后的处理逻辑如下图所示。

​所以说,其实Redis仅仅是采用单线程来负责执行命令请求处理,而非整个Redis就是一个单线程的。回到最初的问题,为什么Redis选择采用单线程的方式来执行命令。在多线程编程的时候面临问题主要有:

  • 并发线程安全问题, 需要保证操作的先后顺序,需要保证同一时刻只能有1个线程对某个对象进行写操作 —— 需要构建完备的同步保护机制,会对整体性能造成影响。

  • 多线程维护的系统额外开销 —— CPU需要不停的在多个线程之间进行切换,由此会带来一系列的额外开销。

而由于Redis是一种key-value模型的数据结构模式,比如很多查询操作都是O(1)的时间复杂度,其操作执行速度非常快,所以这种情况下,结合I/O多路复用模型一起,使用单线程的方式执行命令,反而可以达到比多线程更加优异的表现。

问题可以进一步引申,可以继续聊一些其他问题。比如:

  • 既然Redis是单线程的,那使用的时候有什么需要注意的事项吗? 不能执行耗时操作,会阻塞其余请求命令的执行。

  • I/O多路复用是个什么概念?它和BIO、NIO之间有什么异同? 诸如此类的问题,都可以进一步的去展开考察。

  • 当前计算机一般都是多核CPU,用单线程去执行的话,相当于其它几个核就浪费了,那有什么方式可以将其余的几个核也利用起来么? 答案其实也不难,在一台机器上同时去部署多个Redis进程,组成个集群,就可以啦。

Q2. 如果我想要查询一下生产环境的Redis中有多少以“User_”开头的记录数量,可以怎么做?

这个问题其实是有一点小陷阱的。查找以指定前缀开头的记录,首先很多同学想到的就是keys命令,但问题中有个约束是在生产环境中执行。所以这个问题看似简单,其实需要结合如下几点来综合考虑:

  1. 通常情况下,生产环境中的数据量是非常大的、且请求并发量会比较高;

  2. Redis的keys命令是一个耗时操作,复杂度O(n),数据量越大执行速度越慢;

  3. Redis的命令执行是单线程执行的。

基于上述几点因素,如果在数据量较大的生产环境去执行keys命令将会导致执行耗时特别长,而由于Redis是单线程执行命令,就会导致其余请求命令被阻塞无法执行,这样在一个高并发集群内,很容易造成集群内请求的大面积阻塞,影响系统的整体稳定性。

那么keys命令不可以用,有什么替代方案呢?可以使用scan命令。

Q3. 假如有一批机器,内存都比较小(单机内存小于整体待缓存数据量),用来搭建个Redis做热点数据缓存扛压以降低数据库的请求压力。如果你来做的话,会有哪些应对思路呢?

这个问题就比较开放,而且答案也不唯一,考核的点也比较综合。

首先来分析下题目,从题干描述中可以捕捉到几个信息,以及对应的关联知识点:

  1. 单机内存小于整体数据量,所以想要将所有数据全量加载到单机内存里面是不可行的;

  2. 使用Redis的用途是扛压来降低数据库访问压力的,也就是允许部分请求穿透Redis打到数据库上的,所以可以考虑将有限内存用来存放热点数据,扛住大部分的流量;

  3. 题目说有一批机器,就是说机器的数量不止一台,所以可以考虑构建集群的方式,扩展Redis集群总内存大小,这样以集群的力量来缓存全部的数据量。

所以说这个题目里面其实涉及到了两个考点:

  1. 热点数据的概念、也即Redis的数据淘汰策略。

  2. Redis集群扩展的相关概念。

更进一步,又可以引申出很多其它细节问题,比如:

  • Redis中的数据淘汰策略有哪些? no-enviction、volatile-lru、volatile-ttl、volatile-random、allkeys-lru、allkeys-random

  • Redis的数据淘汰策略与数据过期有啥区别? 数据过期是达到了设定的过期时间之后使数据不可用,而数据淘汰策略主要是在容量满之后采取的被动应对策略。

  • Redis集群中是如何决定一个记录应该保存在哪个节点上的? 关于一致性Hash相关的内容,以及如何解决数据倾斜问题、节点扩容对缓存命中情况的影响等等。

回头看下,是不是其中蕴含的内容还是蛮多的?

这里我们以面试场景中会被问及的几个问题作为切入点,大概聊了下与Redis有关的一系列内容。当然这里介绍的都比较浅显,甚至只是列了下相关的知识点,主要是先让大家先感受下Redis所包含与涉及的相关知识点。在后续的文章中,我们将逐步逐个地去剖析与介绍。

小结回顾

我们只是简单的聊了下Redis的基础概念以及主要的特性介绍,同时通过几个实际的面试题演示了下Redis整体内容的“博大精深”。而关于Redis的更多细化方向的展开阐述,我们将会在后续文章中逐步介绍。那么你对Redis如何看呢?欢迎评论区一起交流下,期待和各位小伙伴们一起切磋、共同成长。

公众号:Java收藏夹

 

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

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

相关文章

3天3定制大屏,反向PUA

摘要 本次分享一段无讨价还价余地的单人3天定制化大屏全过程(强调说拖拽屏的请绕道,和你想的不一样),要动效、要地图、要流光。天坑的心理博弈到最终解决的过程及技术思路。 前因 没啥征兆突然接到说,要在下周完成2个大屏的定制开发,起初没提…

C51 - 定时器

Contents1> 概述(STC89C51RC/RD)2> 作用: CPU的 "闹钟"3> 工作原理 (16位计数器)[TL0 TH0]: 数据寄存器TF: 定时器<溢出>标志位4> 程序设计1> 概述(STC89C51RC/RD) STC89C51RC/RD 定时器数量: 3个; T0模式:工作模式 模式0: 13位计数器; 模式1: …

理解循环神经网络

理解循环神经网络 之前有一篇文章已经初步介绍过RNN的原理(https://forchenxi.github.io/2021/04/23/nlp-rnn/)&#xff0c;里面其实已经介绍的比较清晰易懂了&#xff0c;这篇文章再来回顾和拓展一下. 首先要知道RNN是一个带有内部环的神经网络&#xff0c;上面的这篇文章中…

港科夜闻|香港科大(广州)校长倪明选教授出席江门双碳实验室第一届理事会一次会议...

关注并星标每周阅读港科夜闻建立新视野 开启新思维1、香港科大(广州)校长倪明选教授出席江门双碳实验室第一届理事会一次会议。11月21日下午&#xff0c;江门双碳实验室召开第一届理事会一次会议&#xff0c;审议通过有关文件&#xff0c;完善实验室组织架构&#xff0c;谋划下…

Python之条件语句逻辑运算符

目录 一、逻辑运算符 1.基本运算符 2.比较运算符 3.赋值运算符 二、 if条件语句 三、循环语句 一、逻辑运算符 1.基本运算符 2.比较运算符 3.赋值运算符 # 条件语句逻辑运算符 print((5 / 2)) print((5 // 2)) print((3 ** 2)) #3的2次方# 递增 # a1 # a1 # print(a) # a,b…

主流的深度学习推理架构有哪些(NCNNN)

AI 技术在具体落地应用方面&#xff0c;和其他软件技术一样&#xff0c;也需要具体的部署和实施。部署对于不同的平台设备上的部署方法和不同的架构工具。目前在人工智能的落地部署方面&#xff0c;各大平台机构都退出了自家的部署平台。 目前市场上应用最广泛的部署工具主要有…

用DIV+CSS技术设计的网上书城网页与实现制作(大一Web课程设计)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Java项目:JSP中华传统美食网站平台管理系统

作者主页&#xff1a;源码空间站2022 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 作者主页&#xff1a;夜未央5788 简介&#xff1a;Java领域优质创作者、Java项目、学习资料、技术互助 文末获取源码 项目介绍 本项目分为前台与后台&…

【网页设计】基于HTML+CSS+JavaScript学生网上报到系统响应式网站

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

计算机网络---万维网(WWW)

&#xff08;一&#xff09;WWW的概念与组成结构 万维网&#xff08;World Wide Web&#xff0c;WWW)是一个分布式、联机式的信息存储空间&#xff0c;在这个空间中:一样有用的事物称为一样“资源”&#xff0c;并由一个全域“统一资源定位符”(URL&#xff09;标识。这些资源通…

Scala的简单语法介绍

文章目录变量声明语句块if语句for循环while、do while数组Map映射tuple元组变量声明 //在Scala中val用于定义常量&#xff0c;var用于定义变量 var var_i 1 var_i 1val val_i 1 val_i 1 val_i 2运行结果如下&#xff1a; 可以看到&#xff0c;常量是初始复制就确定了&am…

Hello Erupt

前言 本系列将直接以Erupt的分布式方案为路线进行更新。本文的定位是Erupt的HelloWorld。目标&#xff0c;跑起来&#xff0c;让我们看看它是什么样的。 运行起来 准备一个数据库 第一步还是先运行起来。由于最近接触的公司项目都是在使用mysql的驱动&#xff0c;这里我也就…

python+人脸识别+opencv实现真实人脸驱动的阿凡达(上)

目录一、前言二、技术路线三、主要技术点分析(1) 人脸识别模块特征点的漂移(2) 柔性运动与刚性运动的处理setp1 基于人脸特征点的三角剖分setp2 基于三角映射的仿射变换(3) 正脸转侧脸的处理四、小结一、前言 我们在此前的名叫pythonopencv实现人脸微整形博文里已经简单地实现…

Java GUI图形编程 使用awt和swing 制作简易计算器的工具包含源码和讲解 / java练习项目

系列文章目录 提示&#xff1a;阅读本章之前&#xff0c;请先阅读目录 文章目录系列文章目录前言一、常规配置1. 设置窗口大小2. 获取当前屏幕的尺寸3. 窗口居中4. 设置窗口名称5. 添加监听器&#xff0c;关闭窗口6. 设置窗口可见性7. 设置文本框不可编辑8. 设置文本框提示9. 设…

OpenGL原理与实践——核心模式(六):光照贴图、光源分类以及多光源场景主要源码实现

本章主要以代码为主&#xff0c;理论理解即可。详细分析代码 目录 光照贴图 光源分类 平行光 点光源 shader——点光源 聚光灯 聚光灯边缘优化——光强递减 源码解析 main 全局变量、句柄 main函数主体逻辑 createModel() createTexture(const char* _filename) …

骨感传导蓝牙耳机怎么样,骨感传导耳机对于我们耳道是否有保护

在现在数码产品普及生活的时代&#xff0c;耳机也成为了我们每天的标准&#xff0c;以往佩戴的都是入耳式的耳机&#xff0c;但长时间佩戴下会出现耳朵疼痛&#xff0c;严重的更会导致听力障碍的问题发生&#xff0c;针对这一现象&#xff0c;一种新型的骨感传导耳机来到了我们…

后台默默付出的劳动者,四大组件之服务(Service)

后台默默付出的劳动者&#xff0c;四大组件之服务Service前言十、后台默默付出的劳动者&#xff0c;四大组件之服务&#xff08;Service&#xff09;10.1 服务是啥&#xff1f;10.2 Android异步消息处理机制10.2.1 Android异步消息处理机制介绍10.2.2 基于Android异步消息处理机…

Packet Tracer - 排除多区域 OSPFv2 故障

地址分配表 设备 接口 IP 地址 子网掩码 默认网关 ISP GigabitEthernet0/0 209.165.200.17 255.255.255.240 不适用 ASBR GigabitEthernet0/0 209.165.200.18 255.255.255.240 不适用 Serial0/0/0 10.1.1.2 255.255.255.252 不适用 Serial0/0/1 10.2.2…

制作一个企业网站——html华为官网购物商城项目的设计与实现

常见网页设计作业题材有 个人、 美食、 公司、 学校、 旅游、 电商、 宠物、 电器、 茶叶、 家居、 酒店、 舞蹈、 动漫、 服装、 体育、 化妆品、 物流、 环保、 书籍、 婚纱、 游戏、 节日、 戒烟、 电影、 摄影、 文化、 家乡、 鲜花、 礼品、 汽车、 其他等网页设计题目, A…

【Redis】使用 Java 客户端连接 Redis

一、三种客户端比较 Jedis : 学习成本低&#xff0c;以 Redis 命令作为方法名称&#xff0c;但是其线程不安全 lettuce&#xff1a;基于 Netty 实现&#xff0c;支持同步、异步、响应式编程&#xff08;SpringBoot&#xff09;&#xff0c;并且线程安全。支持 Redis 的哨兵模…