Redis常见面试题

Redis是一个内存中的键值对数据库,以其高速读写性能常用于缓存。文章讨论了Redis的单线程模型、数据类型、IO多路复用机制,以及在保证双写一致性上的几种策略,如先删除缓存再更新数据库、先更新数据库再删除缓存和异步更新缓存。此外,还涉及了缓存穿透、击穿和雪崩问题的解决方案,以及Redis的持久化(RDB和AOF)、数据过期策略和分布式锁的实现。
摘要由CSDN通过智能技术生成

Redis

   Redis是一个数据库,不过与传统数据库不同的是redis的数据存储在内存中,并且是键值对数据库,因此读写速度非常快,应用于缓存方向,但是redis不支持事务回滚

Redis数据类型

字符串:String
哈希:Hash
列表:List
集合:Set
有序集合:ZSet

对于服务端程序来说,线程切换和锁通常是性能杀手,单线程避免了线程切换和竞争所带来的消耗

  Redis大部分操作在内存上完成,所以性能很高
  Redis采用了IO多路复用机制,使其在网络IO操作中能并发处理大量客户端请求,实现高吞吐率

保证双写一致性(缓存和持久数据库的数据一致)

1.先删除缓存在更新数据库

  • 在进行更新操作时,先删除缓存,然后再更新数据库,后续请求再次读取时,会从数据库读取完后再将新数据库更新到缓存。

  • 存在的问题:删除缓存数据之后,更新数据库完成之前,如果有新的请求,就会从数据库读取旧数据重新写到缓存中,再次造成不一致,并且之后读的都是旧数据。

先更新数据库再删除缓存

  进行更新操作时,先更新MySQL,成功之后,删除缓存,后续读取请求时再将新数据回写缓存。
  存在的问题:更新MySQL和删除缓存的这段时间,请求读取的还是缓存的旧数据,不过等数据库更新完成之后,就会恢复一会,影响比较小

异步更新缓存

  数据库的更新操作完成之后不直接操作缓存,而是把操作指令封装成消息发送给消息队列,由redis自己去消费更新数据,消息队列可以保证数据操作顺序一致性,以确保缓存系统的数据正常

Redis使用场景

  缓存 -> 穿透、击穿、雪崩、双写一致性、持久化、数据过期策略,数据淘汰策略
  分布式锁 -> setnx、redisson

缓存穿透

  缓存穿透是传递一个不存在的数据,redis中查不到,mysql中也查不到,不会写回redis所有请求都打进数据库导致数据库压力过大宕机
  解决方案: 缓存空数据,但是会数据不一致
  解决方案:布隆过滤器

缓存击穿

  缓存击穿是给一个key设置了过期时间,当key过期的时候,恰好由大量请求发送过来,这些并发请求会瞬间把数据库压垮
  解决方案:使用互斥锁,强一致性,性能差
  解决方案: 逻辑过期策略,高可用,性能好,不能保证数据绝对一致

互斥锁解决缓存击穿

  当缓存失效时,不会立即去查找数据库,先使用redis的setnx去设置一个互斥锁,操作成功返回时,在进行load db的操作并回写缓存

设置当前key逻辑过期策略

  在设置key的时候设置一个时间字段表示过期时间,一起存入缓存,不设置key的过期时间
查询的时候,从redis取出数据判断时间是否过期
  如果过期,就开一个线程进行数据同步,当前返回过期数据,当然这个数据不是最新的

什么是缓存雪崩,如何解决?

  缓存雪崩是指很多缓存采用同样的过期时间,在同一时间大量缓存失效,请求打回数据库,导致数据库压力过大,造成雪崩,雪崩时多个key同时过期,击穿时一个key过期但是有很多并发请求
  解决方案:

  1. 不同key设置不同的过期时间,过期时间根据key的实际业务用途来设置
  2. 利用redis基础群提高服务的可用性,哨兵、集群
  3. 给缓存业务添加降级限流策略 nginx或者gateway
  4. 给业务添加多级缓存 Guava或者Caffeine

redis作为缓存,聊一聊双写一致性问题

  当要求数据库和redis保持高度一致时,可以采用读写锁保证强一致性,使用redisson实现读写锁,在读的时候加一把共享锁,保证读读不互斥,读写互斥。当更新数据库时,添加一个排他锁,读写和读读都互斥,这样就能保证在写数据的同时不会让其他线程读数据,避免了脏数据。(读和写方法必须使用同一把锁)
   当数据同步可以由一定延迟时,可以采用canal组件实现数据同步;不需要更改业务代码,部署一个canal服务。当数据库更新后,canal会读取binlog数据,然后通过canal的客户端获取到数据,更新缓存即可。

Redis持久化的问题

  redis持久化有两种方式RDB和AOF
  RDB叫redis快照,会把redis内存存储的数据写到磁盘上,当redis宕机的时候,方便从RDB快照文件中恢复数据。
