8-4 缓存机制及Redis常考面试题

2022-09-19 09:25:21

一、考点聚焦

缓存的使用场景;Redis的使用;缓存使用中的坑
1.为什么要使用缓存?使用场景?
2.Redis的常用数据类型,使用方式
3.缓存使用问题:数据一致性问题;缓存穿透、击穿、雪崩问题

二、什么是缓存?为什么要使用缓存?

本章主要讨论的是内存缓存(常见的有RedisMemcached
1.缓解关系数据库(常见的是Mysql)并发访问的压力:热点数据
2.减少响应时间:内存IO速度比磁盘快
3.提升吞吐量:Redis等内存数据库单机就可以支撑很大并发

操作时间对比:

操作响应时间
打开一个网站几秒
在数据库中查询一条记录(有索引)十几毫秒
机械苏特给次寻址定位4毫秒
从机械磁盘顺序读取1MB数据2毫秒
SSD磁盘顺序读取1MB数据0.3毫秒
从远程分布式缓存Redis读取一个数据0.5毫秒
从内存中读取1MB数据十几微秒
Java程序本地方法调用几微秒
网络传输2KB数据1微秒

三、RedisMemcached主要区别?

对比参数RedisMemcached
类型1、支持内存
2、非关系型数据库
1、把持内存
2、key-value键值对形式
3、缓存系统
数据存储类型1、String
2、List
3、Set
4、Hash
5、Sort Set【俗称ZSet
1、文本型
2、二进制类型【新版增加】
查询【操作】类型1、批量操作
2、事务支持【虽然是假的事务】
3、每个类型不同的CRUD
1、CRUD
2、少量的其他命令
附加功能1、发布/订阅模式
2、主从分区
3、序列化支持
4、脚本支持【Lua脚本】
多线程服务支持
网络IO模型单进程模式多线程、非阻塞IO模式
事件库自封简易事件库AeEvent贵族血统的LibEvent事件库
持久化支持1、RDB
2、AOF
不支持

四、请简述Redis常用数据类型和使用场景?

考察对Redis使用的掌握程度
1.String(字符串):用来实现简单的KV键值对存储,比如计数器
2.List(链表):实现双向链表,比如用户的关注,粉丝列表
3.Hash(哈希表):用来存储彼此相关信息的键值对
比如:用HSET key filed value格式存储用户相关信息:

HSET name[id: user_name]

4.Set(集合):存储不重复元素,比如用户的关注者
5.Sorted Set(有序集合):实时信息排行榜

五、延伸考点:Redis内置实现

对于中高级工程师,需要了解Redis各种类型的C底层实现方式
1.String:整数或者sdsSimple Dynamic String
2.Listziplit或者double linked list

说明:
ziplist:通过一个连续的内存块实现list结构,其中的每个entry节点头部保存前后节点长度信息,实现双向链表功能。

3.Hashziplist或者hashtable
4.Setintset或者hashtable
5.SortedSetskiplist跳跃表
6.深入学习请参考:《Redis设计与实现》
自我检查:你知道这些数据结构操作的时间和空间复杂度么?

六、Redis实现的跳跃表是什么结构?

Sorted Set为了简化实现,使用skiplist而不是平衡树实现
在这里插入图片描述

七、Redis有哪些持久化方式?

Redis支持两种方式实现持久化
1.快照方式:把数据快照放在磁盘二进制文件中,dump.rdb

快照的实现试是指定时间间隔把Redis数据库状态保存到一个压缩的二进制文件中。优点是可以恢复某个时间间隔的数据,缺点是一旦数据库宕机,该时间间隔的数据就会丢失。也可以直接在Redis的客户端执行savebgsave保存快照。

2.AOF(Append Only File):每一个写命令追加到appendonly.aof中。
这种方式不会因为宕机而丢失很多数据,缺点是文件会比较大
3.可以通过修改Redis配置实现选择哪种持久化方式

八、什么是Redis事务?

Mysql的事务有什么不同?
1.将多个请求打包,一次性、按序执行多个命令的机制
2.Redis通过MULTI, EXEC,WATCH等命令实现事务功能
3.Python redis-py pipeline=conn.pipeline(transaction=True)设置事务的功能

九、Redis如何实现分布式锁?

1.使用setnx实现加锁,可以同时通过expire添加超时
2.锁的value值可以使用一个随机的uuid或者特定的命名
3.释放锁的时候,通过uuid判断是否是该锁,是则执行delete释放锁

十、使用缓存的模式?

常用的缓存使用模式
1.Cache Aside:同时更新缓存和数据库(推荐使用)
2.Read/Write Through:先更新缓存,缓存负责同步更新数据库
3.Write Behind Caching:先更新缓存,缓存定期异步更新数据库

如何处理数据库和缓存之间的数据一致性问题?
可能导致问题:先更新数据库后更新缓存,并发写操作可能导致缓存读取的是脏数据。
解决方法:一般先更新数据库然后删除缓存

十一、如何解决缓存穿透问题?

大量查询不到的数据的请求落到后端数据库,数据库压力增大
1.由于大量缓存查不到就去数据库取,数据库也没有要查的数据。
比如:很多无脑爬虫通过自增id的方式爬取网站,网站查不到相关id的数据
2.解决:对于没有查到返回为None的数据也缓存
3.插入数据的时候删除是一项耳朵和,或者设置较短的超时时间。

十二、如何解决缓存击穿的问题?

某些非常热点的数据key 过期,大量请求打到后端数据库
1.热点数据key 失效导致大量请求打到数据库增加数据库压力
2.解决:
分布式锁:获取锁的线程从数据库拉数据更新缓存,其他线程等待
异步后台更新:后台任务针对过期的key 自动刷新(实现简单)

十四、如何解决缓存雪崩问题?

缓存不可用或者大量缓存key 同时失效,大量请求直接打到数据库

场景:
缓存不可用:有多个缓存服务器,其中一台或多台挂了,这时大量的请求落到少数的缓存服务器上,缓存可能承受不了了。
大量缓存key同时失效:设置缓存时可能会给类似的失效时间,导致短时间里有大量的缓存key失效

解决:
1.多级缓存:不同级别的key 设置不同的超时时间
2.随机超时:key的超时时间随机设置,防止同时超时
3.架构层:提升系统可用性。监控、报警完善

  • 作者:WinvenChang
  • 原文链接:https://blog.csdn.net/u014257214/article/details/117673124
    更新时间:2022-09-19 09:25:21