Redis知识点

redis默认内存查看及调整

1、redis默认内存在32位系统下最多使用3GB内存

redis默认内存在64位系统下不限制内存大小

2、生产上内存设置:一般推荐redis设置内存为 最大物理内存的四分之三

3、内存修改的两种方式:

3.1 通过redis.conf配置文件修改

格式:maxmemory 字节

举例:maxmemory 104857600

3.2 通过config命令修改

格式:config set maxmemory 字节

举例:config set maxmemory 104857600

查看内存命令:config get maxmemory

4、查看redis内存使用情况的命令:info memory

1.常用的数据结构:五种(string、list、hash、set、zset)

string: 是一个key,value结构,适合存储用户信息的,比如存储一些token啊等等 。

hash:是一个key,map结构,就可以用来存储些字典信息。

set:是一个无序集合,里面的元素是不可重复,针对这个不能重复的特点,我们就可以做一些儿去重的场景。

zset:是一个有序的集合,就是它会根据那个score然后自动排序,可以用来做些排名的功能,非常方便。

list:双向列表,一般可以做一些顺序存储,比如说可以左进左出,也可以左进右出,非常灵活。 lpush rpop

2.有那些数据类型:八种(string、list、hash、set、zet、bitMap、hyperloglogs、Streams)

bitMap:是个位图,它是一个二进制的存储,我们可以做一些签到业务,它相比较那个mysql的话,它可以节省很多的一个空间。

hyperloglogs:它会对重复的元素自动去重,非常适合做那个UV(数据的统计,一个周期内,访问网站的人数之和)的一个统计。

Geospatial Geo  :可以推算出地理位置信息,两地之间的距离,可以做那个搜索附近功能。

3.底层数据结构如何实现:本质上来讲就是个hashMap, 键值对保存形式。

作为NoSQL数据库,本质上来讲就是个hashMap, 以key-value的字典方式来存储数据,其中的value主要支持五种数据类型。

4.redis 在项目中咋用的:计数器、会话缓存、消息队列、 分布式锁、热点数据、排行榜、短信过期、去重用set集合(set集合可以用作集合运算,本身set就是不可重复的)、redisson框架、常用就是作为二级缓存

5.redis 的优缺点: 就说应用场景就行,对它的理解突突突

6.redis的持久化机制:RDB(配置文件,sava...............说明白)、AOF(三种模式),最大的区别: 生成的文件不一样,RDB是二进制文件,操作不了, AOF生成的日志文件,可以操作

RDB是按照一定时间把内存数据以快照方式存储到硬盘中

快照的周期可以在redis.conf 配置文件中的save参数来定义。

sava 900 1 900秒(15分)之后至少有1个key发生变化,触发RDB

save 300 10 300秒(5分钟)之后至少有10个key发生变化,触发RDB

save 60 10000 60秒(1分钟)之后 至少有10000个key发生变化,触发RDB

RDB的优点的话就是恢复速度快,占用内存小,但是会丢失数据

AOF是将操作的命令写到日志文件中。

AOF三种写入策略

appendfsync always 每次写操作都写入AOF日志文件 最安全

appendfsync everysec 每秒刷新一次缓冲区中的数据到AOF文件。这种方式是redis默认使用的策略,是考虑数据完整性和性能的这种方案,理论上,这种方式最多只会丢失1秒内的数据。

appendfsync no redis服务器不负责将数据写入到AOF文件中,而是直接交给操作系统去判断什么时候写入。这种方式是最快的一种策略

AOF的话是记录所有的执行指令,优点就是AOF不会丢数据,但是恢复速度会比较慢。 严格意义上来讲,AOF也有可能会丢数据,因为AOF是先落缓存,然后再刷磁盘,如果说AOF现在还没有刷盘,就直接宕机了,这个时候也会丢失部分数据的。

4.0之前,默认是RDB模式,使用AOF的话,RDB就失效了

4.0之后,可以使用混合模式 ,默认是关闭的,可以通过配置文件aof-use-rdb-preamble开启。

如果使用混合持久化方式的话,AOF重写的时候就直接把RDB的内容写到AOF文件开头,这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的,AOF ⾥⾯的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。

