当前位置:   article > 正文

java面试八股文--Redis_redis面试八股文

redis面试八股文

RDB和AOF机制

RDB:Redis DataBase

在指定的时间间隔内将内存的数据集快照写入磁盘,实际操作过程是fork一个子进程,先将数据集写入临时文件,写入成功后,再替换之前的文件,用二进制压缩存储

优点:

  1. 整个Redis数据库只包含一个文件dump.rdb,方便持久化
  2. 容灾性好,方便备份
  3. 性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化.使用单独子进程来进行持久化,主进程不会进行任何IO操作,保证了redis的高性能.
  4. 相对于数据集大时,比AOF的启动效率更高

缺点:

  1. 数据安全性低.RDB是间隔一段时间进行持久化,如果持久化之间redis发生故障,会发生数据丢失.所以这种方式更适合数据要求不严谨的时候.
  2. 由于RDB是通过fork子进程来协助完成数据持久化工作的,因此,如果当数据集较大时,可能会导致整个服务器停止服务几百毫秒,甚至是1秒钟.

AOF:Append Only File

以日止的形式记录服务器所处理的每一个些,删除操作,查询操作不会记录,以文本的方式记录,可以打开文件看到的详细的操作记录。

优点:

1.数据安全,Redis中提供了三种同步策略,即每秒同步,每修改同步和不同步。事实上,每秒同步也是异步完成的,其效率也是非常高的,所得是一旦系统出现宕机现象,那么一秒钟之内修改的数据将会丢失。而每修改同步那我们将其视为同步持久化,即每次发生的数据变化都被会立即记录到磁盘中。

2.通过append模式写文件,即使中途服务器宕机也不会破坏已经存在的内容,可以通过redis-check-aof工具解决数据一致性问题

3.AOF机制的rwriter模式,定期对AOF文件进行重写,以达到压缩的目的

缺点:

1.AOF文件比RDB文件大,且恢复速度慢

2.数据集大的时候,比RDB启动效率低

3.运行效率没有RDB高

AOF文件比RDB更新频率高,优先使用AOF还原数据

AOF比RDB更安全也更大

RDB性能比AOF好

如果两个都配了,优先加载AOF

Redis的过期键的删除策略

Redis是key-value数据库,我们可以设置Redis中缓存的key的过期时间。Redis的过期策略就是指当Redis中缓存的key过期了,Redis如何处理

  • 惰性过期:只有当访问一个key时,才会判断该ksy是否已过期,过期则清除。该策略可以最大化地节省CPU资源,却对内存非常不友好。极端情况下可能出现大量的过期key没有再次被访问,从而不会被清除,占用大量内存
  • 定期过期:每隔一定的时间,会扫描一定数量的数据库的expires字典中一定数量的key,并清除其中已过期的key。该策略是一个折中方案。通过调整定时扫描的时间间隔和每次扫描的限定耗时,已经在不同情况下使得CPU和内存资源达到最优的平衡结果。

(expires字典会保存所有设置了过期时间的key的过期时间数据,其中,key是指键空间的某个键的指针,value是盖键的毫秒精度的UNIX时间戳表示的过期时间。键空间是指该Redis集群中保存的所有键。)

Redis中同时使用了惰性过期和定期过期两种过期策略

Redis线程模型,单线程快的原因

Redis基于Reactor模式开发了网络时间处理器,这个处理器叫做文件事件处理器file event handler。这个文件事件处理器,它是单线程的,所以Redis才叫做单线程的模型,它采用IO多路复用机制来监听多个Socket,根据Socket上的时间类型来选择对应的事件处理器来处理这个事件。可以实现高性能的网络通信模型,又可以跟内部其他线程的模块进行拼接,保证了Redis内部的线程模型的简单性。

文件事件处理器的结构包含四个部分:多个Socket,IO多路复用程序,文件事件分派器以及事件处理器(命令请求处理器,命令回复处理器,连接应答处理器等)

多个Socket可能并发地产生不同的操作,每个操作对应不同的文件事件,但是IO多路复用程序会监听多个Socket,会将SOcket放入一个队列中排队,每次队列中取出一个Socket个事件分派器,事件分派器把Socket个对应的事件处理器。

然后一个Socket的事件处理完之后,IO多路复用程序才会将队列的下一个Socket给事件分派器。文件事件分派器会根据每个Socket当前产生的时间,来选择对应的事件处理器来处理。

单线程快的原因:

1.纯内存操作

2.核心是基于非阻塞的IO多路复用机制

3.单线程反而避免了多线程的频繁上下文切换带来的性能问题

简述Redis的事务实现

1.事务开始

MULTI命令的执行,标志着一个事务的开始。MULTI命令会将客户端状态的flags属性打开REDIS-MULTI标识来完成的

