Java常见面试题之Redis

这篇具有很好参考价值的文章主要介绍了Java常见面试题之Redis。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Redis的数据类型

        Redis支持五中常用数据类型,string hash list set zset

Redis的持久化机制是什么

        Redis提供两种持久化机制,RDB和AOF机制

        RDB持久化机制,是指数据集快照的方式半持久化模式记录Redis数据库的所有键值对,在某个时间点将数据写入一个临时文件,持久化结束后,用这个临时文件替换上次的持久化文件,达到数据恢复.

优点:

  • 只有一个文件dump.rdb,方便持久化.
  • 容错性好,一个文件可以保存到安全的磁盘.
  • 性能最大化,fork子进程来完成写操作,让主进程继续处理命令,所以是IO最大化,使用单独的子进程进行持久化,主进程不会进行任何的IO操作,保证了Redis的高性能.
  • 相对于数据集大时,比AOF的启动效率更高.

缺点:数据安全性较低,RDB是间隔一段时间进行持久化,如果持久化之间Redis发生故障,会发生数据丢失.所以这种方式更适合数据要求不严谨的时候.

        AOF持久化机制:是指所有的命令行记录以Redis命令请求协议的格式完全持久化存储保存为aof文件.

优点:

  • 数据安全,aof持久化可以配置appendsync属性,有always,每进行一次命令操作就记录到aof文件中一次.
  • 通过append模式写文件,及时中途服务器宕机,可以通过redis-check-aof工具解决数据一致性问题.
  • AOF机制的rewrite模式,aof文件没有被rewrite之前,可以删除其中的某些命令

缺点:

  • aof文件比rdb文件大,且恢复速度慢.
  • 数据集大时,比RDB启动效率低

Redis过期策略,淘汰机制

        过期策略

        1.定时删除,当对一个key设置了过期时间,当该时间到期之后,立即执行对该key的删除,优点是对内存友好,保证key一旦过期就能立即从内存中删除.缺点:对CPU不友好,在过期的键数量较多的时候,删除过期的键需要占用一定的CPU时间,对服务器的响应时间和吞吐量造成影响.

        2.惰性删除,当一个key过期之后,并不会立即从内存中删除,而是在调用key的时候去检查其是否过期,如果过期,将其从内存中删除.优点是对CPU友好,只有在使用的时候才会检查.对于没有用到的key不会浪费时间进行过期检查.缺点:对内存不友好,key过期之后如果一直没有使用,就会一直占用这部分内存.如果Redis中存在很多过期键没有被使用,就永远不会删除,内存不会被释放,从而造成内存泄漏.

        3.定期删除,每隔一段时间,就随机抽取一些设置了过期时间的key进行检查,将其中过期的键删除掉,默认是1s执行10次定期删除,每次抽取5个.优点可以通过限制删除操作执行的时长和频率来减少删除的操作对CPU的影响.另外定期删除,也能有效释放过期键占用的内存.缺点:单一确定删除操作执行的时长和频率,如果执行的太频繁,定期删除策略变得和定时删除一样,对CPU不友好.如果执行频率太低,就和惰性删除一样,过期键占用的内存不会及时得到释放.而且,如果在获取某个键时,如果某个键的过期时间到了,但是还没执行定期删除,那么就会返回这个键的值,这是业务不能忍受的错误.

        淘汰策略.

  • no-eviction 当内存不足以容纳新数写入的数据时,新写入操作会报错.无法写入新数据,一般不操作.
  • allkeys-lru 当内存不足以容纳新写入的数据时,移除最近最少使用的key,这个是最常用的.
  • allkeys-random 当内存不足以容纳新写入的数据时,随机移除key
  • allkeys-lfu 当内存不足以容纳新写入的数据时,移除最少使用的key
  • volatile-lru 当内存不足以容纳新写入的数据时,在设置了过期时间的key中,移除最近最少使用的key
  • volatile-random 内存不足以容纳新写入新写入的数据时,在设置了过期的key中,随机删除一个.
  • volatile-lfu 当内存不足以容纳新写入的数据时,在设置了过期时间key中,移除最少使用的key
  • volatile-ttl 当内存不足以容纳新写入的数据时,在设置了过期时间的key中,优先移除剩余存货时间最短的.