7。同时开启RDB和AOF ,AOF-USE-RDB-preamble 默认是关闭的false, 打开true 将RDB文件内容写在AOF日志文件开头

Redis 4.0 开始⽀持 RDB 和 AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb- preamble 开启)。

如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF ⽂件开头。这样做的好处是可以结合 RDB 和 AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的,AOF ⾥⾯的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。

8.怎么选择合适的持久化方案, 基于性能 做缓存,用RDB 基于安全 做秒杀,用AOF

如果特别想要保证安全性,应该同时使用两种持久化方案。在这种情况下,当Redis重启的时候会优先载入AOF文件来恢复原始的数据,因为在通常情况下AOF文件保存的数据集要比RDB文件保存的数据集要完整。

如果想要性能快,且可以承受数分钟以内的数据丢失,那么你可以只使用RDB持久化。

有很人都只使用AOF持久化,但并不推荐这种方式,因为定时生成RDB快照(snapshot)非常便于进行数据库备份,并且RDB恢复数据集的速度也要比AOF恢复的速度要快,除此之外,使用RDB还可以避免AOF程序的bug。

如果你只希望你的数据在服务器运行的时候存在,你也可以不使用任何持久化方式。

9.redis的键过期策略:定时删除、惰性删除、定期删除

redis的所有数据结构都可以设置过期时间,然后时间一到的话它就会自动删除,因为redis是单线程的,所以说收割时间也会占用到处理时间,如果说收割的太过于频繁的话,会导致线上读写指令的一个卡顿,所以就是说redis会将所有的有过期时间的key,它会放到一个字典表里面,会定时遍历这个字典,然后删除到期的key,redis默认每秒会遍历10次,但是它不是全表扫描,他是一个贪心算法去遍历的。

同时redis会采用一种惰性删除策略,当我们去查询这个key的时候,我们会先去查询这个key是否过期,如果过期则删除。

定时过期: 每个设置过期时间的key都需要创建一个定时器,到过期时间就会立即清除。该策略可以立即清除过期的数据,对内存很友好; 但是会占用大量的CPU资源去处理过期的数据,从而影响缓存的响应时间和吞吐量。

惰性过期: 只有当访问一个key时,才会判断该key是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存。

定期过期: 每隔一段时间,程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库, 则由算法决定。该策略是前两者的一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,可以在不同情况下使得CPU和内存资源达到最优的平衡效果。

(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指向键空间中的某个键的指针,value是该键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。)

Redis中同时使用了惰性过期和定期过期两种过期策略。(重要)

但是,仅仅通过给 key 设置过期时间还是有问题的。因为还是可能存在定期删除和惰性删除漏掉了很多过期 key 的情况。这样就导致⼤量过期 key 堆积在内存⾥,然后就Out of memory了。那么就需要Redis 内存淘汰机制。

10.redis的内存淘汰机制:内存满才会出现 三大类:对设置了过期时间的进行淘汰、对所有的进行淘汰、不进行淘汰

Redis 提供 6 种数据淘汰策略:

1. volatile-lru︰已设置过期时间数据集中挑选最近最少使⽤的数据淘汰

2. volatile-ttl︰已设置过期时间的数据集中挑选将要过期的数据淘汰

3. volatile-random︰已设置过期时间的数据集中任意选择数据淘汰

4. allkeys-lru︰当内存不⾜不允许写⼊数据时,在键空间中,移除最近最少使⽤的 key(这个是最常⽤的)

5. allkeys-random︰从数据集中任意选择数据淘汰

6. no-eviction︰禁⽌驱逐数据,也就是说当内存不⾜不允许写⼊数据时,新写⼊操作会报错。这个应该没⼈使⽤吧!

4.0版本后增加以下两种︰

7. volatile-lfu ︰已设置过期时间的数据集中挑选最不经常使用的数据淘汰

8. alkeys-lfu ︰当内存不足不允许写入数据时,在键空间中,移除最不经常使用的key

注意:Redis的内存淘汰策略的选取并不会影响过期的key的处理。内存淘汰策略用于处理内存不足时的需要申请额外空间的数据;过期策略用于处理过期的缓存数据。

