Redis 总结精讲

超级详细 的 Redis 安装教程 1、双击 启动 Redis2、打开cmd,进入到刚才解压到的目录,启动临时服务:默认端口:6379 有的机器双击 redis-server.exe 执行失败,找不到配置文件,可以采用以下执行方式: 在命令行(cmd)中按如下方式执行: 打开另一个cmd窗口,客户端调用:1、进入Redis安装包目录,安装服务: 2、,可以看到服务安装成功 将d盘下新建一个文件夹叫redis2,把redis文件夹的东西拷贝到redis2文件夹下,将redis-windows.conf配置文件中的ip 和端口号改一下,然后按照 阅读详情

Redis 总结精讲 
1、为什么使用redis
2、使用redis有什么缺点
3、单线程的redis为什么这么快
4、redis的数据类型,以及每种数据类型的使用场景
5、redis的过期策略以及内存淘汰机制
6、redis和数据库双写一致性问题
7、如何应对缓存穿透和缓存雪崩问题
8、如何解决redis的并发竞争问题

 

正文

 

1、为什么使用redis

 

分析:博主觉得在项目中使用redis,主要是从两个角度去考虑:性能和并发。当然,redis还具备可以做分布式锁等其他功能,但是如果只是为了分布式锁这些其他功能,完全还有其他中间件(如zookpeer等)代替,并不是非要使用redis。因此,这个问题主要从性能和并发两个角度去答。


回答:如下所示,分为两点


(一)性能


如下图所示,我们在碰到需要执行耗时特别久,且结果不频繁变动的SQL,就特别适合将运行结果放入缓存。这样,后面的请求就去缓存中读取,使得请求能够迅速响应。



 

题外话:忽然想聊一下这个迅速响应的标准。其实根据交互效果的不同,这个响应时间没有固定标准。不过曾经有人这么告诉我:”在理想状态下,我们的页面跳转需要在瞬间解决,对于页内操作则需要在刹那间解决。另外,超过一弹指的耗时操作要有进度提示,并且可以随时中止或取消,这样才能给用户最好的体验。”


那么瞬间、刹那、一弹指具体是多少时间呢?


根据《摩诃僧祗律》记载

 

一刹那者为一念,二十念为一瞬,二十瞬为一弹指,二十弹指为一罗预,二十罗预为一须臾,一日一夜有三十须臾。

 

那么,经过周密的计算,一瞬间为0.36 秒,一刹那有 0.018 秒.一弹指长达 7.2 秒。

 

(二)并发

 

如下图所示,在大并发的情况下,所有的请求直接访问数据库,数据库会出现连接异常。这个时候,就需要使用redis做一个缓冲操作,让请求先访问到redis,而不是直接访问数据库。


 

2、使用redis有什么缺点

 

分析:大家用redis这么久,这个问题是必须要了解的,基本上使用redis都会碰到一些问题,常见的也就几个。


回答:主要是四个问题


(一)缓存和数据库双写一致性问题

(二)缓存雪崩问题

(三)缓存击穿问题

(四)缓存的并发竞争问题


这四个问题,我个人是觉得在项目中,比较常遇见的,具体解决方案,后文给出。

 

3、单线程的redis为什么这么快

 

分析:这个问题其实是对redis内部机制的一个考察。其实根据博主的面试经验,很多人其实都不知道redis是单线程工作模型。所以,这个问题还是应该要复习一下的。


回答:主要是以下三点


(一)纯内存操作
(二)单线程操作,避免了频繁的上下文切换
(三)采用了非阻塞I/O多路复用机制

 

题外话:我们现在要仔细的说一说I/O多路复用机制,因为这个说法实在是太通俗了,通俗到一般人都不懂是什么意思。博主打一个比方:小曲在S城开了一家快递店,负责同城快送服务。小曲因为资金限制,雇佣了一批快递员,然后小曲发现资金不够了,只够买一辆车送快递。


经营方式一


