(计算机基础 核心知识)Redis
1.什么情况下使用redis
- 针对热点数据进行缓存
- 对于特定限时数据的存放
- 针对带热点权值数据的排序list
- 分布式锁
在许多的场景中,我们为了保证数据的最终一致性,需要很多的技术方案来支持,比如分布式事务、分布式锁等。很多时候我们需要保证一个方法在同一时间内只能被同一个线程执行。在单机环境中,通过 Java 提供的并发 API 我们可以解决,但是在分布式环境下,就没有那么简单啦。
- 分布式与单机情况下最大的不同在于其不是多线程而是多进程。
- 多线程由于可以共享堆内存,因此可以简单的采取内存作为标记存储位置。而进程之间甚至可能都不在同一台物理机上,因此需要将标记存储在一个所有进程都能看到的地方。
什么是分布式锁?
- 当在分布式模型下,数据只有一份(或有限制),此时需要利用锁的技术控制某一时刻修改数据的进程数。
- 与单机模式下的锁不仅需要保证进程可见,还需要考虑进程与锁之间的网络问题。(我觉得分布式情况下之所以问题变得复杂,主要就是需要考虑到网络的延时和不可靠。。。一个大坑)
- 分布式锁还是可以将标记存在内存,只是该内存不是某个进程分配的内存而是公共内存如 Redis、Memcache。至于利用数据库、文件等做锁与单机的实现是一样的,只要保证标记能互斥就行。
2.简述Redis过期策略
- 定期删除,redis默认是每100ms就随机抽取一些设置了过期时间的key,并检查其是否过期,如果过期就删除。因此该删除策略并不会删除所有的过期key。
- 惰性删除,在客户端需要获取某个key时,redis将首先进行检查,若该key设置了过期时间并已经过期就会删除。
实际上redis结合上述两种手段结合起来,保证删除过期的key。
3.Redis数据类型
- String:字符串类型,最简单的类型
- Hash:类似于Map的一种结构。 是一个键值(key=>value)对集合。
- List:有序列表。
- Set: 无序集合。 Redis 的 Set 是 string 类型的无序集合。集合是通过哈希表实现的,所以添加,删除,查找的复杂度都是 O(1)。
- ZSet:带权值的集合,即每个ZSet元素还另有一个数字代表权值,集合通过权值进行排序。zset 和 set 一样也是string类型元素的集合,且不允许重复的成员。不同的是每个元素都会关联一个double类型的分数。redis正是通过分数来为集合中的成员进行从小到大的排序。zset的成员是唯一的,但分数(score)却可以重复。
4.简述Redis的RDB
RDB即将当前数据生成快照,并保存于硬盘中。可以通过手动命令,也可以设置自动触发。
RDB 就是 Redis DataBase 的缩写,中文名为快照/内存快照,RDB持久化是把当前进程数据生成快照保存到磁盘上的过程,由于是某一时刻的快照,那么快照中的值要早于或者等于内存中的值。
触发rdb持久化的方式有2种,分别是手动触发和自动触发
save命令是redis手动触发RDB过程的命令。使用该命令后,服务器阻塞,直到RDB过程完成后终止。该过程占用内存较多。
自动触发
- 通过配置文件,设置一定时间后自动执行RDB
- 如采用主从复制过程,会自动执行RDB
5.Redis快的原因
- redis是基于内存的数据库,内存数据读取存储效率远高于硬盘型
- redis采用多路复用技术通过采用epoll的非阻塞IO,提升了效率
6.简述主从复制模式
在主从复制中,有主库(Master)节点和从库(Slave)节点两个角色。 从节点服务启动会连接主库,并向主库发送SYNC命令。
主节点收到同步命令,启动持久化工作,工作执行完成后,主节点将传送整个数据库文件到从库,从节点接收到数据库文件数据之后将数据进行加载。此后,主节点继续将所有已经收集到的修改命令,和新的修改命令依次传送给从节点,从节点依次执行,从而达到最终的数据同步。
通过这种方式,可以使写操作作用于主库,而读操作作用于从库,从而达到读写分离。
7.简述缓存雪崩/缓存击穿/缓存穿透的解决方法
什么是缓存雪崩?
当某一个时刻出现大规模的缓存失效的情况,那么就会导致大量的请求直接打在数据库上面,导致数据库压力巨大,如果在高并发的情况下,可能瞬间就会导致数据库宕机。这时候如果运维马上又重启数据库,马上又会有新的流量把数据库打死。这就是缓存雪崩。
什么是缓存击穿?
其实跟缓存雪崩有点类似,缓存雪崩是大规模的key失效,而缓存击穿是一个热点的Key,有大并发集中对其进行访问,突然间这个Key失效了,导致大并发全部打在数据库上,导致数据库压力剧增。这种现象就叫做缓存击穿。
关键在于某个热点的key失效了,导致大并发集中打在数据库上。所以要从两个方面解决,第一是否可以考虑热点key不设置过期时间,第二是否可以考虑降低打在数据库上的请求数量。
解决方案:
1、上面说过了,如果业务允许的话,对于热点的key可以设置永不过期的key。
2、使用互斥锁。如果缓存失效的情况,只有拿到锁才可以查询数据库,降低了在同一时刻打在数据库上的请求,防止数据库打死。当然这样会导致系统的性能变差。
什么是缓存穿透?
我们使用Redis大部分情况都是通过Key查询对应的值,假如发送的请求传进来的key是不存在Redis中的,那么就查不到缓存,查不到缓存就会去数据库查询。假如有大量这样的请求,这些请求像“穿透”了缓存一样直接打在数据库上,这种现象就叫做缓存穿透。
分析:
关键在于在Redis查不到key值,这和缓存击穿有根本的区别,区别在于缓存穿透的情况是传进来的key在Redis中是不存在的。假如有黑客传进大量的不存在的key,那么大量的请求打在数据库上是很致命的问题,所以在日常开发中要对参数做好校验,一些非法的参数,不可能存在的key就直接返回错误提示,要对调用方保持这种“不信任”的心态。
1、把无效的Key存进Redis中。如果Redis查不到数据,数据库也查不到,我们把这个Key值保存进Redis,设置value="null",当下次再通过这个Key查询时就不需要再查询数据库。这种处理方式肯定是有问题的,假如传进来的这个不存在的Key值每次都是随机的,那存进Redis也没有意义。
- 缓存数据设置随机过期时间,防止同一时间大量数据过期。
- 设置热点数据永远不过期。
- 对于集群部署的情况,将热点数据均与分布在不同缓存中。
- 使用熔断机制。当流量到达一定的阈值时,就直接返回“系统拥挤”之类的提示,防止过多的请求打在数据库上。至少能保证一部分用户是可以正常使用,其他用户多刷新几次也能得到结果。
- 提高数据库的容灾能力,可以使用分库分表,读写分离的策略。
- 为了防止Redis宕机导致缓存雪崩的问题,可以搭建Redis集群,提高Redis的容灾性。
8.MySQL与Redis区别
MySQL是,主要用于存
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
曾获多国内大厂的 ssp 秋招 offer,且是Java5年的沉淀老兵(不是)。专注后端高频面试与八股知识点,内容系统详实,覆盖约 30 万字面试真题解析、近 400 个热点问题(包含大量场景题),60 万字后端核心知识(含计网、操作系统、数据库、性能调优等)。同时提供简历优化、HR 问题应对、自我介绍等通用能力。考虑到历史格式混乱、质量较低、也在本地积累了大量资料,故准备从头重构专栏全部内容