2022年常问redis面试题

编程入门 行业动态 更新时间:2024-10-28 07:19:37

1.什么是Redis

Redis是完全开源免费的,遵守BSD协议,是一个高性能的key-value数据库

Redis与其他key-value缓存产品有以下三个特点:

Redis支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的可以再次加载进行使用

Redis不仅仅支持简单的key-value类型的数据,同时还提供list,set,zset,hash等数据结构存储。

Redis支持数据的备份,即master-slave模式的数据备份

Redis优势

性能极高-Redis能读的速度是110000次/s,写的速度是81000次/s。丰富的数据类型 -Redis支持二进制案列的Strings,Lists,Hasher,Sets及Ordered Sets数据类型操作。

原子 -Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过Multi和Exec指令包起来

丰富的特性 -Redis还支持publish通知,key过期等等性能

2.Redis与其他key-value存储有什么不同?

Redis有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。Redis运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样Redis可以做很多内部复杂性很强的事情。同时在磁盘格式方面他们是紧凑的以追加的方式参数,因为他们并不需要进行随机访问

3.Reids的数据类型

Redis支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及zsetsorted set:(有序集合),geospatial地理位置(继而四被搜),hyperloglog , bitmaps

4.使用Redis有哪些好处?

1.速度快,因为数据存在内存中, 类似于HashMap,hashMap的优势就是查找和操作的时间复杂度都是O1)

2.支持丰富数据类型,支持string,list,set,Zset,hash等

3.支持事务,操作都是原子性,原子性:对数据更改要么全部执行,要么全部不执行

4.丰富的特性:可用于缓存,消息,按key设置过期时间,过期后将会自动删除

5.Redis相比Mencached有哪些优势?

1.Memcached所有的值均是简单的字符串,redis作为其替代者,支持更为丰富的数据类

2.Redis的速度比Memcached快

3.Redis可以持久化其数据

6.Memcache与Redis的区别有哪些?

1.存储方式Memcache(摸nuok)把数据全部存在内存中,断电后会挂掉,数据不能超过内存大小。Redis有部分存在硬盘上,这样能保证数据的持久化

2.数据支持类型:Memcache对数据类型相对简单。Reids有复杂的数据类型

3.使用底层模型不同 它们之间底层实现方式以及与客户端之间通信的应用协议不一样。Reids直接自己构建VM机制,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求

7.Redis是单进程单线程的?

Reids是单进程单线程的,redis利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销

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

512M

9.Reids持久化机制

Redis是一个支持持久化的内存数据库,通过持久化机制把内存中的数据同步到硬盘文件来保证数据持久化。当redis重启后通过把硬盘文件重新加载到内存,就能达到恢复数据的目的

实现:单独创建fork()一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后由子进程写入到临时文件中,持久化的过程结束了,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放

RDB是redis默认的持久化方式。按照一定的时间周期策略把内存的数据以快照的形式保存到硬盘的二进制文件。即Snapshot(四闹破上t)存储,对应产生的数据文件为dump.rdb(咋们破),通过配置文件中的save参数来定义快照的周期(快照可以是其所表示的数据的一个副本,也可以是数据的一个复制品)

AOF:Redis会将每一个收到的写命令都通过Write函数追加到文件最后,类似于Mysql的binlog。当Redis重启是会通过重新执行文件中保存的写命令在内存中重建整个数据库内容。当俩种方式同时开启,数据恢复Redis优先选择AOF恢复

10.缓存雪崩、缓存穿透、缓存预热、缓存更新、缓存降级、缓存击穿等问题

一、缓存雪崩

缓存中大量数据过期,查询数据量大,引起数据库压力过大甚至down机
解决方案:
1.设置热点数据永远不过期
2.定时更新缓存
3.springcache解决方案:
设置差别过期时间间隔
比如 CacheManager配置多个过期时间维度
配置文件time-to-live配置设置不同的过期时间
 cache:
   #使用的缓存类型
    type: redis
   #过时时间
    redis:
      time-to-live: 3600000
      # 开启前缀,默以为true
      use-key-prefix: true
      # 键的前缀,默认就是缓存名cacheNames
      key-prefix: XD_CACHE
      # 是否缓存空结果,防止缓存穿透,默以为true
      cache-null-values: true