客户每送来一份快递,小曲就让一个快递员盯着,然后快递员开车去送快递。慢慢的小曲就发现了这种经营方式存在下述问题

 

  • 几十个快递员基本上时间都花在了抢车上了,大部分快递员都处在闲置状态,谁抢到了车,谁就能去送快递

  • 随着快递的增多,快递员也越来越多,小曲发现快递店里越来越挤,没办法雇佣新的快递员了

  • 快递员之间的协调很花时间

 

综合上述缺点,小曲痛定思痛,提出了下面的经营方式


经营方式二


小曲只雇佣一个快递员。然后呢,客户送来的快递,小曲按送达地点标注好,然后依次放在一个地方。最后,那个快递员依次的去取快递,一次拿一个,然后开着车去送快递,送好了就回来拿下一个快递。

 

对比


上述两种经营方式对比,是不是明显觉得第二种,效率更高,更好呢。在上述比喻中:

 

  • 每个快递员——————>每个线程

  • 每个快递——————–>每个socket(I/O流)

  • 快递的送达地点————–>socket的不同状态

  • 客户送快递请求————–>来自客户端的请求

  • 小曲的经营方式————–>服务端运行的代码

  • 一辆车———————->CPU的核数

 

于是我们有如下结论


1、经营方式一就是传统的并发模型,每个I/O流(快递)都有一个新的线程(快递员)管理。


2、经营方式二就是I/O多路复用。只有单个线程(一个快递员),通过跟踪每个I/O流的状态(每个快递的送达地点),来管理多个I/O流。

 

下面类比到真实的redis线程模型,如图所示



 

参照上图,简单来说,就是。我们的redis-client在操作的时候,会产生具有不同事件类型的socket。在服务端,有一段I/0多路复用程序,将其置入队列之中。然后,文件事件分派器,依次去队列中取,转发到不同的事件处理器中。


需要说明的是,这个I/O多路复用机制,redis还提供了select、epoll、evport、kqueue等多路复用函数库,大家可以自行去了解。

 

4、redis的数据类型,以及每种数据类型的使用场景

 

分析:是不是觉得这个问题很基础,其实我也这么觉得。然而根据面试经验发现,至少百分八十的人答不上这个问题。建议,在项目中用到后,再类比记忆,体会更深,不要硬记。基本上,一个合格的程序员,五种类型都会用到。


回答:一共五种


(一)String


这个其实没啥好说的,最常规的set/get操作,value可以是String也可以是数字。一般做一些复杂的计数功能的缓存。


(二)hash


这里value存放的是结构化的对象,比较方便的就是操作其中的某个字段。博主在做单点登录的时候,就是用这种数据结构存储用户信息,以cookieId作为key,设置30分钟为缓存过期时间,能很好的模拟出类似session的效果。


(三)list


使用List的数据结构,可以做简单的消息队列的功能。另外还有一个就是,可以利用lrange命令,做基于redis的分页功能,性能极佳,用户体验好。本人还用一个场景,很合适---取行情信息。就也是个生产者和消费者的场景。LIST可以很好的完成排队,先进先出的原则。


(四)set


因为set堆放的是一堆不重复值的集合。所以可以做全局去重的功能。为什么不用JVM自带的Set进行去重?因为我们的系统一般都是集群部署,使用JVM自带的Set,比较麻烦,难道为了一个做一个全局去重,再起一个公共服务,太麻烦了。


另外,就是利用交集、并集、差集等操作,可以计算共同喜好,全部的喜好,自己独有的喜好等功能。


(五)sorted set


sorted set多了一个权重参数score,集合中的元素能够按score进行排列。可以做排行榜应用,取TOP N操作。

 

5、redis的过期策略以及内存淘汰机制

 

分析:这个问题其实相当重要,到底redis有没用到家,这个问题就可以看出来。比如你redis只能存5G数据,可是你写了10G,那会删5G的数据。怎么删的,这个问题思考过么?还有,你的数据已经设置了过期时间,但是时间到了,内存占用率还是比较高,有思考过原因么?