2.命令入队

当一个客户端切换到事务状态之后,服务器会根据这个客户端发送的命令来执行不同的操作。如果客户端发送的命令为MULTI,EXEC,WATCH,DISCARD中的一个,立即执行这个命令,否则将命令放入一个事务队列里面,然后向客户端返回QUEUE回复

  • 如果客户端发送的命令为EXEC、DISCARD、WATCH、MULTI四个命令中的一个,那么服务器立即执行这个命令
  • 如果客户端发送的时候四个命令以外的其他命令,那么服务并不立即执行这个命令。受限价差此命令的格式时都正确,如果不正确,服务器会在客户端状态(redisClient)的flags属性关闭REDIS-MULTI标识,并返回错误信息个客户端。如果正确,将这个命令放入一个事务队列里面,然后向客户端返回QUEUE回复

事务队列时依照FIFO的方式保存入队的命令

3.事务执行

客户端发送EXEC命令。服务器执行EXEC命令逻辑

  • 如果客户端状态的flags属性不包括REDIS-MULTI标识,或者包含REDIS-DIRTY-CAS或者REDIS-DIRTY-EXEC标识,那么久直接取消事务的执行.
  • 否则客户端处于事务状态(flags有REDIS-MULTI),服务器会遍历客户端的事务队列,然后执行事务队列中的所有命令,最后将返回结果全部返回给客户端

redis不支持事务回滚机制,但是它会检查每一个事务中的命令是否错误

Redis的事务不只是检查哪些程序员自己的逻辑错误.例如对String类型的数据库键执行HashMap类型的操作!

  • WATCH命令是一个乐观锁,可以为Redis事务提供check-and-set(CAS)行为.可以监控一个或多个键,一旦其中有一个键被修改(或删除),之后的事务就不会执行,监控一直持续到EXEC命令
  • MULTI命令用于开启一个事务,它总是返回OK,MULTI执行之后,客户端可以继续向服务器发送任意多条命令,这些命令不会立即执行,而是被放到一个队列中,当EXEC命令被调用时,所有队列里的命令才会被执行
  • EXEC:执行所有事务块内的命令.返回事务块内所有命令的返回值,按命令知识的先后顺序排序.当操作被打断时,返回空值nil。
  • 通过调用DISCARD,客户端可以清空事务队列,并放弃执行事务,并且服务端会从事务状态中退出。
  • UNWATCH命令可以取消watch对所有key的监控

Redis集群方案

主从

哨兵模式:

sentinel,哨兵是redis集群中非常重要的一个组件,主要有以下功能:

  • 集群监控:负责监控redis master和slave进程是否正常工作
  • 消息通知:如果某个redis实例有故障,那么哨兵负责发送消息作为报警通知给管理员
  • 故障转移:如果master node挂掉了,会自动转移到slave node 上
  • 配置中心:如果故障转移发生了,通知client客户端新的master地址

哨兵用于实现redis集群的高分用,本身也是分布式的,作为一个哨兵集群去运行,互相协同工作

  • 故障转移时,判断一个master node是否宕机了,需要大部分的哨兵统一才行,涉及到了分布式选举
  • 及时部分哨兵结点挂掉了,哨兵集群还是能正常工作的
  • 哨兵通常需要三个实例,来保证自己的健壮性
  • 哨兵+redis主从的不是架构,是不保证数据零丢失的,只能baozhengredis集群的高可用性
  • 对于哨兵+redis主从的这种复杂的部署架构,尽量在测试环境和生产环境,都进行充足的测试和演练

Redis Cluster是一种服务端Sharding技术,3.0版本开始正式提供。采用slot(槽)的概念,一共分成16384个槽。将请求发送到任意结点,接受到请求的节点会将查询请求发送给正确的节点上执行

方案说明:

  • 通过哈希的方式,将数据分片,每个节点均分存储一定的哈希槽(哈希值)区间的数据,默认分配了16384个槽位
  • 每份数据分片会存储在多个互为主从的多节点上
  • 数据写入主节点,再同步到从节点(支持配置为阻塞同步)
  • 同一分片多个结点的数据不保持强一致性
  • 读取数据时,当客户端操作的key没有分配在该节点上时,redis会返回转向指令,指向正确的节点
  • 扩容时需要把旧节点的数据迁移一部分到新节点

在redis cluster架构下,每个redis要放开两个端口号,比如一个是6397,另外一个就是加1w的端口号,比如16379

16379端口号是用来进行节点间通信的,也就是cluster bus的通信,用来进行故障检测,配置更新,故障转移授权。cluster bus用了另外一种二进制的协议,gossip协议,用于节点间进行高效的数据交换,占用更少的网络带宽和处理时间。