Redis的事务

        Redis的事务不保证原子性,在Redis中,单条命令是原子性执行的,但事务不保证原子性,且没有回滚.事务中任意命令执行失败,其余的命令仍会被执行.

        Redis没有隔离级别的概念,批量操作在发送exec命令前被放入队列缓存,并不会被实际执行,也就不存在事务内的查询要看到的事务里的更新,所以事务外的查询是查不到的.

         优点:一次性按照顺序执行多个Redis命令,不受其他客户端命令请求影响,事务中的命令要么都执行,要么都不执行.

        缺点:事务执行时,不能保证原子性,命令入队每次都需要和服务器进行交互,增加带宽.

        注意:当事务中命令的语法使用错误时,最终会导致事务执行不成功,即事务中所有命令都不执行.当时事务中命令知识逻辑错误,就比如给字符串做加减乘除操作,只能在执行过程中发现错误,这种事务执行中失败的命令不影响其他命令的执行.

Redis集群,哨兵,主从复制模式

主从复制模式

        主从复制,是只将一台Redis服务器的数据复制到其他Redis服务器,前者成为主节点,master,后者成为从节点slave,数据的复制只能是从主节点到从节点.master节点可以增删改查数据,slave只能查询数据

        主从复制实现了数据的热备份,是持久化之外的一种数据冗余方式.当主节点出现问题之后,可以有从节点提供服务,实现快速的故障恢复.在主从复制的基础上,配合读写分离,可以右主节点提供写服务,由从节点提供读服务,尤其是在写少读多的场景下,通过多个从节点分担读负载,可以大大提高Redis服务器的并发量.除此之外,主从模式还是集群和哨兵能够实施的基础.

哨兵模式

        哨兵是一个分布式系统,用于对主从结构中的每台服务器进行监控,当出现故障时通过投票机制选择新的Master并将所有的Slave连接到新的Master.所以整个运行哨兵集群的数量不能少于3个节点.

        哨兵会不断检查主节点和从节点是否运作正常.当主节点不能正常工作时,哨兵会开始自动故障转移操作.它会将失效主节点的其中一个从节点升级为新的主节点.并让其他从节点改为复制新的主节点.

        哨兵结构由哨兵节点和数据节点组成,在整个哨兵系统中,会同时存在一个或多个哨兵节点组成,哨兵节点的特殊的Redis节点,不存储数据.主节点和从节点都是数据节点.

集群

        数据分区是集群最核心的功能.集群将数据分散到多个节点,一方面突破了Redis单机内存大小的限制,存储容量大大增加,另一方面,每个主节点都可以对外提供读服务和写服务,大大提高了集群的响应能力.

        集群支持主从复制模式和主节点的自动故障转移,当任意节点发送故障时,集群仍然可以对外提供服务.

      

Redis如果hash冲突,怎么解决

        当一个新的键值对要添加到字典中时,程序需要现根据键值对的键算出哈希值和索引值,然后再根据索引值,将包含新键值对的哈希表节点放到哈希表数组对应的指定索引上面.

        Redis中的hash冲突是指,两个key的哈希值和哈希桶计算对应关系时,正好落在了一个哈希桶中.

        Redis的哈希表是采用链地址法解决键冲突的,每个哈希表节点上都有一个next指针,多个哈希表节点可以用next指针构成一个单向链表,被分配到同一个索引上的多个节点可以用这个单向链表连接起来,这样就解决了键冲突的问题.

        