回答:


redis采用的是定期删除+惰性删除策略。


为什么不用定时删除策略?


定时删除,用一个定时器来负责监视key,过期则自动删除。虽然内存及时释放,但是十分消耗CPU资源。在大并发请求下,CPU要将时间应用在处理请求,而不是删除key,因此没有采用这一策略.


定期删除+惰性删除是如何工作的呢?


定期删除,redis默认每个100ms检查,是否有过期的key,有过期key则删除。需要说明的是,redis不是每个100ms将所有的key检查一次,而是随机抽取进行检查(如果每隔100ms,全部key进行检查,redis岂不是卡死)。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。


于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。


采用定期删除+惰性删除就没其他问题了么?


不是的,如果定期删除没删除key。然后你也没即时去请求key,也就是说惰性删除也没生效。这样,redis的内存会越来越高。那么就应该采用内存淘汰机制。


在redis.conf中有一行配置

 

# maxmemory-policy volatile-lru

 

该配置就是配内存淘汰策略的(什么,你没配过?好好反省一下自己)

 

1)noeviction:当内存不足以容纳新写入数据时,新写入操作会报错。应该没人用吧。

 

2)allkeys-lru:当内存不足以容纳新写入数据时,在键空间中,移除最近最少使用的key。推荐使用,目前项目在用这种。

 

3)allkeys-random:当内存不足以容纳新写入数据时,在键空间中,随机移除某个key。应该也没人用吧,你不删最少使用Key,去随机删。

 

4)volatile-lru:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,移除最近最少使用的key。这种情况一般是把redis既当缓存,又做持久化存储的时候才用。不推荐

 

5)volatile-random:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,随机移除某个key。依然不推荐

 

6)volatile-ttl:当内存不足以容纳新写入数据时,在设置了过期时间的键空间中,有更早过期时间的key优先移除。不推荐

 

ps:如果没有设置 expire 的key, 不满足先决条件(prerequisites); 那么 volatile-lru, volatile-random 和 volatile-ttl 策略的行为, 和 noeviction(不删除) 基本上一致。

 

6、redis和数据库双写一致性问题

 

分析:一致性问题是分布式常见问题,还可以再分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题。答这个问题,先明白一个前提。就是如果对数据有强一致性要求,不能放缓存。我们所做的一切,只能保证最终一致性。另外,我们所做的方案其实从根本上来说,只能说降低不一致发生的概率,无法完全避免。因此,有强一致性要求的数据,不能放缓存。

 

首先,采取正确更新策略,先更新数据库,再删缓存。其次,因为可能存在删除缓存失败的问题,提供一个补偿措施即可,例如利用消息队列。

 

7、如何应对缓存穿透和缓存雪崩问题

 

分析:这两个问题,说句实在话,一般中小型传统软件企业,很难碰到这个问题。如果有大并发的项目,流量有几百万左右。这两个问题一定要深刻考虑。

 

回答:如下所示

 

缓存穿透,即黑客故意去请求缓存中不存在的数据,导致所有的请求都怼到数据库上,从而数据库连接异常。

 

解决方案:

 

(一)利用互斥锁,缓存失效的时候,先去获得锁,得到锁了,再去请求数据库。没得到锁,则休眠一段时间重试

 

(二)采用异步更新策略,无论key是否取到值,都直接返回。value值中维护一个缓存失效时间,缓存如果过期,异步起一个线程去读数据库,更新缓存。需要做缓存预热(项目启动前,先加载缓存)操作。

 

(三)提供一个能迅速判断请求是否有效的拦截机制,比如,利用布隆过滤器,内部维护一系列合法有效的key。迅速判断出,请求所携带的Key是否合法有效。如果不合法,则直接返回。

 

缓存雪崩,即缓存同一时间大面积的失效,这个时候又来了一波请求,结果请求都怼到数据库上,从而导致数据库连接异常。

 

