某讯一面,感觉问Redis的难度不是很大

打印 上一主题 下一主题

主题 801|帖子 801|积分 2403

前不久,有位朋友去某讯口试,他说被问到了许多关于 Redis 的问题,好比为什么用 Redis 作为 MySQL 的缓存?Redis 中大量 key 集中逾期怎么办?如何保证缓存和数据库数据的同等性?我将它们整理出来,跟各人一起来探讨如何回答这些问题,希望对各人有所资助。
   Redis 为什么这么快?

为什么用 Redis 作为 MySQL 的缓存?

Redis 除了做缓存,还能做什么?

使用 redis 分布式锁,如何合理设置逾期时间?

Redis 单线程模型了解吗?

Redis 中大量 key 集中逾期怎么办?

如何保证缓存和数据库数据的同等性?

  

Redis 为什么这么快?

Redis 内部做了非常多的性能优化,比力重要的有下面几点:

  • Redis 基于内存,内存的访问速度比磁盘快许多;
  • Redis 基于 Reactor 模式设计开辟了一套高效的事件处理模型,主要是单线程事件循环IO 多路复用
  • Redis 内置了多种优化过后的数据范例/结构实现,性能非常高。
  • Redis 通信协议实现简单且解析高效。
扩展:那既然都这么快了,为什么不直接用 Redis 当主数据库呢?


  • 主要是由于内存本钱太高且 Redis 提供的数据长期化仍然有数据丢失的风险。
为什么用 Redis 作为 MySQL 的缓存?

主要是由于 Redis 具备高性能高并发两种特性。下面来详细介绍一个高性能和高并发。(这个问题是个开放题,我的答案仅供参考)
高性能

如果用户第一次访问 MySQL 中的某些数据。这个过程会比力慢,由于是从硬盘上读取的。将该用户访问的数据缓存在 Redis 中,如许下一次再访问这些数据的时间就可以直接从缓存中获取了,操作 Redis 缓存就是直接操作内存,以是速度相称快。
如果 MySQL 中的对应数据改变的之后,同步改变 Redis 缓存中相应的数据即可。
高并发

单台装备的 Redis 的 QPS(Query Per Second,每秒钟处理完请求的次数) 是 MySQL 的 10 倍,Redis 单机的 QPS 能轻松破 10w,而 MySQL 单机的 QPS 很难破 1w。
以是,直接访问 Redis 可以或许承受的请求是远宏大于直接访问 MySQL 的,以是我们可以思量把数据库中的部分数据转移到缓存中去,如许用户的一部分请求会直接到缓存这里而不用经过数据库。
Redis 除了做缓存,还能做什么?


  • 分布式锁:通过 Redis 来做分布式锁是一种比力常见的方式。通常情况下,我们都是基于 Redisson 来实现分布式锁。
  • 限流:一般是通过 Redis + Lua 脚本的方式来实现限流。如果不想自己写 Lua 脚本的话,也可以直接使用 Redisson 中的 RRateLimiter 来实现分布式限流,其底层实现就是基于 Lua 代码+令牌桶算法。
  • 消息队列:Redis 自带的 List 数据结构可以作为一个简单的队列使用。Redis 5.0 中增加的 Stream 范例的数据结构更加得当用来做消息队列。它比力类似于 Kafka,有主题和消耗组的概念,支持消息长期化以及 ACK 机制。
  • 延时队列:Redisson 内置了延时队列(基于 Sorted Set 实现的)。
  • 分布式 Session:使用 String 或者 Hash 数据范例生存 Session 数据,全部的服务器都可以访问。
  • 复杂业务场景:通过 Redis 以及 Redis 扩展(好比 Redisson)提供的数据结构,我们可以很方便地完成许多复杂的业务场景好比通过 Bitmap 统计生动用户、通过 Sorted Set 维护排行榜。
使用 redis 分布式锁,如何合理设置逾期时间?
Redis 单线程模型了解吗?

Redis 基于 Reactor 模式设计开辟了一套高效的事件处理模型 ,这套事件处理模型对应的是 Redis 中的文件事件处理器(file event handler)。
由于文件事件处理器是单线程方式运行的,以是我们一般都说 Redis 是单线程模型。
口试官又问了一个小问题,感觉回答的不错
既然是单线程,那怎么监听大量的客户端连接呢?