优点:

  • 无中心架构,支持动态扩容,对业务透明
  • 具备Sentinel的监控和自动Failover(故障转移)能力
  • 客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可
  • 高性能,客户端直连redis服务,免去了proxy代理的损耗

缺点:

  • 运维也很复杂,数据迁移需要人工干预
  • 只能使用0号数据库
  • 不支持批量操作(pipeline管道操作)
  • 分布式逻辑和存储模块耦合等

Redis Sharding是Redis Cluster出来之前,业界普遍使用的多Redis实例集群方法。其主要思想是采用哈希算法将Redis数据的key进行散列,通过hash函数,特定的key会映射到特定的Redis节点上,java redis客户端驱动jedis,支持Redis Sharding功能,即ShardedJedis以及结合缓存池的ShardedJedisPool

优点:

优势在于非常简单,服务器端的Redis实例彼此独立,相互无关联,每个Redis实例像单服务器一样运行,非常容易线性拓展,系统的灵活性很强

缺单:

由于Sharding处理放到客户端,规模进一步扩大时会给运维带来挑战

客户端Sharding不支持动态增删节点。服务端Redis实例化群拓扑结构有变化时,每个客户端都需要更新调整,连接不能共享,当应用规模增大时买资源浪费制约优化

Redis主从复制的核心原理

通过执行salveof命令或设置slaveof选项,让一个服务器去复制另外一个服务器的数据。主数据库可以进行读写操作,当写操作导致数据变化时会自动将数据同步给从数据库,而从数据库一般是只读的,并接受主数据库同步过来的数据。一个主数据库可以拥有多个从数据库,而一个从数据库只能拥有一个主数据库。

全量复制:

1.主节点通过bgsave命令fork子线程进行RDB持久化,该过程是非常消耗CPU,内存(页表复制)、硬盘IO的

2.主节点通过网络将RDB文件发送给从节点,对主节点的宽带会带来很大的消耗

3.从节点清空老数据,载入新RDB文件的过程是阻塞的,无法响应客户端的命令,如果从节点执行bgrewriteaof,也会带来额外的消耗

部分复制:

1.赋值偏移量:执行复制的双方,主从节点分别维护一个复制偏移量offset

2.复制积压缓冲区:主节点内部维护了一个固定长度的,先进先出(FIFO)队列,做为赋值积压缓冲区,当主从节点offset的差距过大超过缓冲区长度时,将无法执行部分复制,只能执行全量复制

3.服务器运行ID(runid):每个Redis结点,都有其运行ID,运行ID由结点在启动时自动生成,主节点会将自己的运行ID发送给从节点,从节点会将主节点的运行ID存起来。从节点Redis断开重连时的时候,就是根据运行ID来判断同步的进度:

  • 如果从节点保存的runid与主节点现在的runid相同,说明主从节点之前同步过,主节点会继续尝试使用部分复制(到底能不能部分复制还要看offset和复制积压缓冲区的情况)
  • 如果从节点保存的runid与主节点现在的不同,说明从节点在断线前同步的Redis节点并不是当前的主节点,只能进行全量复制

过程原理:

缓存雪崩,缓存穿透,缓存击穿 

缓存雪崩是指缓存同一时间大面积的失效,所以,后面的请求都会落到数据库上,造成数据库短时内承受大量请求而崩掉

解决方案:

  • 给缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生
  • 给每一个缓存数据增加相应的缓存标记,记录缓存是否失效,如果缓存标记失效,则更新数据缓存
  • 缓存预热
  • 互斥锁

缓存击穿是指缓存和数据库中都没有的数据,导致所有的请求都落到受苦上,造成数据库短时内承受大量请求而崩掉

解决方案:

  • 接口层增加校验,如用户劝校验,id做基础校验,id》<=0的直接拦截;
  • 从缓存取不到的数据,在数据库也没有取到,这是也可以将key-value对写成key-null,缓存有效时间可以设置短点,如30秒(设置太长会导致正常情况也无法使用),这样可以防止攻击用户反复用同一个id暴力攻击
  • 采用布隆过滤器,将所有可能存在的数据哈西道一个足够大的bitmap中,一个一定不存在的数据会被这个bitmap拦截掉,从而避免了对底层数据的查询压力

缓存击穿是指缓存中没有但数据库中有的数据(一般是缓存时间到期),这是由于并发用户特别多,同时读缓存没读到数据,又同时去数据库取数据,引起数据库压力瞬间增大,造成过大压力,和缓存雪崩不同的是,缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

解决方案:

  • 设置热点数据永远不过期
  • 加互斥锁

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/人工智能uu/article/detail/823636
推荐阅读
相关标签
  

闽ICP备14008679号