解决方案:

 

(一)给缓存的失效时间,加上一个随机值,避免集体失效。

 

(二)使用互斥锁,但是该方案吞吐量明显下降了。

 

(三)双缓存。我们有两个缓存,缓存A和缓存B。缓存A的失效时间为20分钟,缓存B不设失效时间。自己做缓存预热操作。然后细分以下几个小点

 

  • I 从缓存A读数据库,有则直接返回

  • II A没有数据,直接从B读数据,直接返回,并且异步启动一个更新线程。

  • III 更新线程同时更新缓存A和缓存B。

 

8、如何解决redis的并发竞争key问题

 

分析:这个问题大致就是,同时有多个子系统去set一个key。这个时候要注意什么呢?大家思考过么。需要说明一下,博主提前百度了一下,发现答案基本都是推荐用redis事务机制。博主不推荐使用redis的事务机制。因为我们的生产环境,基本都是redis集群环境,做了数据分片操作。你一个事务中有涉及到多个key操作的时候,这多个key不一定都存储在同一个redis-server上。因此,redis的事务机制,十分鸡肋。


回答:如下所示


(1)如果对这个key操作,不要求顺序


这种情况下,准备一个分布式锁,大家去抢锁,抢到锁就做set操作即可,比较简单。


(2)如果对这个key操作,要求顺序


假设有一个key1,系统A需要将key1设置为valueA,系统B需要将key1设置为valueB,系统C需要将key1设置为valueC.


期望按照key1的value值按照 valueA–>valueB–>valueC的顺序变化。这种时候我们在数据写入数据库的时候,需要保存一个时间戳。假设时间戳如下

 

系统A key 1 {valueA  3:00}

系统B key 1 {valueB  3:05}

系统C key 1 {valueC  3:10}

 

那么,假设这会系统B先抢到锁,将key1设置为{valueB 3:05}。接下来系统A抢到锁,发现自己的valueA的时间戳早于缓存中的时间戳,那就不做set操作了。以此类推。

 

其他方法,比如利用队列,将set方法变成串行访问也可以。总之,灵活变通。

Redis进行数据分页减轻DB的压力 redis分页: 1)redis相比mysql,速度比较快,用户体验好。 2)不经常变化的数据,可以使用redis存储,比如公司介绍等。 3)在mysql中操作后,存储到数据库中;下次在获取数据的时候,先从redis中查询,如果有就直接获取,如果没有在查询数据库。 4)过期时间设置:过期后,就会删除此条数据;然后数据只能从mysql中查询。 5)redis入门使用我之前博客 Redis缓存分页 1... 阅读详情

相关推荐

R2M缓存介绍-业务使用方面.pptx

R2M缓存介绍-业务使用方面

redis学习

本文围绕以下几点进行阐述 1、为什么使用redis 2、使用redis有什么缺点 3、单线程的redis为什么这么快 4、redis的数据类型,以及每种数据类型的使用场景 5、redis的过期策略以及内存淘汰机制 6、redis和数据库双写一致性问题 7、如何应对缓存穿透和缓存雪崩问题 8、如何解决redis的并发竞争问题 1、为什么使用redis 分析:博主觉得在项目中使用redi...

seulzz的博客 4157

专栏丨华为HN8145XR光猫获取超级管理员密码

摘要:本文详细介绍了华为HN8145xr光猫获取超级管理员权限的完整步骤。首先通过ONT使能工具补全shell,然后利用Telnet登录光猫后台进行操作。文章提供了多种获取超级密码的方法,包括配置文件解密、一键查询工具等,并针对联通光猫特别说明了默认密码格式(CUAdmin+后八位数字)。此外,还介绍了恢复出厂设置、修改SSID等实用操作,帮助用户完全掌控光猫设备。文末附有详细的命令行操作指南,适合有一定技术基础的用户参考。

8283

My-Redis