二:缓存穿透

缓存和数据库中没有数据,而用户不断发起请求。每次查询这个值都会请求到数据库,给数据库压力过大
解决方案:
1.接口层增加效验,如用户鉴权效验,id做基础效验,id<=0的直接拦截
2.如果查询数据库为空,我们可以给缓存设置个默认值
3.使用布隆过滤器快速判断数据是否存在
SpringCache解决方案:
cache:
   #使用的缓存类型
    type: redis
   #过时时间
    redis:
      time-to-live: 3600000
      # 开启前缀,默以为true
      use-key-prefix: true
      # 键的前缀,默认就是缓存名cacheNames
      key-prefix: XD_CACHE
      # 是否缓存空结果,防止缓存穿透,默以为true
      cache-null-values: true

三:缓存预热

缓存预热就是系统上线后,将相关的缓存数据直接加载到缓存系统。这样就可以避免在用户请求的时候,先查询数据库,然后再将数据缓存的问题!用户直接查询事先被预热的缓存数据
解决思路:
1.直接写个缓存刷新页面,上线时手工操作下
2.数据量不大,可以在项目启动的时候自动进行加载
3.定时刷新缓存

四、缓存降级

当访问量剧增、服务出现问题(响应时间慢或不响应)或非核心服务影响到核心流程的性能时,仍然需要保证服务还是可用的,即使是有损服务。系统可以根据一些关键数据进行自动降级,也可以配置开关实现人工降级
​
降级的最终目的是保证核心服务可用,即使是有损的。而且有些服务是无法降级的(如加入购物车、结算)
​
解决预案
1.一般:比如有些服务偶尔因为网络抖动或者服务正在上线而超时,可以自动降级
2.警告:有些服务在一段时间内成功率有波动(如在95~100%之间),可以自动降级或人工降级,并发送告警
3.错误:比如可用率低于90%,或者数据库连接池被打爆了,或者访问量突然猛增到系统能承受的最大阈值,此时可以根据情况自动降级或者人工降级
4.严重错误:比如因为特殊原因数据报错了,此时需要紧急人工降级。服务降级的目的,是为了防止Reids服务故障,导致数据库跟着一起发生雪崩问题。因此,对于不重要的缓存数据,可以采取服务降级策略,例如一个比较常见的做法就是,Redis出现问题,不去数据库查询,而是直接返回默认值给用户

5.缓存击穿

某一个热点key,在不停的扛着高并发,当这个热点key失效的一瞬间,持续的高并发访问就击破缓存直接访问数据库,导致数据库down机
​
解决方案:
1.设置热点数据“永不过期”
2.加上互斥锁:上面的现象是多个线程同时去查询数据库的这条数据,那么我们可以在第一个查询数据的请求上使用一个互斥锁来锁住它
 其他的线程走到这一步拿不到锁就等着,等第一个线程查询到了数据,然后将数据放到redis缓存起来。后面的线程进来发现已经有缓存了,就直接走缓存

最后总结

雪崩是大面积的key缓存实效;穿透是redis 里不存在这个缓存key;击穿是redis某一个热点key突然失效,最终的受害者都是数据库

11.热点数据和冷数据是什么

热点数据,缓存才有价值

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

对于上面俩个例子,寿星列表、导航信息都存在一个特点,就是消息修改评率不高,读取通常非常高的场景。

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

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

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

12.单线程的redis为什么这么快

1.纯内存操作

2.单线程操作,避免了频繁的上下文切换

3.采用了非阻塞I/O多路复用机制

13.redis的数据类型,以及每种数据类型的使用场景

一共五种

1.string

最常规的set/get操作,value可以是string也可以是数据。一般做一些复杂的计数功能的缓存

2.hash

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

3.list

使用list数据结构,可以做简单的消息队列的功能。另外一个就是,利用lrange命令,做基于redis的分页功能,性能好,用户体验好。还可以生产者和消费的场景。list可以很好的完成排队,先进先出原则

4.set