11.如何保证redis缓存双写一致性:redis和mysql 延时双删策略

分为两种情况吧:一种是业务一致性较高,另一个是业务允许延迟一致。

针对一致性要求高可以采用分布式锁,读数据时添加共享锁(读锁,read lock),写数据时添加排它锁(独占锁 write lock)

共享锁是 读可以共享,写的话就互斥

排它锁是 读写都互斥

使用读写锁,可以保证数据的强一致性,但是性能会降低

针对允许延迟一致要求 可以采用延时双删策略,先进行缓存删除,再更新数据库,最后延迟N秒再执行缓存清除,进行两次删除。这其中延迟的秒数 要大于一次写操作的时间。这个时间就需要统计具体读数据和写缓存的操作时间了,以此为基础来进行估算。

12.缓存穿透、击穿、雪崩

【Redis篇】Redis缓存之缓存穿透_redis 缓存穿透-CSDN博客

缓存穿透是体现于:用户查询不存在的数据,缓存中查询不到就会直接查询数据库,同一时间遇到高并发请求,导致数据库宕机,这就违背了缓存的意义,缓存就是为了不查询数据库而设立的,这种穿透的解决方案

一、缓存空数据: 将数据库的查询结果 null 也存入redis中,这样用户再查询的话就不会查询数据库了,因为缓存中已经有这条数据了,只不过值是null。 (将value存null值处理)

如果大量数据都不存在,这样会导致redis存了大量空数据,会消耗内存,可以给缓存设置一个过期时间。

如果原先查询的数据不在,后续数据库又添加上了,可能存在数据不一致的问题。

二、采用布隆过滤器,它的底层主要是先去初始化一个比较大数组,里面存放的二进制0或1。在一开始都是0,当一个key来了之后经过3次hash计算,根据计算结果找到对应数组下标,然后把数组中原来的0改为1,这样的话,三个数组的位置就能表明一个key的存在。查找的过程也是一样的,一个一定不存在的数据一定会被拦截掉,从而避免了对底层存储系统的查询压力

【Redis篇】Redis缓存之缓存雪崩_redis缓存雪崩-CSDN博客

缓存雪崩是体现于:当redis中的同一时间段多个key同时失效或者redis服务宕机,刚好遇到了高并发请求,导致数据库压力过大,最终宕机。

解决方案

针对于多个key失效有两种

一、同一业务中给不同key设置随机的过期时间

二、给缓存业务做降级限流策略

针对于redis服务宕机有两种

三、部署redis高可用性,集群模式

四、给缓存业务做熔断

还有就是给业务做二级缓存,使用nginx作为一级缓存,redis作为二级缓存。

【Redis篇】Redis缓存之缓存击穿-CSDN博客

缓存击穿是体现于:redis中的某一个key设置了过期时间,当key过期时,恰好大量的并发请求过来,都去查数据库可能导致数据库压力过大而宕机

击穿的解决方案

一、将redis中的热点数据的过期时间设置为永久,不过期

二、使用互斥锁,当线程A查询缓存,缓存没有的话,就获取互斥锁,然后去查询数据库返回数据添加到redis缓存中,再释放锁

在线程A获得锁期间,其他线程来查询时,缓存查询不到,也去获取互斥锁,但是获取失败,就休眠会儿再重试,重新从缓存开始查,等线程A释放锁之后,其他线程查询时缓存里已经有数据可以直接返回了。

使用互斥锁可以保证数据的强一致性,但是性能会差。

13.哨兵模式

14.主备模式

15.集群模式 (分片策略)

16.脑裂问题 什么情况会出现,如何避免解决

是指Redis集群中某个节点在网络故障或软件故障的情况下无法与其他节点通信,导致集群中的一部分节点无法被其他节点访问,从而形成两个独立的子集,称为"脑裂"。

当Redis集群中某个节点出现脑裂时,另一个子集中的节点仍然可以正常通信,因此该子集仍然可以正常提供服务。但是,另一个子集中的节点无法访问其他节点,因此可能会导致数据不一致或丢失。

