redis面试
rdb和aof的机制
rdb:在指定的时间间隔内将内存中的数据集快照写入磁盘,实际操作过程就是fork的一个子进程,先将数据集写入临时文件,写入成功后在替换之前的文件,用二进制压缩存储。
优点:
1.整个redis数据库只包含一个dump.rdb文件,方便持久化
2.容灾性好,方便备份。
3.性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以io最大化。使用单独子进程来进行持久化,主进程不会进行任何io操作,保证redis的高性能。
4.相对于数据集大时,比aof的启动效率高
缺点:
数据安全性低,rdb是间隔一段时间进行持久化的,如果间隔期间redis发生故障,会导致数据丢失。
aof
以日志的形式记录服务器所处理的每一个写的操作,删除操作。查询操作不会记录,以文本的方式记录,可以打开文件看到详细的操作记录。
优点:
1.数据的安全,redis中提供了三种同步的策越,每秒同步,每修改同步,不同步。事实上,每秒同步也是异步完成的,其效率是非常高的,所有一旦出现系统的宕机现象,那么这一秒之内修改数据会丢失。而每修改同步,我们可用将其视为同步持久化,每次发生的数据都会立即记录到磁盘中。
2.通过append模式写文件,即使中途服务器宕机也不会破会已存在的内容,可用通过redis-check-aof工具解决数据一致的问题。
3.aof的机制的rewrite模式:定期的向aof文件进行重写,以达到压缩的目的
缺点:
1.aof文件比rdb文件大,恢复速度慢
2.数据集大时,启动效率也比rdb慢
3.运行效率没有rdb高
者两中方式redis默认时使用rdb,如果两个方式都配了,会优先加载aof
redis的过期key的删除策略
1.惰性过期:只有当访问key的时候,才会区判断key是否过期,过期则清除。 key指向的value会占用大量内存,但是会节省cpu的资源,只有用到才会调用cpu
2.定期过期:每隔一段时间,扫描一定数量的key,并清除过期的key
redis同时使用了者两种策略
redis的线程模型,单线程为什么快
redis基于reactor模式(响应式模式)开发的网络事件处理器,这个文件处理器是单线程的,所以redis是单线程的模型,采用io多路复用机制来同时监听多个socket,根据socket上的事件类型来选择对应的事件处理器来处理这个事件,可以实现高性能的网络通信模型,又可以跟内部其他单线程的模块进行对接,保证了redis内部的线程模型的简单性。
单线程的快原因
1.纯内存的操作
2.核心是基于非阻塞的io多路复用机制
3.单线程反而避免了多线程的频繁上下文切换带来的性能问题
缓存雪崩,缓存穿透,缓存击穿
缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时间内承受大量请求而崩掉。
redis发生故障,重启服务,一时间请求都会落到数据库。
解决方案
1.缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
2.给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存标记失效,则更新数据缓存(会消耗内存)
3.缓存预热 在启动系统之前,写一个接口,讲热点数据放到缓存上去,在启动服务
4.互斥锁 查到一个缓存,发现缓存失效,在去查数据库的时候把key加锁,等查到数据后放到redis后在释放锁
缓存穿透:是指缓存和数据库中都没有的数据,导致所有的请求都落在数据库上,造成数据库短期内承受大量请求而崩掉
场景:用户恶意攻击
解决方案
1.接口层增加校验,如用户鉴权校验,id做基础校验,id<=0的直接拦截
2.从缓存取不到的数据,在数据库中也没有取到,这是也可以将key-value对写为key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也没法使用)。这样可以防止攻击用户反复用同一个id暴力攻击。
3.采用布隆过滤器,将所有可能存在的数据哈希到一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层存储系统的查询压力。
缓存击穿:指缓存中没有但数据库中有数据(一般是缓存时间到期),这时由于并发用户特别多,同时读缓存没有读到数据,又同时去数据库去取数据,引起数据库压力瞬间增大,造成过大压力,和缓存雪崩不同的是,缓存击穿并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库.
解决方案
设置热点数据永远不过期
加互斥锁
redis事务实现
原子性,要么全部执行,要么全部不执行,但是Redis的事务是不支持回滚操作的
一致性:Redis通过谨慎的错误检测和简单的设计保证事务的一致性。Redis事务可能出错的地方以及解决方案:
- 入队错误:如果一个事务在入队命令的过程中发现命令不存在或者命令格式不正确,Redis将拒绝执行这个事务
- 执行错误:事务在执行的过程中发生错误的命令会被服务器识别出来,并进行相应的错误处理,所以这些出错的命令不会对数据库做任何修改,也不会对事务的一致性产生任何影响
- 服务器停机:如果Redis服务器在执行事务的过程中停机,且服务器运行在任意模式下(无持久化的内存模式、RDB模式或者AOF模式),事务执行中途发生的停机都不会影响数据库的一致性
隔离性:Redis使用单线程的方式执行事务,并且服务器保证在执行事务期间不会对事务进行中断,因此,Redis的事务总是串行的方式运行,并且事务总是具有隔离性的
持久性:rdb和aof
Redis通过MULTI、EXEC、WATCH、DISCARD等命令来实现事务功能。主要有以下三个阶段:
MULTI命令的执行,标识着一个事务的开始 事务开启
当一个客户端切换到事务状态之后,服务器会根据这个客户端发送来的命令来执行不同的操作。如果客户端发送的命令为MULTI、EXEC、WATCH、DISCARD中的一个,立即执行这个命令,否则将命令放入一个事务队列里面 命令入队
当一个处于事务状态的客户端向服务器发送EXEC命令时,服务器会遍历这个客户端的事务队列,执行队列中保存的所有命令,最后将执行完的结果全部返回给客户端(每个命令对应一个返回) 事物执行
redis的集群方案
主从复制的概念
将一台主机redis服务器的数据,复制到其他的从机服务器上,主机只有一台,也成为主节点master节点,如果带一个redis的集群从机至少要两台
从机也称为从节点slave,数据的复制是单向的,只能从主节点到从节点,而主机以写为主,从机以读为主。
哨兵模式
哨兵的作用是监控Redis系统的运行状态,功能包括以下两个:
1.监控主数据库和从数据库是否正常运行
2.主数据库出现故障时自动将从数据库转换为主数据库
负载均衡算法,类型
1.轮询法
2.随机法
3.源地址哈希法
4.加权轮询法
分布式架构下,session共享有什么方案
1.采用无状态服务(jwt)
2.存到cookie中
3.存在redis中
4.session复制
分布式id生成方案
1.uuid 会生成时间戳,全局唯一的机器识别号
优点:代码简单,性能好(本地生成,没有网络消耗),保证唯一
缺点:1.每次生成的id都是无序的,无法保证趋势递增 2.生成的是字符串,存储性能会差3.长度过长,不适合存储,消耗数据库性能4.可读性查
2.数据库自增序列
必须是单点模式
3.雪花算法

浙公网安备 33010602011771号