Redis面试题

1. 什么是Redis,Redis的优缺点?

Redis本质上是一个key-value类型的内存的数据库,很像memcached,整个数据库统统加载在内存当中就行操作,定期通过异步操作把数据库数据flush到硬盘上进行保存。

优点:

因为是纯内存操作,Redis的性能非常出色,每秒可以处理超过10万次读写操作 ,是已知性能快的key-value DB.------性能出色

Redis最大魅力是保存多种数据结构,此外单个value的最大限制是1GB,不像memcached只能保存1MB的数据,因此Redis可以用来实现很多有用的功能--------丰富的数据接口,value限制1GB

可以用List的FIFO双向链表,实现一个轻量级的高性能的消息队列服务,用它的Set可以做高性能的tag系统等等。

另外Redis也可以对存入的key-value设置expire时间,因为也可以被当做一个功能加强版的memcached来用。

缺点:

Redis数据库容量收到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要限制在较小数据量的高性能操作和运算上。

 

2. Redis相比memcached有哪些优势?

  • memcached所有值均是简单的字符串,redis可以作为替代者,支持更丰富的数据类型.
  • redis的速度比memcached快的多。
  • redis可以持久化其数据。

3. Redis支持哪几种数据类型

String,List,Set,Sorted Set,hash

4. Redis主要消耗什么物理资源

内存

5. Redis的全称是什么?

Remote Dictionary Server

6. Redis有哪几种数据淘汰策略

  • noeviction:返回错误当内存限制叨叨并且客户端尝试执行会让更多的内存被使用的命令(大部分的写入指令,但DEL和几个例外)
  • allkeys-lru:尝试回收少使用的键(LRU),使得新添加的数据有空间存放
  • volatile-lru:尝试回收少使用的键(LRU),但仅限于在过期集合的键,使得新添加的数据有空间存放。
  • allkeys-random:回收随机的键,使得新添加的数据有空间存放
  • volatile-random:回收随机的键,使得新添加的数据有空间存放,但仅限于在过期集合的键
  • volatile-ttl:回收在过期集合的键,并且优先回收存活时间(TTL)较短的键,使得新添加的数据有空间存放。

7. 一个字符串类型的值能存储最大的容量是多少?

512M

 

8. 为什么Redis需要把所有数据放入内存中?

Redis为了达到快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘、所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度严重影响redis的性能。

在内存越来越便宜的今天,redis将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。

9. Redis集群方案应该怎么做?都有哪些方案?

codis

目前用的最多的集群方案,基本和twemproxy一致的效果,但它支持在节点数量改变情况下,旧节点数据可恢复到新hash节点。

redis cluster3.0自带的集群,特点在于它的分布式算法不是一致的hash,而hash槽的概念,以及自身支持节点设置从节点

在业务代码层实现起,几个毫无关联的redis实例,在代码层,对key进行hash计算,然后去对应redis实例操作数据。这种方式对hash层代码要求比较高。考虑部分包括,节点失效后的替代方案,数据震荡后的自动脚本恢复,实例的监控等等。

10. Redis有哪些适合的场景?

  • 会话缓存(session Cache)
    • 用Redis缓存会话比其他存储的优势在于:redis可以持久化,
  • 全页缓存(FPC)
    • 即使重启了Redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降
  • 队列
    • redis在内存存储引擎领域的一大优点是提供list和set操作,这使得redis能作为很好的消息队列平台来使用,Redis作为队列使用的操作
  • 排行榜/计数器
    • Redis在内存中队数字就行递增或递减的操作实现非常好,集合Set和有序集合Sorted set,也是的我们在执行这些操作的时候变得非常简单
    • 统计靠前的10个用户
    • ZRANGE user_score 0 10 WITHSCORES
  • 发布/订阅

11. Redis管道有什么用?

一个请求/响应服务能实现处理新的请求,即使旧的请求还未被响应,这样就可以将多个命令发送到服务器,而不用等待回复,后在一个步骤中读取该答复

12. 怎么理解Redis事务?

事务是一个单独的隔离操作,事务中所有命令都会序列化,按顺序地执行。事务在执行过程中,不会被其他客户端发送的命令请求所打断。

事务是一个原子操作,事务中的命令要么全部执行,要不全部不执行。

13. Redis事务相关的命令有哪几个?

MULTI、EXEC、DISCARD、WATCH

