Redis教程

来谈谈Redis

本文主要是介绍来谈谈Redis,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!

来谈谈Redis

文章目录

  • 来谈谈Redis
    • 1、你对Redis的了解?
    • 2、Redis的使用场景?
    • 3、Redis支持的数据类型有哪些?
    • 4、Redis为什么这么快?
    • 5、什么是缓存穿透?怎么解决
    • 6、什么是缓存雪崩?怎么解决
    • 7、双写一致性:先更新数据库,后删除缓存?
    • 8、Redis持久化几种方式?
    • 9、Redis的过期淘汰策略?

1、你对Redis的了解?

Redis是一个开源使用ANSI C语言编写、支持网络、基于内存可持久化的日志型、Key-Value数据库,提供多种语言的API。

2、Redis的使用场景?

  1. 缓存:减轻MySQL的查询压力,提升系统性能;
  2. 排行榜:SortSet(有序集合)实现;
  3. 计数器/限速器:利用Redis中原子性的自增操作,统计用户点赞数、用户访问数等,用mysql,频繁的读写带来相当大的压力,限速器:限制某个用户访问某个API的频率,抢购时,防止用户疯狂点击带来不必要的压力;
  4. 好友关系:利用集合,如交集、并集、差集等,实现共同好友、共同爱好之类的功能;
  5. 消息队列:Redis自身的发布/订阅模式,也可以用List来实现一个队列机制,如:到货通知、邮件发送,不需要高可靠,但会带来很大的DB压力,完全可以用List来完成异步解耦;
  6. Session共享:Session保存在服务器的文件上的,如果是集群服务,同一个用户过来可能落在不同的机器上,导致用户频繁登录;采用Redis保存Session后,无论用户落在哪台机器上都能获取到对应的Session信息。

不适合的场景:

数据量太大:会增加成本,

访问频率太低:保存在内存中纯属浪费资源

3、Redis支持的数据类型有哪些?

1、String字符串(键)

使用场景:缓存、计数器、共享Session、限速

2、Hash哈希

使用场景:本身就是键值对结构,,比字符串序列化更加直观,更新操作更加便捷

3、List列表

使用场景:列表类型是用来存储多个有序的字符串,还可以获取指定范围的元素列表、获取指定索引下的元素,Redis的lpush + brpop命令组合即可实现阻塞队列,生产者客户端是用lpush从列表左侧插入元素,多个客户端使用brpop命令阻塞式的“抢”列表尾部的元素,多个客户端保证了消费的负载均衡和高可用。

4、Set集合

和列表不同的是不允许有重复元素,并且是无序的,不能通过索引下标获取元素,但是支持集合内的增删改查,支持多个集合取交集、并集、差集。

5、zset(sortedset)有序集合

使用场景:给每个元素设置一个分数,作为排序的依据,排行榜,以及榜单维护可能是:按照时间、按照播放量、按照获得的赞数等。

4、Redis为什么这么快?

  1. 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。
  2. 数据结构简单,对数据操作也简单
  3. 单线程,避免了上下文切换和竞争条件,也不存在多线程或者多线程导致的切换而消耗CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
  4. 使用多路I/O复用模型,非阻塞IO

5、什么是缓存穿透?怎么解决

用户查询一个一定不存在的数据,刚开始在缓存中查询不到,于是就去数据库中查询,查询不到,数据也不写入缓存,这就导致每次查询这个不存在的数据都去数据库中查询

解决办法:

缓存空对象,如果返回的数据为空,我们仍然把空结果进行缓存,过期时间设置很短(5分钟)。

缓存空对象存在的问题

1、需要更多的内存空间,设置较短的过期时间

2、缓存和存储的数据会有一段时间窗口的不一致,可能对业务造成影响,可以用消息系统或其他方式清除掉缓存层的空对象。

布隆过滤器:将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,避免了对底层存储系统的查询压力。

6、什么是缓存雪崩?怎么解决

缓存集中在一段时间失效,所有查询落在数据库上

解决办法:

1.在缓存的时候给过期时间加上一个随机值,大幅度减少缓存同一时间过期。

2.加锁排队:缓存失效后,通过加锁或队列来控制读数据库写缓存的线程数量,如:对于某一个key只允许一个线程查询数据和写缓存,其他线程等待;

3.数据预热:通过缓存reload机制,先去更新缓存,即将发生大并发前手动触发加载不同的key,设置不同的过期时间,尽量让失效时间均匀。

4.做二级缓存(双缓存策略)cache1为原始缓存,cache1为拷贝缓存,cache1失效,可以访问cache2,原始失效时间为短期,拷贝失效时间为长期。

7、双写一致性:先更新数据库,后删除缓存?

仍然存在问题,更新数据库成功了,但是删除缓存没有删除成功,再读缓存每次都是错误的数据了

利用消息队列

image-20220318151017482

  1. 请求A先对数据库进行更新操作
  2. 对redis进行删除操作的时候发现报错,删除失败
  3. 此时将redis的key作为消息体发送到消息队列中
  4. 系统接收到消息队列发送的消息后再次对redis进行删除操作

对业务代码造成大量侵入,耦合在一起

订阅mysql数据库的binlog日志对缓存进行操作

8、Redis持久化几种方式?

持久化就是把内存的数据写到磁盘中去,防止服务宕机了内存数据丢失。RDB(默认)和AOF

RDB

Redis DataBase的缩写。按照一定的周期策略把内存的数据以快照的形式保存到硬盘的二进制文件,即Snapshot快照存储,数据文件为dump.rdb,通过配置文件中的save参数定义快照的周期。

rdbSave:生成RDB文件,

rdbLoad:从文件加载到内存

AOF

AOF是Append-only file的缩写,Redis会将每一个收到的写的命令都通过Write函数追加到文件最后,类似于MySQL的binlog。Redis重启是会通过执行文件中保存的写命令在内存中重建整个数据库的内容。每当执行服务器任务或函数时,flushAppendOnlyFile函数都会被调用:

write:根据条件,将aof_buf中的缓存写入到AOF文件;

save:根据条件,调用fsync或fdatasync函数,将AOF文件保存到磁盘中

区别:

  1. AOF文件比RDB更新频率高,优先使用AOF还原数据;
  2. AOF比RDB更安全也更大;
  3. RDB性能比AOF好;
  4. 两个都配了优先加载AOF。

9、Redis的过期淘汰策略?

volatile-lru:从已设置过期时间的数据集中挑选最近最少使用的数据淘汰;

volatile-ttl:从已设置过期时间的数据集中挑选要过期的数据淘汰;

volatile-random:从已设置过期时间的数据集中任意选择数据淘汰;

allkeys-lru:从所有数据集中挑选最近最少使用的数据淘汰;

allkeys-random:从所有数据集中任意选择数据进行淘汰;

noeviction:禁止驱逐数据;

Redis的淘汰算法实际实现上并非对所有key,而是抽样一小部分并且从中选出被淘汰的key。

保证缓存的数据都是热点数据,可以将内存最大使用量设置为热点数据占用的内存量,然后启用allkeys-lru,淘汰策略,将最近最少使用的数据淘汰;

Redis4.0引入了volatile-lfu和allkeys-lfu淘汰策略,通过统计访问的频率,将频率访问最少的键值对淘汰。

这篇关于来谈谈Redis的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!