8-4 缓存机制及Redis常考面试题
Posted WinvenChang
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了8-4 缓存机制及Redis常考面试题相关的知识,希望对你有一定的参考价值。
一、考点聚焦
缓存的使用场景;Redis
的使用;缓存使用中的坑
1.为什么要使用缓存?使用场景?
2.Redis
的常用数据类型,使用方式
3.缓存使用问题:数据一致性问题;缓存穿透、击穿、雪崩问题
二、什么是缓存?为什么要使用缓存?
本章主要讨论的是内存缓存(常见的有Redis
和Memcached
)
1.缓解关系数据库(常见的是mysql
)并发访问的压力:热点数据
2.减少响应时间:内存IO
速度比磁盘快
3.提升吞吐量:Redis
等内存数据库单机就可以支撑很大并发
操作时间对比:
操作 | 响应时间 |
---|---|
打开一个网站 | 几秒 |
在数据库中查询一条记录(有索引) | 十几毫秒 |
机械苏特给次寻址定位 | 4 毫秒 |
从机械磁盘顺序读取1MB 数据 | 2 毫秒 |
从SSD 磁盘顺序读取1MB 数据 | 0.3 毫秒 |
从远程分布式缓存Redis 读取一个数据 | 0.5 毫秒 |
从内存中读取1MB 数据 | 十几微秒 |
Java 程序本地方法调用 | 几微秒 |
网络传输2KB 数据 | 1 微秒 |
三、Redis
和Memcached
主要区别?
对比参数 | Redis | Memcached |
---|---|---|
类型 | 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
:整数或者sds
(Simple Dynamic String
)
2.List
:ziplit
或者double linked list
说明:
ziplist
:通过一个连续的内存块实现list
结构,其中的每个entry
节点头部保存前后节点长度信息,实现双向链表功能。
3.Hash
:ziplist
或者hashtable
4.Set
:intset
或者hashtable
5.SortedSet
:skiplist
跳跃表
6.深入学习请参考:《Redis
设计与实现》
自我检查:你知道这些数据结构操作的时间和空间复杂度么?
六、Redis
实现的跳跃表是什么结构?
Sorted Set
为了简化实现,使用skiplist
而不是平衡树实现
七、Redis
有哪些持久化方式?
Redis
支持两种方式实现持久化
1.快照方式:把数据快照放在磁盘二进制文件中,dump.rdb
。
快照的实现试是指定时间间隔把Redis
数据库状态保存到一个压缩的二进制文件中。优点是可以恢复某个时间间隔的数据,缺点是一旦数据库宕机,该时间间隔的数据就会丢失。也可以直接在Redis
的客户端执行save
或bgsave
保存快照。
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.架构层:提升系统可用性。监控、报警完善
以上是关于8-4 缓存机制及Redis常考面试题的主要内容,如果未能解决你的问题,请参考以下文章
2021-05-13 Redis面试题 简单说说缓存雪崩及解决方法