为了避免脑裂的发生,Redis建议在集群中使用双主模型,即每个节点都可以成为主节点,并在需要时进行主从切换。同时,Redis提供了许多故障转移策略,如自动故障转移(AutoFailover)、手动故障转移(HardFailover)等,可以在脑裂发生时自动修复集群,保持集群的完整性。

此外,Redis还提供了许多监控和警报工具,以便管理员可以在集群中检测和预防脑裂的发生。例如,Redis提供了基于Zabbix的监控插件,可以实时监控集群的运行状态,并在出现问题时自动发送警报通知。

17.redis为什么那么快(数据结构取决于怎么样,就怎么怎么快)

1、首先redis本身是基于内存,读写不受磁盘IO限制,就已经很快了。

2、redis单线程情况下,内核会一直监听socket上的连接请求和数据请求,一旦有请求就交给redis线程处理,实现了一个redis处理多个IO流的效果。

3、redis是单线程的,单线程不需要考虑锁,自然就不会变慢,不会存在上下文切换所引起的CPU消耗。

4、不同数据类型使用不同的数据结构速度大大得到提升。

5、不同的数据类型,不同的数据结构,所涉及的编码转化,redis提供每种结构相对应的数据编码。

18.redis为啥单线程还快?*(多路IO复用模型)

因为redis的存储是基于内存的,所以说redis它本身就会很快,如果说redis是多线程的话,那反而会有一个上下文的切换,这样的话会降低我们的一个效率,但redis它处理网络IO是多线程处理的,所以说redis它虽然是单线程,但是它还依旧会很快

19.redis实现分布式锁(三种 setnx 会有啥问题 redisson 、 redlocak)

1.可以使用setnx命令实现分布式锁,它的原理是这样的,当用户A使用setnx设置一个键发现它里面没有值的时候,它会往里面存储一个值,然后返回1 ,上锁成功,当用户B使用setnx获取锁时,发现有值,返回0,这样的特性就实现了分布式锁。

但是如果用户A在请求的过程当中,服务器挂掉了,用户B正常请求,就会出现一个阻塞的情况了,原因是用户A在获得锁之后因为服务器挂掉了,并没有释放锁,导致其他用户在获取的时候,里面一直有值,获取不到锁,从而造成了一个死锁的现象,所以使用setnx时要给这个key设置一个“合理”的过期时间。

还有一种可能是 当用户A业务的处理时间较长,超过了设置的过期时间,那么业务B就趁虚而入了,当业务A处理完之后释放锁,这时释放的是业务B的锁,这时候解决就需要在用户A处理的时候,给它添加一个子线程,每10秒确认主线程是否在线,在线则将过期时间进行重设,再就是可以给锁加一个唯一ID,那么key就是绑定那一个线程,从而就不会释放其他线程的锁了。

实现这些代码非常麻烦,而且还要保证它的一个健壮性,否则一个细节不注意就会出现bug

2.那么我们就可以使用redisson,redisson就可以完成以上所说的功能从而实现分布式锁,Redisson提供的看门狗机制,它实际上是一种自动延期机制,使得Redisson提供的分布式锁可以自动续期。如果一个线程获取锁后,运行程序到释放锁所花费的时间大于锁自动释放时间(也就是看门狗机制提供的超时时间,Redisson会自动给redis中的目标锁延长超时时间)。使用它也是比较简单,只要添加redisson的相关依赖,将redisson的客户端Client 依赖注入到项目中,通过getLock(key)入参自定义一个key,再打点调用lock方法就可以实现redisson的分布式锁

使用redisson也会出现一个问题,就是如果redis使用了集群的模式(中小规模项目一般是:1主4从+3哨兵),因为redis采用的是AP模式,只能保证高可用,高性能,无法保证高一致性,当设置一个锁的时候只会往一个节点去设置锁,设置完了就会立马告诉你成功,内部去进行同步,假设你把这个锁的key设置到 了主节点,这个时候主节点正好挂掉了,其他节点还没有同步这把锁,从节点变成新的主节点了,其他线程就可以从新的节点上获取锁。这时依然会发生线程不安全,这时redisson也提供了解决办法,那就是red locak 红锁

【Redis】之 RedLock 分布式锁-CSDN博客

