最新版本:redis7.x
springcloud:2.0.22
springboot:3
1.Redis效率高原因?
-
内存存储
-
单线程+io多路复用
-
支持多种数据结构类型
-
内部网络通信优化
Redis之所以被认为是快速的,主要有以下几个原因:
-
内存存储:Redis将数据存储在内存中,而不是磁盘上。相比于磁盘访问内存访问速度更快,可以实现很低的延迟和高吞吐量。
-
单线程模型:Redis采单线程模型,避免了多线程间的竞争和上下文切换的开销。线程模型简化了并发控制,减少了锁的使用,提高了处理请求的效率。
-
高效的数据结构:Redis提供了多种高效的数据结构,如字符串、哈希表、跳跃表、集合和有序集合等。这些数据结构在内部实现上都经过了优化,能够快速地进行插入、删除、查找和遍历操作。
-
异步操作:Redis支持异步操作,可以在后台执行一些耗时的操作,如持久化、复制和集群的同步等。这样可以减少客户端的等待时间,提高系统的响应速度。
-
高效的网络通信(核心):Redis自定义的RESP协议进行网络通信,协议本身简单而高效。Redis的网络通信采用非阻塞I/O多路复用机制和事件驱动的方式,可以处理大量的并发连接,提高了系统的并发性能。
-
优化的算法和数据结构:Redis在内部实现中使用了许多优化的算法和数据结构。例如,使用跳跃表(Skip List)来实现有序集合,使用压缩列表(ziplist)来存储小规模的列表和哈希表等。这些优化可以减少内存占用和提高数据操作的效率。
总的来说,Redis之所以快速,是因为它使用内存存储、采用单线程模型、提供高效的数据结构、支持异步操作、优化网络通信和使用优化的算法和数据结构等。这些特性使得能够在处理大量请求时保持低延迟和高吞吐量。
2.Redis基本数据类型有哪些?你用过哪些在什么场景使用?
-
string、list、set、zset、hash、bitmap。。。
-
String,在专辑详情数据作为缓存使用,使用string类型
-
hash,存储排行榜数据
-
Bitmap,解决缓存穿透问题(布隆过滤器)、24小时一个用户对应一个声音计算一次播放量
3.Redis的持久化机制有哪些?优缺点?项目里采用什么方式
Redis的持久化机制旨在将内存中的数据保存到硬盘上,以防止数据因系统故障或Redis服务中断而丢失。这不仅可以保护数据的完整性,还可以支持数据备份、恢复和迁移等操作。
RDB(Redis Database)持久化:
-
原理:RDB是一种快照式持久化方式,它可以定期将Redis的数据集快照写入磁盘中。当Redis重启时,可以通过读取RDB文件来恢复数据集。
-
优点:适用于大规模数据的备份和灾难恢复,恢复速度快。
-
缺点:由于是定时快照,可能会丢失最后一次快照与宕机之间产生的数据。
AOF(Append Only File)持久化:
-
原理:AOF是一种日志式持久化方式,它会记录Redis的所有写操作(如添加、删除、更新等操作)到磁盘中。当Redis重启时,可以通过执行AOF文件中的命令来恢复数据集。
-
优点:数据安全性高,不易丢失数据,因为AOF记录了所有的写操作。
-
缺点:AOF文件体积可能会不断增大,占用更多的磁盘空间,且恢复速度可能较慢。记录写操作时会导致对磁盘的频繁写入,可能会对性能有影响;
AOF和RDB对比:
-
AOF文件比RDB更新频率高,优先使用AOF还原数据。
-
AOF比RDB更安全也更大
-
RDB性能比AOF好
-
如果两个都配了优先加载AOF
4.Redis的过期策略是怎么样的?
Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理。
-
惰性过期:只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。
-
定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。
(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。)
-
Redis中同时使用了惰性过期和定期过期两种过期策略。
5.Redis的内存淘汰策略是怎么样的?如何选择淘汰策略?
redis是内存数据库,内存肯定有限的,不断向redis内存里面放数据,内存满了,还往内存里面放数据,如何处理?
策略1:noeviction(默认)
默认情况下,Redis 在使用的内存空间超过 maxmemory 值时,并不会淘汰数据,一旦缓存被写满了,再有写请求来时,Redis 不再提供服务,而是直接返回错误。
四个策略: volatile-random、volatile-ttl、volatile-lru 和 volatile-lfu
前提条件:限制在已经设置了过期时间的键值对上选择某个数据进行删除
-
volatile-ttl 在筛选时,会针对设置了过期时间的键值对,根据过期时间的先后进行删除,越早过期的越先被删除。
-
volatile-random 就像它的名称一样,在设置了过期时间的键值对中,进行随机删除。
-
volatile-lru 会使用 LRU 算法筛选设置了过期时间的键值对。
-
volatile-lfu 会使用 LFU 算法选择设置了过期时间的键值对。
三个策略:allkeys-lru、allkeys-random、allkeys-lfu
这三种淘汰策略的备选淘汰数据范围,就扩大到了所有键值对,无论这些键值对是否设置了过期时间。它们筛选数据进行淘汰的规则是:
-
allkeys-random 策略,从所有键值对中随机选择并删除数据
-
allkeys-lru 策略,使用 LRU 算法在所有数据中进行筛选。
-
allkeys-lfu 策略,使用 LFU 算法在所有数据中进行筛选。
6.什么是热Key问题,如何解决?
热Key问题是指在Redis中,某个或某些特定的键被频繁访问,导致对这些键的操作成为系统的性能瓶颈。热Key问题可能会导致Redis负载过高,响应时间延长,甚至造成系统崩溃。
为了解决热Key问题,可以采取以下一些策略:
-
增加缓存容量:扩大Redis内存容量可以提高缓存命中率,减少对热Key的访问次数,从而缓解热Key问题。可以考虑升级Redis服务器或增加Redis集群节点来增加内存容量。
-
缓存预热:在系统启动或流量低峰期,提前加载热Key的数据到缓存中,使得这些热Key的数据在实际访问时已经存在于缓存中,减少对后端存储的访问。
-
数据分片:对于热Key所对的数据量较大的情况,可以考虑将数据进行分片存储,将不同片段的数据存放在不同的键上,从而减轻单个键的访问压力。
-
缓存降级:对于某些热Key,可以考虑将其缓存时间设置较短,或者不缓存,直接访问后端存储。这样可以避免热Key对缓存系统的过度压力,同时确保其他非热Key正常缓存。
-
使用Redis集群:通过搭建Redis集群,将热Key分散到多个节点上,实现负载均衡和高可用性,提高系统的整体性能和稳定性。
综合考虑具体业务场景和系统需求,可以采取不同的策略或组合使用来解决热Key问题。
7.什么是大Key问题,如何解决?
大约的评判标准:体积大,数量多
-
单个string的value>1MB
-
容器(list,hash,set)元素数量超过1万
产生的问题:
-
内存占用过高: 大Key占用了大量的内存空间,导致其他数据无法被缓存,从而影响Redis的性能和响应速度。
-
数据加载时间延长: 由于大Key的加载和传输需要较长时间,会导致读取和写入操作的延迟。
-
持久化问题: 在进行数据持久化(如RDB快照、AOF日志)时,大Key会增加持久化的时间和磁盘空间占用。
如何解决:
-
数据分片:对于大数据,使用分片的方式进行存储,将一个大Key拆分成多个小Key,每个小Key存储一部分数据。
-
分布式存储: 将大数据存储在分布式数据库中,如Redis Cluster或其他分布式存储系统。
-
合理选择数据结构:根据实际的业务需求,选择更合适的数据结构,避免在单个Key中存储过大的数据。
-
合理设置过期时间: 对于不再需要的数据,设置Key的过期时间,让Redis自动清理过期的数据。
-
定期清理:清理不再用的数据
综合使用这些方法可以有效地解决大Key问题,提高Redis的性能和稳定性。
8.什么是缓存击穿、缓存穿透、缓存雪崩?
-
redis缓存中会出现缓存穿透、缓存雪崩、缓存击穿、数据不一致的问题。
-
缓存穿透是由于大量请求,请求了redis和数据库中不存在的数据,解决办法有两种,第一种就是返回null值,并储存在redis中,但是这种方案并不能有效避免随机key的访问,第二种就是加布隆过滤器,这样当请求过来时,会先经过布隆过滤器进行判断,若数据在redis或者mysql中存在,则进行访问,若都不存在,则直接返回null值;
-
缓存雪崩是由于redis缓存的大量值在同一时刻同时失效,从而导致大量的请求访问数据库,引起了雪崩现象,可以在缓存数据时设置随机的过期时间,对于单节点宕机可以采取集群部署的方式避免。
-
对于缓存击穿,是由于大量请求请求了同一个缓存中不存在的热点key,导致大量请求同时访问数据库,造成压力,可以采用分布式锁进行避免,当大量请求在访问数据库之前,先进行加锁处理,保证在同一时间只能有一个线程操作数据,其他线程只能自旋等待,操作数据库的线程在访问到数据后,将数据存储在redis中,供其他线程进行读取。
9.什么情况下会出现数据库和缓存不一致的问题?
-
数据一致性问题,redis缓存数据应该要与mysql数据库中的数据保持一致,但当多个线程进行访问时,可能会出现数据不一致的问题,比如:【先删再更】t1线程在更新mysql数据时,先将缓存中的数据进行删除,正常情况下会更新数据库的数据,但t1线程还未来得及更新时,t2线程对数据进行了访问,由于缓存中数据被删,会直接访问mysql数据库,这时t2线程就会得到更新前的旧数据,并且将得到的旧数据存储在缓存中,t1在之后才完成对数据库的更新,那么当t3线程对数据进行访问时,就会直接从redis缓存中得到旧数据,从而出现了数据不一致性的问题;【先更再删】或者t1线程在更新mysql数据库数据时,先将数据库中的数据进行更新,正常情况下会删除缓存中的数据,但t1线程还未来得及删除时,t2线程对数据进行了访问,由于t1线程还没有将缓存中的数据进行删除,会导致t2线程从缓存中得到旧数据,从而出现了数据不一致性的问题。可以通过redis延迟双删尝试保证数据的一致,先删除缓存中的数据--对数据库进行更新--休眠一会,保证数据的同步--再删除缓存中的数据;也可以通过canal同步方案保证数据的一致性,当数据库中的数据发生了改变会在二进制日志中进行记录,canal则会实时监控二进制日志的变化,获取更新的数据,并且对数据进行解析和存储,从而保证了数据的一致性,要注意canal属于cs架构,客户端服务器,通过软件才能访问,即当服务器启动时,若不存在客户端,那么canal也不会拉取mysql二进制日志。
10.介绍一下Redis的集群方案有哪些?哨兵工作原理?
-
主从模式:数据备份和读写分离的模式,有一个主节点(写操作)和多个从节点(读操作),从节点会复制主节点的数据,实现数据的备份。
-
主从模式+哨兵模式:
在哨兵模式下,哨兵节点会定期检查主节点和从节点的运行状态。如果发现主节点发生故障,哨兵节点会在从节点中选举出一个新的主节点,并通知其他的从节点和哨兵节点。
-
集群模式(redis cluser):
在集群模式下,Redis使用一种叫做哈希槽的技术来实现数据的分片。整个哈希空间被分成16384个哈希槽,每个节点负责一部分哈希槽。当一个键需要被存储时,Redis会根据键的值计算出一个哈希值,然后根据哈希值决定将这个键存储在哪个节点上。这样,读写请求就可以在多个节点上并行处理,提高了系统的性能。
去中心化:任意一个Master节点都可以接受客户端的请求,操作时多个Master节点之间互相连通(重定向)
11.Redis除了做缓存之外,还可以做什么
-
验证码的过期时间,通过redis实现
-
计算播放量,对于一个用户对同一个声音的播放量在24小时之内仅计算一次
-
防止重复提交redis+lua
-
MQ消息的幂等性保证setnx
-
实现分布式锁:setnx+过期时间(避免死锁)+uuid(谁加的谁放)+lua(加锁和放锁的原子性)+续期(确保操作是在有锁的状态下执行的);或者redisson实现
-
更新排行榜,hash
173万+

被折叠的 条评论
为什么被折叠?