因为set堆放的是不重复值得集合,全局去重。

可以计算共同喜好,全部喜好,自己独有的喜好功能等

5.sorted set

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

6.hyperloglog

基数:数学上集合的元素个数,是不能重复的。

UV(Unique visitor):是指通过互联网访问、浏览这个网页的自然人。访问的一个电脑客户端为一个访客,一天内同一个访客仅被计算一次。

hyperloglog 的优点是占用内存小,并且是固定的。存储 2^64 个不同元素的基数,只需要 12 KB 的空间

7.bitmap位图

bitmap 常用于统计用户信息比如活跃粉丝和不活跃粉丝、登录和未登录、是否打卡等

8.geospatial(鸡儿四被搜)

该功能可以推算出地理位置信息,两地之间的距离。

geo 底层实现原理其实就是 zset ,可以使用 zset 命令操作 geo

14.redis的过期策略以及内存淘汰机制

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

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

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

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

定期删除,redis默认每隔100ms随机抽取检查,是否有过期的key,有过期可以则删除。因此,如果只采用定期删除策略,会导致很多key到时间没有删除。于是,惰性删除派上用场。也就是说在你获取某个key的时候,redis会检查一下,这个key如果设置了过期时间那么是否过期了?如果过期了此时就会删除。

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

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

maxmemory-policy volatile-lru

该配置就是配内存淘汰的策略的

volatile-lru(我里tai哦 lru):从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random(我里太哦 让的们):从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction(驱逐):(in ria key 生)禁止驱逐数据,新写入操作会报错

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

15.redis常见性能问题和解决方案

1.master最好不要做任何持久化工作,如RDB内存快照和AOF日志一样

2.如果数据比较重要,某个slave开启AOF备份数据,策略设置为每秒同步一次

3.为了主从复制的速度和链接的稳定,master和slave最好在同一个局域网内

4.尽量避免在压力很大的主库上增加从库

5.主从复制不要用图状结构,用单向链表结构更为稳定,即:master<slave1<slave2<slave3

16.为什么redis操作是原子性的,怎么保证原子性的?

对于redis而言,命令的原子性指的是:一个操作的不可以再分,操作要么执行,要么不执行

redis的操作之所以是原子性的,是因为redis是单线程

redis本身提供的所有API都是原子操作,redis中的事务是要保证批量操作的原子性

多个命令在并发中也是原子性的吗?

不一定,将get和set改成单命令操作,incr。使用redis的事务,或者使用Reids+Lua==的方式实现

17.redis事务

redis事务功能是通过Multi(毛符停)、exec(E个染可)、discard(第四高德)、watch(我吃)四个原语实现的

redis会将一个事务中的所有命令序列化,然后按顺序执行

1.redis不支持回滚"redis在事务失败时不进行回滚,而是继续执行余下的命令",所以redis的内部可以保持简单且快速

2.如果在一个事务中的命令出现错误,那么所有的命令都不会执行

3.如果在一个事务中出现运行错误,那么正确的命令会去执行

(1)multi命令用于开启一个事务,他总是返回ok。multi执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即被执行,而是被放到一个队列中,当exec命令被调用时,所有队列中的命令才会被执行

(2)exec:执行所有事务块内的命令。返回事务块内所有命令的返回值,按命令执行的先后顺序排列。当操作被打断时,返回空值null

(3)通过调用discard,客户端可以清空事务队列,并放弃执行事务,并且客户端会从事务状态中退出

(4)watch命令可以为redis事务提供check-and-set(cas行为)可以监控一个或多个键,一旦其中有一个键被修改(删除),之后的事务就不会执行,监控一直持续到exec命令

18.redis的持久化机制是什么?各自的优缺点?

Redis提供俩种持久化机制RDB和AOF机制

1.RDBredis DataBase持久化方式:是指用数据集快照的方式半持久化模式 记录redis数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次持久化的文件,达到数据恢复

优点:

1.只有一个文件dump.rdb(咋们破),方便持久化

2.容灾性好,一个文件可以保存到安全的磁盘

3.性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化。使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能

4.相对于数据集大时,比AOF的启动效率更高

缺点:

1.数据安全性低。RDB是间隔一段时间进行持久化,如果持久化之间redis发送故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候

2.AOFAppend-only file持久化方式:是指所有的命令行记录以redis命令请求协议的格式完全持久化存储)保存为aof文件

优点:

1.数据安全,aof持久化可以配置appendfsync(啊砰的赛可)属性,有always,每进行一次命令操作就记录到aof文件中一次。

2.通过append模式写文件,即使中途服务器down机,可以通过redis-check-aof工具解决数据一致性问题

3.AOF机制的rewrite模式。AOF文件没被rewrite之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作flushall)

缺点:

1.AOF文件比RDB文件大,且恢复速度慢

2.数据集大的时候,比RDB启动效率低

20.redis过期键的删除策略

1.定时删除:贼设置键的过期时间的同时,创建一个定时器timer.让定时器在键的过期时间来临时,立即执行对键的删除操作

2.惰性删除:放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键;如果没有过期,就返回该键

3.定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定

21.redis的回收策略(淘汰策略)

volatile-lru:(我里tai哦 lru)从已设置过期时间的数据集中挑选最近最少使用的数据淘汰

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

volatile-random:(我里太哦 让的们)从已设置过期时间的数据集中任意选择数据淘汰

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

allkeys-random:从数据集中任意选择数据淘汰

no-enviction(驱逐):(in ria key 生)禁止驱逐数据

注意这里的 6 种机制,volatile 和 allkeys 规定了是对已设置过期时间的数据集淘汰数据还是从全部数据集淘汰数据,后面的 lru、ttl以及 random 是三种不同的淘汰策略,再加上一种 no-enviction 永不回收的策略

使用策略规则:

1、如果数据呈现幂律分布,也就是一部分数据访问频率高,一部分数据访问评率低,则使用allkeys-lru

2.如果数据呈现平等分布,也就是所有的数据访问评率都相同,则使用allkey

22.为什么redis需要把所有数据放到内存中?

redis为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以redis具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘I/O速度严重影响redis的性能。如果设置了最大使用的内存,则数据已有记录数达到内存限制后不能继续插入新值

23.redis的同步机制了解嘛?

redis可以使用主从同步,从从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接收完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程

24.是否使用过redis集群,常见集群分类,集群的原理是什么?

主从复制集群

分片集群

1.redis sentinal 着眼于高可用,在master down机时会自动将slave提升为master,继续提供服务

sentinal职责如下

  • 监控(Monitoring):sentinel会不断的定期检查你的主服务器和从服务器是否运作正常

  • 提醒(Notification):当被监控的某个redis服务器出现问题时,sentinel可以通过API向管理员或者其他应用程序发送通知

  • 自动故障迁移(Automacticfailover):当一个服务器不能正常工作时,sentinel会开始一次自动故障迁移操作,它会将失效主服务器的其中一个从服务器升级为新的主服务器,并让失效主服务器的其他从服务器改为复制新的主服务器;当客户端试图连接失效的主服务器时,集群也会向客户端返回新主服务器的地址,使得集群可以使用新主服务器代替失效服务器

  • 统一的配置管理:连接者sentinel取得主从的地址

2.redis cluster(氪佬四der) 着眼于扩展性,在单个redis内存不足时,使用cluster进行分片存储

25.redis集群方案什么情况下会导致整个集群不可用?

有ABC三个节点的集群,在没有复制模型的情况下,如果节点B失败了,那么整个集群就会以为缺少5501-11000这个范围的槽而不可用

26.redis支持的java客户端有哪些?官方推荐用哪个?

redisson,jedis(粘带四)等等,官方推荐Redisson

27.jedis与redisson对比有什么优缺点?

jedis是redis的java实现的客户端,其API提供了比较全面的redis命令的支持;

Redisson实现了分布式和可扩展的java数据结构,和jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等redis特性。redisson的宗旨是促进使用者对redis的关注分离,从而让使用者能够将经历更集中的放在处理业务逻辑上

28.redis如何设置密码及验证密码?

设置密码:config set require pass(瑞块儿 怕死) 123456

授权密码:auth (恩斯) 123456