触发RDB快照的方式有两种

  1. 手动触发比如执行save(有主进程执行RDB,会造成阻塞)或者bgsave命令(开启一个紫禁城执行RDB,不影响主进程)
  2. 自动触发,可以在配置文件中修改设置,save 900 1(900秒内,如果至少有一个key被修改,则执行bgsave)

AOF追加文件
  当redis操作写命令时,会把命令存储到文件中,当redis宕机时,会读取这个文件再次执行这个命令,来恢复数据。
  RDB因为是一个二进制文件,体积小会快很多,但是有可能会丢失数据,通常在项目中也会使用AOF恢复数据,虽然AOF恢复的慢,但是它丢失数据的风险要小很多,可以将RDB和AOF配合使用

redis的数据过期策略

  redis有两种数据过期策略:

  • 一种是惰性删除:设置一个key的过期时间后,不用再去管他,当我们需要这个key的时候,会自动检查是否过期,如果过期就删除
  • 第二种是定期删除:每隔一段时间,对一些key进行检查,删除里面过期的key

定期删除有两种方式:

  • SLOW模式:定时任务,执行频率默认10hz,每次不超过25ms,通过配置文件redis.conf选项来调整参数
  • FAST模式:执行频率不固定,每次事件循环会尝试执行,但两次间隔不低于2ms,每次耗时不超过1ms(不能占用主进程过多时间)
  • redis过期删除策略一般采用惰性删除和定期删除两种策略同时使用

redis如何实现分布式锁

  • 在redis中提供了一个setnx(set if not
    exists)命令,用了这个命令之后只能有一个客户端对key设置值,在key没过期或者没有被删除时,其他客户端不能设置这个key

  • setnx命令:

    获取锁:set lock value nx ex 10(nx是互斥,ex是设置超时时间)
    释放锁:del key

redis实现分布式锁如何控制锁的有效时长

  要使用setnx控制比较麻烦,许哟啊考虑业务需要的时间,如果网络波动业务没走完,锁被释放就会完蛋,可以考虑用redisson实现
  redission中需要手动去改加锁,并且可以控制所得失效时间和等待时间,其中有一个WatchDog看门狗的机制,每隔一段时间就回去查看业务是否还持有这把锁,如果持有就增加锁时间,直到业务执行完毕。

redisson实现分布式锁时可重入吗

  可以重入,为了避免死锁的发生,重入就是在内部判断是否当前这个线程持有锁,如果当前线程持有锁,就会计数,如果锁释放就会计数减1.
  在存储时用hash结构,大key可以按照自己的业务定制,小key时当前线程唯一标志,value时当前线程重入的次数。

数据淘汰策略

  redis数据淘汰策略默认是noeviction,不删除任何数据,内存不足直接报错。策略可以在配置文件中设置,有两个重要的概念LRU和LFU。
  LRU最近最少使用,当前时间减去最后一次访问时间,值越大淘汰优先级越高。
  LFU最少频率使用,key的访问频率越小淘汰优先级越高。
数据库中有1000万条数据,redis只能缓存一小部分,如何保证都是热点数据,可以使用allkeys-lru淘汰策略,访问频率低的淘汰留下来的就是访问频率高的了

回答: Redis常见面试题包括但不限于以下几个方面: 1. Redis的特点和优势:Redis是一个基于内存的NoSQL数据库,支持多种数据结构和丰富的操作,具有高性能、高并发、持久化、主从同步等特点。 2. Redis的数据结构:Redis支持多种数据结构,包括字符串(string)、列表(list)、集合(set)、有序集合(sorted set)和哈希(hash),每种数据结构都有相应的操作方法。 3. Redis的持久化方式:Redis有两种持久化方式,分别是RDB(Redis Database)和AOF(Append Only File)。RDB是将内存中的数据定期保存到磁盘上,而AOF是将每个写操作追加到文件末尾。 4. Redis的使用场景:Redis可以用于缓存、会话管理、计数器、排行榜、消息队列等多种场景。它的高性能和丰富的数据结构使得它在处理大量并发请求和快速读写的场景下表现出色。 5. Redis的并发访问:Redis采用单进程单线程模式,通过队列模式将并发访问变为串行访问。在Jedis客户端对Redis进行并发访问时可能会出现连接超时、数据转换错误、阻塞等问题,需要注意处理这些并发访问的情况。 综上所述,Redis是一个功能强大的基于内存的NoSQL数据库,具有多种数据结构和丰富的操作方法,适用于多种场景。在面试中,了解Redis的特点、数据结构、持久化方式、使用场景和并发访问等方面的知识是非常重要的。 #### 引用[.reference_title] - *1* *2* [redis面试题总结(附答案)](https://blog.csdn.net/guorui_java/article/details/117194603)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [精选 21道 Redis 最常问面试题!收藏一波 !](https://blog.csdn.net/w915209092/article/details/126035419)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值