Redis是什么 Redis是一个开源的底层使用C语言编写的key-value内存数据库。可用于缓存数据、事件发布订阅、高速队列等场景,而且支持丰富的数据类型:string(字符串)、hash(哈希)、list(列表)、set(无序集合)、zset(有序集合)。 使用场景 随着数据量的增长,MySQL已经满足不了大型互联网类应用的需求。因此,Redis基于内存存储数据,在某些场景下,就会大大提高效...

qq_43508801的博客 709

【Excel VBA 编程】批量核对两张表格数据,行和列显示顺序均被打乱

利用数据字典在 Excel 中进行表格数据的核对,该表格含有多行多列,并且行和列顺序是打乱的,批量核对数据后将差异输出

wei1019的专栏 1293

手把手教你用FPGA+AD9822搭建300DPI的CIS高速图像采集系统(附时序调试心得)

本文详细介绍了如何利用FPGA作为核心控制器,结合AD9822三通道采样保持放大器/ADC,构建一套完整的300DPI CIS高速图像采集系统。内容涵盖从CIS传感器驱动时序、AD9822寄存器配置与协同调试,到采用千兆以太网替代USB实现稳定高速数据传输的完整实战指南,并分享了关键的时序调试心得与系统集成经验。

weixin_29306261的博客 135

Redis面试精讲 Day 18:Redis网络优化与连接管理

理解Redis单线程网络模型掌握连接池实现原理熟悉关键网络配置参数能够诊断连接相关问题学会安全网络实践。

在未来等你的专栏 742

Acgis中实现栅格经纬度和行政区关联

目前已有意大利的shp文件,希望将意大利划分成0.1*0.1经纬度的栅格,并且关联每个栅格中心点所属的省份信息。最终希望得到的输出是一个表格,里面包含栅格的经纬度、所属省份信息。

qq_42183184的博客 3369

Redis面试精讲 Day 17:Redis内存优化最佳实践

理解Redis内存组成和分配原理掌握各种数据结构的优化方法熟悉内存淘汰策略的选择能够处理内存碎片问题学会分析监控内存使用。

在未来等你的专栏 938

Jetson Nano官方镜像下载&烧录

在NVIDIA Jetson Nano开发者套件上安装NVIDIA官方Ubuntu镜像

weixin_44222088的博客 8854

Vivado SDK中LWIP库版本冲突与RTL8211FDI兼容性实战解析

本文深入解析Vivado 2019.1 SDK中LWIP 1.0库与RTL8211FDI千兆PHY芯片的版本冲突问题,并提供实战解决方案。通过手动移植高版本LWIP库、整合第三方驱动及优化BSP配置,有效解决了以太网通信兼容性问题,确保千兆性能稳定运行。

ios99的博客 275

Redis面试精讲 Day 3:Redis持久化机制详解

Redis持久化是指将内存中的数据以特定格式保存到磁盘的过程,目的是在Redis服务重启后能够恢复数据。Redis提供了两种主要的持久化方式:| 持久化方式 | 原理 | 数据安全性 | 恢复速度 || RDB | 定时生成内存快照 | 可能丢失最后一次快照后的数据 | 快 || AOF | 记录所有写操作命令 | 通常最多丢失1秒数据 | 慢 |RDB通过快照实现持久化,适合备份和快速恢复AOF记录写命令,提供更好的数据安全性混合持久化结合了两者优势,是推荐的配置方式。

在未来等你的专栏 1249

从ST转国产ARM必看:GD32/APM32等5款芯片的SWD下载全攻略(含CH32特殊处理)

本文为从STM32转向国产ARM芯片的开发者提供了详细的SWD下载调试指南。针对GD32F103C8T6、APM32F103C8T6等五款热门国产芯片,详细说明了如何利用已有的ST-Link工具和Keil MDK环境进行程序烧录,并特别介绍了CH32F103芯片所需的独立器件库安装等特殊处理方法,帮助开发者实现平滑迁移,提升开发效率。

weixin_29195615的博客 278