3.红锁会针对redis中所有节点来进行同步,如果没有使用red lock的话,那就是设置到主节点之后直接告诉你上锁成功,如果用了red lock的话,它要保证至少半数以上(N/2 +1)的节点都同步完成且获取锁的时间要小于锁失效的时间,才会告诉你上锁成功,这样的方式,就能保证强一致性了

20.缓存预热、缓存降级

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据!

解决方案

1. 直接写个缓存刷新页面,上线时手工操作一下;

2. 数据量不大,可以在项目启动的时候自动进行加载;

3. 定时刷新缓存;

当访问量剧增、服务出现问题(如响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级。

缓存降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)。

在进行降级之前要对系统进行梳理,看看系统是不是可以丢卒保帅; 从而梳理出哪些必须誓死保护,哪些可降级;比如可以参考日志级别设置预案:

1. 一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级;

2. 警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警;

3. 错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阀值,此时可以根据情况自动降级或者人工降级;

4. 严重错误:比如因为特殊原因数据错误了,此时需要紧急人工降级。

服务降级的目的,是为了防止Redis服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户。

21.redis冷热数据

热点数据,缓存才有价值

对于冷数据而言,大部分数据可能还没有再次访问到就已经被挤出内存,不仅占用内存,而且价值不大。频繁修改的数据,看情况考虑使用缓存

对于热点数据,比如我们的某热门产品,生日祝福模块,当天的寿星列表,缓存以后可能读取数十万次。再举个例子,某导航产品,我们将导航信息,缓存以后可能读取数百万次。

数据更新前至少读取两次,缓存才有意义。这个是最基本的策略,如果缓存还没有起作用就失效了,那就没有太大价值了。

有一种情况是修改频率很高,但是又不得不考虑缓存的场景,比如:这个读取接口对数据库的压力很大,但是又是热点数据,这个时候就需要考虑通过缓存手段,减少数据库的压力,比如我们的某助手产品的,点赞数,收藏数,分享数等是非常典型的热点数据,但是又不断变化,此时就需要将数据同步保存到Redis缓存,减少数据库压力。

22.redis实现消息队列 (L 进 )(R 出),消费的话配合定时器每隔一秒扫一遍

23.list集合和发布订阅模式 list的如果消费者没有消费,消息一直存在, 发布订阅模式 如果消费者没有消费,消息就没了

相关推荐

  1. 学习redis知识

    2024-04-02 00:06:18       32 阅读
  2. redis的基本知识

    2024-04-02 00:06:18       37 阅读
  3. redis试题按知识归类

    2024-04-02 00:06:18       27 阅读
  4. Redis知识汇总表格总结

    2024-04-02 00:06:18       29 阅读
  5. redis试题按知识归类(三)

    2024-04-02 00:06:18       28 阅读
  6. redis试题按知识归类(二)

    2024-04-02 00:06:18       31 阅读
  7. 5、Redis 缓存设计相关知识

    2024-04-02 00:06:18       34 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-02 00:06:18       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-02 00:06:18       101 阅读
  3. 在Django里面运行非项目文件

    2024-04-02 00:06:18       82 阅读
  4. Python语言-面向对象

    2024-04-02 00:06:18       91 阅读

热门阅读

  1. strstr 的使用和模拟实现

    2024-04-02 00:06:18       39 阅读
  2. 开闭原则(Open Closed Principle)

    2024-04-02 00:06:18       40 阅读
  3. C++经典面试题目(十七)

    2024-04-02 00:06:18       32 阅读
  4. C语言之零基础速成(进制转换秘籍篇)

    2024-04-02 00:06:18       36 阅读
  5. 在Compose中使用状态提升?我提升个P...Provider

    2024-04-02 00:06:18       37 阅读
  6. Python爬虫-request模块

    2024-04-02 00:06:18       32 阅读
  7. 代码随想录刷题-回溯

    2024-04-02 00:06:18       28 阅读
  8. FastAPI+React全栈开发17 让我们创建一个React应用

    2024-04-02 00:06:18       28 阅读
  9. 排序算法-选择排序

    2024-04-02 00:06:18       35 阅读