29.说说redis哈希槽的概念

redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis集群有16384个哈希槽,每个key通过CRC16效验后对16384取模来决定放置哪个槽,集群的每个节点负责一部分hash槽

30.redis集群的主从复制模型是怎么弄的

为了使在部分节点失败或者大部分节点无法通信的情况下集群仍然可用,所以集群使用了主从复制模型,每个节点都会有N-1个复制品

31.Redis集群会有写操作丢失嘛?为什么

redis并不能保证数据的强一致性,这意味着在实际中集群在特定的条件下可能会丢失写操作

32.redis集群之间是如何复制的

异步复制

33.redis集群最大节点个数是多少?

16384个

34.redis集群如何选择数据库

redis集群无法做数据库选择,默认在0数据库

35.怎么测试redis连通性

使用ping命令

36.怎么理解redis事务

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

2.事务是一个原子操作:事务中的命令要么都执行要么全都不执行

37.redis事务相关的命令有哪些?

multi、exec、discard、watch

38.redis key 的过期时间和永久有效分别怎么设置

expire(e渴死白而) 和 persist(破SEI斯t)命令

39.redis如何做内存优化

尽可能使用散列表(hashes),散列表(是说散列表里面存储的数少)使用的内存非常小,所以你应该尽可能的将你的数据模型抽象到一个散列表里面。比如你的web系统中有一个用户对象,不要为这个用户的名称,姓氏,邮箱,密码设置单独的key,而是应该把这个用户的所有信息存储到一张散列表里面

40.redis回收进程如何工作的?

一个客户端运行了新的命令,添加了新的数据。redis检查内存使用情况,如果大于maxmemory的限制,则根据设定好的策略进行回收。

一个新的命令被执行,等等。所以我们不断的穿越内存限制的边界,通过不断达到边界然后不断的回收回到边界以下。如果一个命令的结构导致大量内存被使用(例如很大的集合的交集保存到一个新的键),不用多久内存限制就会被这个内存使用量超越

41.都有哪些办法可以降低redis的内存使用呢

如果你使用的是32位的redis实例,可以好好利用hash,list,sorted set,set 等集合类型数据,因为通常情况下很多小的key-value可以用更紧凑的方式存放在一起

42.redis的内存用完了会发生什么?

如果达到设置的上限,redis的写命令会返回错误信息(但是读命令还可以正常返回)或者你可以将redis当缓存来使用配置淘汰机制。当redis达到内存上限时就会冲刷掉旧的内容

43.一个redis实例最多能存放多少个keys?list,set,sorted set他们最多能存放多少元素

理论上redis可以处理多达232的keys,并且在实际中进行了测试,每个实例至少存放2亿5千万的keys。我们正在测试一些较大的值。任何list,set,sorted set都可以放232个元素。换句话说,redis存储极限是系统中的可用内存值

44.mysql里有2000w数据,redis中只存20w数据,如何保证redis中的数据都是热点数据

Redis 内存数据集大小上升到一定大小的时候,就会施行数据淘汰策略。相关知识:Redis 提供 6 种数据淘汰策略:

volatile-lru:从已设置过期时间的数据集(server.db[i].expires)中挑选最近最少使用的数据淘汰

volatile-ttl:从已设置过期时间的数据集(server.db[i].expires)中挑选将要过期的数据淘汰

volatile-random:从已设置过期时间的数据集(server.db[i].expires)中任意选择数据淘汰

allkeys-lru:从数据集(server.db[i].dict)中挑选最近最少使用的数据淘汰

allkeys-random:从数据集(server.db[i].dict)中任意选择数据淘汰

no-enviction驱逐):禁止驱逐数据

45.redis最适合的场景

1.会话缓存(Session Cache)

最常用的一种使用redis的情景是会话缓存(session cache)。用redis缓存会话比其他存储(如Memcached)的优势在于:Redis提供持久化。当维护一个不是严格要求一致性的缓存时,如果用户的购物车信息全部丢失,大部分都会不高兴的,现在,他们还会这样吗?

幸运的是,随着redis这些年的改进,很容易找到怎么恰当的使用redis来缓存会话的文档。甚至广为人知的商业平台Magento也提供redis插件