Redis实现分布式锁

        在分布式场景中,我们传统的synchronized和lock都失效了,所以此时需要一种全新的锁.redis提供的了一个命令--setnx,当我们使用这个命令去存储数据,如果当前的key已经存在,就不会进行任何操作,同时返回0,如果不存在,就会成功存储数据,返回1.

        根据这个机制,我们可以访问一个程序时,先存入一个约定好的key,value可以是我们当前的时间戳,如果存入成功,那我们就视为当前线程获取到了锁,如果存入失败了.我们就视为锁已被其他线程占有,当前线程没有获取到线程锁.在需要释放线程锁的时候,我们将这个key从redis中删除即可.

        同时,为了避免死锁,我们需要再setnx时对key 添加过期时间.

        在获取锁时,我们可以通过循环去不断尝试获取锁,如果获取到了就开始执行,如果没有获取到就一直获取.当然,我们也可以为这个循环添加一个超时时间.类似于自旋锁的自旋机制.

缓存穿透问题

        指查询一个不存在的数据,我们的机制是先去从缓存中读取,如果缓存中不存在的话会去数据库中查询,并且将查询到的结果存入缓存中.那如果数据库中也没有该数据,就不会放入缓存中,所以这种情况下就会去穿过缓存去访问数据库,这样就可能会导致数据库同时处理大量请求,可能导致数据库崩溃.

        解决方法

  1. 如果是非法参数,我们可以在api层做参数校验,在接受到请求之后就去处理非法参数.
  2. 如果是正确请求,但是数据库中不存在,那我们在缓存中针对该数据添加一个key,value设为null,给他一个过期时间,这样首次请求会到达数据库,但是其他请求都会被缓存拦截.
  3. 采用布隆过滤器判断数据是否存在,如果存在就继续往下查.

缓存击穿

        缓存击穿是指如果大量请求访问某个数据的时候这个数据失效了,就会穿过缓存访问数据库,这样对数据库造成大量压力,导致数据库崩溃

        我们可以通过设置热点数据永不过期去解决,但是这样可能会浪费资源,所以我们可以使用分布式锁进行对数据库的访问拦截,同一时间该类请求中只能有一个线程访问数据库.这样就会大大降低数据库的压力.

缓存雪崩

        缓存雪崩是指同时间大量热点数据同时失效,大量请求同时涌入数据库,导致数据库崩溃.

        解决方式

        首先最暴力的解决方式就是设置热点数据永不过期.

        其次就是对热点数据设置随机的过期时间,不让大量热点同时过期.

布隆过滤器

        布隆过滤器是有一个初始值为0的位图数组和n个哈希值组成的.当我们存储数据时,针对一个key通过多个hash算法取多个值,在位图数组中对这多个值对应的位置值改为1

        在查询的时候,还是先针对这个key做hash计算取多个值,如果这几个值对应的位置都是1,则代表这个key可能存在.如果其中有一个以上的0,则说明这个key一定不存在.

        例如:我们现在存储两条数据,其key分别为zhang和li,如果我们经过hash计算之后zhang得到了3个值,分别是1 3 5,那我们将位图中第 1 3 5位对应值分别改为1.li经过hash计算之后得到了 7  8  9,那我们将位图中第7 8 9对应的值分别改为1.至此,布隆过滤器中第 1 3 5 7 8 9位的值为1,,其余为0.

        我们现在开始查询key为wang和zhao 的两条数据,加入wang通过hash计算之后得到的3个值,分别是1 5 8,我们在位图数组上发现这三个位置对应的值都是1,所以布隆过滤器会认为这个值是可能存在的.zhao经过hash 计算之后得到的数据分别是 2 3 5,在位图数组上我们可以看到 3 5两个位置对应的值是1,但是2对应的值还是0,所以认为和这个key绝对不存在,就会被拦截.文章来源地址https://www.toymoban.com/news/detail-485676.html