14. Redis常见的性能问题有哪些,如何解决?

  • Master写内存快照。save命令调度rdbSave函数,会阻塞主线程的工作,当快照较大时对性能影响是非常大,会间断性暂停服务,所以Master不要写内存块中。
  • Master AOF持久化,如果不重写AOF文件,这个持久化方式对性能的影响是最小的,但是AOF文件会不断增大,AOF文件大会影响Master重启的恢复速度,Master好不要做任何持久化工作,包括内存快照和AOF日志文件,特别是不要启用内存快照做持久化,如果数据比较关键,某个Slave开启AOF备份数据,策略为每秒同步一次。
  • Master调用BGREWRITEAOF重写AOF文件,AOF在重写时会占用大量CPU和内存资源,导致服务load过高,出现短暂服务暂停现象。
  • Redis主从复制的性能问题,为了主从复制的速度和连接的稳定性,Slave和Master在同一个局域网内

15. Redis数据结构

string字符串

简单的key-value类型,value不仅可以是string,也可以是数字。

hash字典

在客户端序列号存储为一个字符串的值,一般是Json格式,比如用户的信息(昵称、性别、年龄、积分等)

List列表

链表,双端链表实现的List

Set集合

一堆不重复的组合,利用Redis提供的Set数据结构,可以存储一些集合性的数据

Sorted Set有序集合

将Set中的元素添加一个权重参数score,使得集合中的元素能够按照score就行有序排列。

带有权重的元素,比如一个游戏的用户得分排行榜

 

 

16. RDB的优缺点

优点:RDB是一个非常紧凑(compact)的文件,它保存在Redis某个时间点上的数据集,这种文件非常适合用于就行备份,比如说,可以在近24小时内,每小时备份一次RDB文件,并且在每月某一天,备份RDB文件。这样的话,即使遇到问题,也可以随时将数据还原到不同的版本。RDB非常使用于灾难回复(disaster reconvery)

缺点:如果需要尽量避免在服务器故障时丢失数据,那么RDB不适合,虽然Redis运行设置不同保存点来控制保存RDB文件的频率,但是因为RDB文件需要保存在整个数据集的状态,所以它并不是一个轻松的操作,

17. AOF的优缺点

优点:AOF持久化会让Redis变的非常耐久,可以设置不同的fsync策略,比如:每秒一次fsync,或者每次执行写入命令是fsync,AOF文件是一个只能追加操作的日志文件(append only log),因此对AOF文件写入不需要进行seek,

缺点:AOF文件的体积通常要大于RDB的体检,AOF的速度要慢与RDB<

 

 

18. 简单说说缓存雪崩及解决办法

由于原有的缓存失效,新缓存未到期间(我们设置了缓存时采用了先相同的过期时间,在同一时刻出现大面积的缓存过期),所有原本应访问缓存的请求都去查询数据库,而对数据库CPU和内存造成了巨大压力,严重的会造成数据库宕机,从而形成一些列连锁反应,造成整个系统崩溃。

解决办法:大多数系统设计者应考虑加锁或者队列的方式保证不会又大量的线程对数据库一次性进行读写,从而避免失效时大量并发请求落到底层存储系统上。还有一个简单的方案就是对缓存失效时间分散开来.

 

 

19. 缓存穿透是怎么导致的?

在高并发下查询不存在的key的数据,会穿过缓存查询数据库,导致数据库压力过大宕机。

解决方法:

1.对查询结果为空的情况也进行缓存,缓存时间ttl设置短一点,或者该key对应的数据insert之后清理缓存。

缺点:缓存大量空值占用空间。

2.使用布隆过滤器,在缓存之前在加一层布隆过滤器,在查询的时候先去布隆过滤器查询key是否存在,如果不存在则直接返回,存在在查缓存或DB

布隆过滤器原理:当一个元素被加入集合是,将这个元素通过n次hash函数结果映射成一个数组中的n个点,把它设置为1.检索时,我们只要看到这些是不是1就知道集合中有没有它了,如果这些点有任何一个0,则被检索元素一定不在,如果都是1,则被检索元素很可能在,总之布隆过滤器是一个很大二进制的位数组。数组里面只有0和1

20. 项目中出现过缓存穿透,简单说说怎么回事

缓存在某个时间点过期的时候,恰好在这个时间点对这个key有大量并发的请求过来,这些请求发现缓存过期一般会从数据库中加载数据并回设到缓存中,这个时候大量并发的请求可能会瞬间把后端DB压垮

解决方案:

1.用分布式锁控制访问的线程,使用redis的setnx互斥锁先进行判断,这样其他线程就出于等待状态,保证不会有大并发操作去访问数据库

2.不设置超时时间,采用volatile-lru淘汰策略

缺点:会造成写一致问题,当数据库数据发生更新时,缓存中的数据不会及时更新,这样会造成数据库中的数据与缓存中的数据不一致,应用会从缓存中读取到脏数据,可采用延迟双删策略处理。(先更新数据库同时删除缓存,等2秒后再删除一次缓存,等到读的时候回写到缓存中。)

posted @ 2023-07-13 15:13  小溪_1  阅读(7)  评论(0编辑  收藏  举报