2.全页缓存(EPC)

除基本的会话token之外,redis还提供很简单的EPC平台。回到一致性问题,即使重启redis实例,因为有磁盘的持久化,用户也不会看到页面加载速度的下降,这是一个极大改进,类似PHP本地FPC。再次以agento为实例,Magento提供一个插件来使用redis作为全页缓存后端。此外,对WordPress的用户来说,Pantheon有一个非常好的插件wp-redis,这个插件能帮助你以最快的速度加载你曾浏览过的页面

3、队列

redis在内存存储引擎领域的一大优点是提供list和set操作,这使得redis能作为一个很好的消息队列平台来使用。redis作为队列使用的操作,就类似于本地程序语言(如python)对list的push操行。如果你快速的在Google中搜索“redis queues”,你马上就能找到大量的开源项目,这些项目的目的就是利用 Redis 创建非常好的后端工具,以满足各种队列需求。例如,Celery 有一个后台就是使用 Redis

作为 broker,你可以从这里去查看。

4.排行榜/计数器

Redis 在内存中对数字进行递增或递减的操作实现的非常好。集合(Set)和有序集合(Sorted Set)也使得我们在执行这些操作的时候变的非常简单,Redis 只是正好提供了这两种数据结构。所以,我们要从排序集合中获取到排名最靠前的 10个用户–我们称之为“user_scores”,我们只需要像下面一样执行即可: 当然,这是假定你是根据你用户的分数做递增的排序。如果你想返回用户及用户的分数,你需要这样执行: ZRANGE user_scores 0 10 WITHSCORES Agora Games 就是一个很好的例子,用 Ruby 实现的,它的排行榜就是使用 Redis 来存储数据的,你可以在这里看到。

5、发布/订阅

最后(但肯定不是最不重要的)是 Redis 的发布/订阅功能。发布/订阅的使用场景确实非常多。我已看见人们在社交网络连接中使用,还可

作为基于发布/订阅的脚本触发器,甚至用 Redis 的发布/订阅功能来建立聊天系统

46.假如redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?

使用 keys 指令可以扫出指定模式的 key 列表。

对方接着追问:如果这个 redis 正在给线上的业务提供服务,那使用 keys 指令会有什么问题?

这个时候你要回答 redis 关键的一个特性:redis 的单线程的。keys 指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用 scan 指令,scan 指令可以无阻塞的提取出指定模式的 key 列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用 keys 指令长。

47.如有有大量的key需要设置同一过期时间,一般需要注意什么?

如果大量的key过期时间设置的过于集中,到过期的那个时间点,redis可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一些

48.使用过redis做异步队列摸,怎么用的?

一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试

如果对方追问可不可以不用sleep呢?

list换有个指令叫blpop,在没有消息的时候,他会阻塞住直到消息到来。如果对方追问能不能生产一次消费多次呢?使用pub/sub主题订阅者模式,可以实现1:N的消息队列

如果对方追问pub/sub有什么特点

在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如RabbitMQ等

如果对方追问redis如何实现延时队列? 使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。

49.使用过分布式锁吗?怎么回事

先拿 setnx 来争抢锁,抢到之后,再用 expire 给锁加一个过期时间防止锁忘记了释放。

这时候对方会告诉你说你回答得不错,然后接着问如果在 setnx 之后执行 expire之前进程意外 crash 或者要重启维护了,那会怎么样?

这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。紧接着你需要抓一抓自己得脑袋,故作思考片刻,好像接下来的结果是你主动思考出来的,然后回答:我记得 set 指令有非常复杂的参数,这个应该是可以同时把 setnx 和expire 合成一条指令来用的!对方这时会显露笑容,心里开始默念:摁,这小子还不错

50.redis分布式锁实现原理

当多个线程访问一个资源时,对该资源的访问方法执行之前加锁,使对资源访问始终保持一个线程,执行完之后进行释放锁,然后再由其他线程进行业务处理

更多推荐

2022年常问redis面试题

本文发布于:2023-06-14 08:19:00,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1454659.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:面试题   年常问   redis

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!