Redis 精讲

原文:https://www.cnblogs.com/rjzheng/p/9096228.html 引言 为什么写这篇文章? 博主的《分布式之消息队列复习精讲》得到了大家的好评,内心诚惶诚恐,想着再出一篇关于复习精讲的文章。但是还是要说明一下,复习精讲的文章偏面试准备,真正在开发过程中,还是脚踏实地,一步一个脚印,不要投机取巧。 考虑到绝大部分写业务的程序员,在实际开发中使用redis的时候...

Dzq_Boyka的博客 392

FPGA SoC 的 RISC-V 固件开发全攻略(三):RISC-V MCU 启动流程深入解析

本文是《FPGA SoC 的 RISC-V 固件开发全攻略》专栏第 3 篇。上一篇:第 2 篇《开发环境搭建与工具链避坑》 | 下一篇:第 4 篇《RISC-V 与 ARM Cortex-M 开发差异对比》

XavierKong的博客 45

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

Redis面试精讲 Day 19:Redis缓存设计模式与策略

Cache Aside是面试最高频的模式(出现率85%)写操作优先考虑最终一致性而非强一致热点数据需要特殊处理(分片+本地缓存)Day20将讲解Redis大规模部署性能调优,包括内核参数优化、集群分片策略等硬核内容。

在未来等你的专栏 808

Probability and Statistics - 4th edition

Probability and Statistics - 4th edition

Redis面试精讲 Day 4:Redis事务与原子性保证

Redis事务的基本概念和四大命令事务的实现原理和错误处理机制WATCH命令实现的乐观锁多语言客户端代码示例高频面试题解析生产环境实践案例明日预告Redis内存分配机制键过期策略及实现原理内存淘汰算法比较生产环境内存优化技巧。

在未来等你的专栏 1041

jre9下载 jdk9

(Java SE Runtime Environment 9.0) 9.0u175 官方最新版 【x86|x64】

迈瑞BS系列全自动生化分析仪LIS协议接口手册(内含HL7和ASTM)

迈瑞BS系列全自动生化分析仪LIS协议接口手册,内含HL7和ASTM)

Redis面试精讲 Day 16:Redis性能监控与分析工具

Redis性能监控是指通过收集、分析和可视化Redis实例的运行指标,以评估其健康状况和性能表现的过程。资源使用率(CPU、内存、网络)命令处理统计客户端连接情况持久化相关指标复制/集群状态Redis提供丰富的内置监控命令关键性能指标涵盖多个维度多种第三方工具增强监控能力性能分析需要系统化方法监控告警是生产环境必备。

在未来等你的专栏 1185

Redis面试精讲 Day 2:Redis数据类型全解析

Redis五种数据类型及其底层实现各类型操作的时间复杂度适用场景与生产环境应用与关系型数据库的对比。

在未来等你的专栏 984

redis精讲

本文围绕以下几点进行阐述 1、为什么使用redis 2、使用redis有什么缺点 3、单线程的redis为什么这么快 4、redis的数据类型,以及每种数据类型的使用场景 5、redis的过期策略以及内存淘汰机制 6、redis和数据库双写一致性问题 7、如何应对缓存穿透和缓存雪崩问题 8、如何解决redis的并发竞争问题 正文 1、为什么使用redis 分析:博主觉得在项目中使用redis,主要...

weixin_43658613的博客 221

Redis面试精讲 Day 14:Redis分片策略与一致性Hash

单机内存容量限制单点性能瓶颈系统扩展性问题数据分片是解决Redis扩展性的关键一致性Hash通过虚拟节点实现均衡分布Redis Cluster采用哈希槽简化分片管理不同分片策略有各自的适用场景生产环境需要监控和调整分片效果。

在未来等你的专栏 1408
上一篇: 权限管理控制与RBAC模型
下一篇: 实时显示从file输入框中打开的图片C:\fakepath路径错误等问题
Array*
博客等级 码龄9年 2粉丝 19原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值