到了这里,关于Java常见面试题之Redis的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 常见面试题之Redis篇(二)

    1. 什么是缓存穿透?怎么解决? 缓存穿透是指查询一个一定 不存在 的数据,如果从存储层查不到数据则不写入缓存,这将导致这个不存在的数据每次请求都要到 DB 去查询,可能导致 DB 挂掉。这种情况大概率是遭到了攻击。 解决方案的话,我们通常都会用布隆过滤器来解决

    2024年02月15日
    浏览(46)
  • Java并发常见面试题

    何为进程? 进程是程序的一次执行过程,是系统运行程序的基本单位,因此进程是动态的。系统运行程序,是一个进程从创建、运行到消亡的过程。 在Java中,当我们启动main函数时其实就是启动了一个JVM的进程,而main函数所在的线程就是这个进程中的一个线程,也称主线程

    2024年02月05日
    浏览(49)
  • Java-常见面试题收集(十)

    1 springboot 特点  1.自动配置:Spring Boot可以自动配置项目所需的常见配置,从而大大简化了项目的搭建和开发过程。开发者只需通过添加相应  2.的依赖,Spring Boot就会自动完成相关的配置工作。  3.独立运行:Spring Boot内嵌了如Tomcat、Jetty等Servlet容器,因此可以打包为jar或

    2024年04月14日
    浏览(41)
  • java常见面试题(160道)

    1. JDK 和 JRE 有什么区别? JDK:Java Development Kit 的简称,Java 开发工具包,提供了 Java 的开发环境和运行环境。 JRE:Java Runtime Environment 的简称,Java 运行环境,为 Java 的运行提供了所需环境。 具体来说 JDK 其实包含了 JRE,同时还包含了编译 Java 源码的编译器 Javac,还包含了很

    2024年02月09日
    浏览(46)
  • 【Java】常见面试题:多线程

    努力经营当下 直至未来明朗 答:① 进程包含线程; ② 线程比进程更轻量,创建更快、销毁也更快; ③ 同一个进程的多个线程之间共用一份内存和文件资源,而进程和进程之间则是独立的文件和内存资源;线程共用资源就省去了线程分配资源的过程 ④ 进程是资源分配的基

    2024年03月21日
    浏览(41)
  • Java常见面试题---面向对象篇

    什么是构造方法?构造方法有那些特点? 构造方法,是一种特殊的方法,它是一个与类同名的方法。 对象 的创建就是通过构造方法来完成,其功能主要是完成对象的 初始 化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也可以 重载 。 特点: 构造

    2024年02月22日
    浏览(41)
  • Java常见面试题之RabbitMQ

            RabbitMQ是一款非常优秀的消息中间件,它可以实现各个模块之间的松耦合,提高程序的灵活性,可扩展性,使用RabbitMQ主要有以下优点: 异步消息传递,RabbitMQ支持异步消息传递,可以实现异步处理消息,提高程序的执行效率. 消息队列排队服务,RabbitMQ可以将消息暂存到消息队列

    2024年02月09日
    浏览(51)
  • 【Java常见面试题】Spring篇

     导航: 【黑马Java笔记+踩坑汇总】JavaSE+JavaWeb+SSM+SpringBoot+瑞吉外卖+SpringCloud+黑马旅游+谷粒商城+学成在线+常见面试题 目录 1、简单介绍Spring 2、说说你对IOC的理解 3、说说你对AOP的理解 4、说说Bean的生命周期 5、说说循环依赖和三级缓存 6、说说Bean的几种注册方式 7、说说B

    2024年02月09日
    浏览(36)
  • Java线程池常见面试题详解

    池化技术 池化技术是一种常见的编程技巧, 把一些能够复用的东西(比如说数据库连接、线程)放到池中,避免重复创建、销毁的开销,在需要时可以重复使用这些预先准备的资源,从而极大提高性能。(提前保存大量资源, 以备不时之需) 线程池、数据库连接池、Http 连接池等

    2023年04月26日
    浏览(79)
  • java常见面试题:如何使用Java进行单元测试?

    单元测试是软件开发中的一个重要环节,它确保每个单独的代码单元都能按照预期工作。以下是如何使用Java进行单元测试的详细说明: JUnit : JUnit是Java中最流行的单元测试框架。 首先,添加JUnit依赖到你的项目中。如果你使用Maven,可以在 pom.xml 中添加以下依赖: 复制代码

    2024年02月02日
    浏览(54)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包