Redis 通过 IO 多路复用程序 来监听来自客户端的大量连接(或者说是监听多个 socket),它会将感爱好的事件及范例(读、写)注册到内核中并监听每个事件是否发生。
I/O 多路复用技能的使用让 Redis 不需要额外创建多余的线程来监听客户端的大量连接,降低了资源的消耗,如许使用的利益是非常显着的。
使用 redis 分布式锁,如何合理设置逾期时间?


需要思量如下几个因素:

  • 任务实行时间:确保逾期时间大于预期的最长实行时间,以免任务还在实行过程中锁就被主动释放,导致并发问题
  • 锁主动续期:如果使用了支持锁主动续期的 Redis 客户端库(如 Redisson),在持有锁的线程还在实利用命期间,可以定期主动延长锁的有效期,如许可以减小因锁逾期导致的并发问题。
  • 锁竞争激烈程度:如果锁的竞争非常激烈,逾期时间不宜设置得太短,否则可能会频仍触发锁的竞争,消耗更多资源。反之,如果锁的竞争不大,可以得当缩短逾期时间,更快地采取锁资源。
  • 死锁检测与处理:设定一个合理的最大等待时间,超过这个时间还没有释放的锁可以被认为是持有锁的客户端出现问题,可以通过监控和相应的逻辑来处理此类死锁。
  • 网络耽误和异常恢复:思量到网络不稳定等因素,逾期时间还应该预留一部分用于处理网络耽误或客户端异常恢复的情况。逾期时间太短可能导致客户端未能及时释放锁或重新获取锁。
  • 锁释放的可靠性:使用 lua 脚本来保证解锁操作的原子性,同时联合 watch 下令或事务处理,以最大程度地确保锁在业务逻辑完成后可以或许准确释放,降低对逾期时间依赖的程度。
Redis 中大量 key 集中逾期怎么办?

首先回答 大量 key 集中逾期可能出现的问题:


  • 请求耽误增加: Redis 在处理逾期 key 时需要消耗 CPU 资源,如果逾期 key 数量巨大,会导致 Redis 实例的 CPU 占用率升高,进而影响其他请求的处理速度,造成耽误增加。
  • 内存占用过高: 逾期的 key 虽然已经失效,但在 Redis 真正删除它们之前,仍然会占用内存空间。如果逾期 key 没有及时清理,可能会导致内存占用过高,乃至引发内存溢出。
之后再回答 可以采取的方案:


  • 1.只管避免 key 集中逾期: 在设置键的逾期时间时只管随机一点。
  • 2.开启 lazy free 机制: 修改 redis.conf 配置文件,将 lazyfree-lazy-expire 参数设置为 yes,即可开启 lazy free 机制。开启 lazy free 机制后,Redis 会在后台异步删除逾期的 key,不会阻塞主线程的运行,从而降低对 Redis 性能的影响。
如何保证缓存和数据库数据的同等性?


其实感觉聊聊 Cache Aside 这个策略就可以了,细说的话没啥太大须要。
下面来说说 Cache Aside 策略:

Cache Aside 中碰到写请求是如许的,更新数据库,然后直接删除缓存。
但是必须是这两步都乐成,才气解决缓存和数据库数据不同等的问题。
关于更新数据库乐成,而删除缓存这一步失败的这种情况,是可能发生的,简单说有两个解决方案:


  • 缓存失效时间变短(不推荐,治标不治本):我们让缓存数据的逾期时间变短,如许的话缓存就会从数据库中加载数据。用户会反馈在一段时间后,才气更新数据哦!!!
  • 增加缓存更新重试机制(常用):如果缓存服务当前不可用导致缓存删除失败的话,我们就隔一段时间进行重试,重试次数可以自己定。不外,这里更得当引入消息队列实现异步重试,将删除缓存重试的消息投递到消息队列,然后由专门的消耗者来重试,直到乐成。
恭喜你,口试通过!!!

就业陪跑训练营学员投稿
接待关注 ❤

我们搞了一个免费的口试真题共享群,互通有无,一起刷题进步。
没准能让你能刷到自己意向公司的最新口试题呢。
感爱好的朋友们可以私信我,备注:口试群。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?立即注册

x
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

天津储鑫盛钢材现货供应商

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表