zoukankan      html  css  js  c++  java
  • redis面试题

     1-3,分布式缓存

            在高并发的分布式的系统中,缓存是必不可少的一部分。没有缓存对系统的加速和阻挡大量的请求直接落到系统的底层,系统是很难撑住高并发的冲击,所以分布式系统中缓存的设计是很重要的一环。

         分布式缓存特性

    高性能:当传统数据库面临大规模数据访问时,磁盘I/O往往成为性能瓶颈,从而导致过高的响应延迟,能够将高速内存作为数据对象的存储介质,数据以key/value形式存储,理想情况下可以获得DRAM(动态随机存取存储器(Dynamic Random Access Memory))级的读写性能;

    动态扩展性:支持弹性扩展,通过动态增加或减少节点应对变化的数据访问负载,提供可预测的性能与扩展性;同时最大限度地提高资源利用率;

    高可用性:可用性包含数据可用性与服务可用性两方面.基于冗余机制实现高可用性,无单点失效,支持故障的自动发现,透明地实施故障切换,不会因服务器故障而导致缓存服务中断或数据丢失.动态扩展时自动均衡数据分区,同时保障缓存服务持续可用;

    易用性:提供单一的数据与管理视图,API接口简单,,且与拓扑结构无关,动态扩展或失效恢复时无需人工配置,自动选取备份节点,多数缓存系统提供了图形化的管理控制台,便于统一维护。

        分布式缓存优点

    1,提升数据读取速度

    2,提升系统扩展能力   

    3,降低存储成本 

       分布式缓存应用场景

    1,用来缓存Web页面的内容片段,包括HTML、CSS和图片等,多应用于社交网站等;

    2,缓存系统作为ORM框架的二级缓存对外提供服务,减轻数据库的负载压力,加速应用访问;

    3,缓存包括Session会话状态及应用横向扩展时的状态数据等;,

    4,并行处理,涉及大量中间计算结果需要共享;

    5,分布式缓存提供了针对事件流的连续查询(continuousquery)处理技术,满足实时性需

    6,分布式缓存为事务型应用提供高吞吐率、低延时的解决方案,支持高并发事务请求处理,多应用于铁路、金融服务和电信等领域。

    4,redis 简介

           nosql框架  ,   持久化(数据库)   缓存(基于内存,速度快),  消息队列(list)

    Redis 是一个开源的使用 ANSI C 语言编写、遵守 BSD 协议、支持网络、可基于内存亦可持久化的日志型、Key-Value 数据库,并提供多种语言的 API的非关系型数据库。

     

    5,Redis 有什么数据类型?分别用于什么场景?

         字符串(strings):微博数,粉丝数,验证码,分布式锁(setnx expire)等

          散列(hashes):可以Hash数据结构来存储用户信息,商品信息等等。

    列表(lists)有序,值不可重复:关注列表,粉丝列表,消息队列等功能都可以用Redis的 list 结构来实现

    集合(sets)无序,值不可重复:共同关注、共同粉丝、共同喜好等功能

    有序集合 有序,值不可重复(sorted sets):地理位置功能(geo),各种排行榜,如在直播系统中,实时排行信息包含直播间在线用户列表,各种礼物排行榜,弹幕消息

    6,Redis有哪些适合的场景?

    1)Session共享(单点登录)

    2)页面缓存

    3)队列(消息队列)

    4)排行榜/计数器

    5)发布/订阅(注册中心)

    redis bgsave和save的区别

         SAVE 和 BGSAVE 两个命令都会调用 rdbSave 函数

     但它们调用的方式各有不同:

    SAVE 直接调用 rdbSave ,阻塞 Redis 主进程,直到保存完成为止。在主进程阻塞期间,服务器不能处理客户端的任何请求。

    BGSAVE 则 fork 出一个子进程,子进程负责调用 rdbSave ,并在保存完成之后向主进程发送信号,通知保存已完成。因为 rdbSave 在子进程被调用,所以 Redis 服务器在BGSAVE 执行期间仍然可以继续处理客户端的请求。

    7,Redis 的持久化方式?有什么优缺点?持久化实现原理?

    redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化),另外一种是AOF持久化(原理是将Reids的操作日志以追加的方式写入文件)。

    区别:

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

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

                       

        rdb优缺点:

               优:

              1)适合备份(它保存了 Redis 在某个时间点上的数据集。 这种文件非常适合用于进行备份: 比如说,你可以在最近的 24 小时内,每小时备份一次 RDB 文件,并且在每个月的每一天,也备份一个 RDB 文件。 这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。)

              2)适合容灾(它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心 )

              3)性能最大化(父进程在保存 RDB 文件时唯一要做的就是 fork 出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘 I/O 操作。)

              4 )  恢复数据快(与aop相比)

               缺:

               1) 容易丢失数据

               2) 数据庞大时,影响主进程( 在数据集比较庞大时, fork() 可能会非常耗时,造成服务器在某某毫秒内停止处理客户端; 如果数据集非常巨大,并且 CPU 时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。 )

        aop优缺点:

              优:

                   1)更高数据安全性(默认配置,最多只丢失一秒数据)

                   2)便于恢复(写入过程中即使出现宕机现象,也不会破坏日志文件中已经存在的内容。然而如果我们本次操作只是写入了一半数据就出现了系统崩溃问题,不用担心,在Redis下一次启动之前,我们可以通过redis-check-aof工具来帮助我们解决数据一致性的问题。)

                  3) 通过重写(rewrite)功能,不让文件体积大(即Redis以append模式不断的将修改数据写入到老的磁盘文件中,同时Redis还会创建一个新的文件用于记录此期间有哪些修改命令被执行。因此在进行rewrite切换时可以更好的保证数据安全性)

                   4) aof内容更容易读懂(AOF 文件有序地保存了对数据库执行的所有写入操作, 这些写入操作以 Redis 协议的格式保存, 因此 AOF 文件的内容非常容易被人读懂, 对文件进行分析 也很轻松)

              缺:

                     1) 相同数量数据,aof体积大于rdb,  rdb恢复数据速度快

                       2) 根据同步策略的不同,AOF在运行效率上往往会慢于RDB

              

               https://blog.csdn.net/denghonghao/article/details/82108770

    8,Redis 的主从复制是如何实现的?

     

    1. 从服务器连接主服务器,发送 SYNC(同步) 命令;ASYNC(异步)
    2. 主服务器接收到 SYNC 命名后,开始执行 BGSAVE 命令生成 RDB 文件并使用缓冲区记录此后执行的所有写命令;
    3. 主服务器 BGSAVE 执行完后,向所有从服务器发送快照文件,并在发送期间继续记录被执行的写命令;
    4. 从服务器收到快照文件后丢弃所有旧数据,载入收到的快照;
    5. 主服务器快照发送完毕后开始向从服务器发送缓冲区中的写命令;
    6. 从服务器完成对快照的载入,开始接收命令请求,并执行来自主服务器缓冲区的写命令;

    9-11 Redis 有哪些架构模式?讲讲各自的特点

        单机版

        特点:简单

    问题:

    1、内存容量有限 2、处理能力有限 3、无法高可用

    主从复制

    特点:

    1、master/slave 角色

    2、master/slave 数据相同

    3、降低 master 读压力在转交从库

    问题:

    1,无法保证高可用(写)

    2,没有解决 master 写的压力

    哨兵

         特点:

    1、保证高可用

    2、监控各个节点

    3、自动故障迁移

    问题:

    1、主从模式,切换需要时间丢数据

    2、没有解决 master 写的压力

    集群

          特点:

    1、无中心架构(不存在哪个节点影响性能瓶颈),少了 proxy 层。

    2、数据按照 slot 存储分布在多个节点,节点间数据共享,可动态调整数据分布。

    3、可扩展性,可线性扩展到 1000 个节点,节点可动态添加或删除。

    4、高可用性,部分节点不可用时,集群仍可用。通过增加 Slave 做备份数据副本

    5、实现故障自动 failover,节点之间通过 gossip 协议交换状态信息,用投票机制完成 Slave到 Master 的角色提升。

    问题:

    1、资源隔离性较差,容易出现相互影响的情况(多个业务使用同一套集群时,无法根据统计区分冷热数据)。

    2、数据通过异步复制,不保证数据的强一致性

    12,什么是一致性哈希算法?什么是哈希槽?

    https://www.cnblogs.com/lpfuture/p/5796398.html

     哈希槽

     从redis 3.0之后版本支持redis-cluster集群,Redis-Cluster采用无中心结构,每个节点保存数据和整个集群状态,每个节点都和其他所有节点连接。

     

      1、所有的redis节点彼此互联(PING-PONG机制),内部使用二进制协议优化传输速度和带宽。

         2、节点的fail是通过集群中超过半数的节点检测失效时才生效。

         3、客户端与redis节点直连,不需要中间proxy层.客户端不需要连接集群所有节点,连接集群中任何一个可用节点即可。

         4、redis-cluster把所有的物理节点映射到[0-16383]slot上(不一定是平均分配),cluster 负责维护node<->slot<->value。

         5、Redis集群预分好16384个桶,当需要在 Redis 集群中放置一个 key-value 时,根据 CRC16(key) mod 16384的值,决定将一个key放到哪个桶中。CRC16(key) mod 16384=0-16383之间的一个数字  

    14-16 缓存穿透、缓存击穿、缓存雪崩区别和解决方案

    缓存处理流程

     前台请求,后台先从缓存中取数据,取到直接返回结果,取不到时从数据库中取,数据库取到更新缓存,并返回结果,数据库也没取到,那直接返回空结果。

    缓存穿透

     缓存穿透是指缓存和数据库中都没有的数据,而用户不断发起请求,如发起为id为“-1”的数据或id为特别大不存在的数据。这时的用户很可能是攻击者,攻击会导致数据库压力过大。

    1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。

    2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中(布隆过滤器),查询时通过该bitmap过滤。

    缓存击穿

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

    如何避免?

    1. 设置热点数据永远不过期。
    2. 加互斥锁,互斥锁参考思路如下

             1)缓存中有数据,直接返回结果了

             2)缓存中没有数据,第1个进入的线程,获取锁并从数据库去取数据,没释放锁之前,其他并行进入的线程会等待100ms,再重新去缓存取数据。这样就防止都去数据库重复取数据,重复往缓存中更新数据情况出现。

    缓存雪崩

         缓存雪崩是指缓存中数据大批量到过期时间,而查询数据量巨大,引起数据库压力过大甚至down机。和缓存击穿不同的是, 缓存击穿指并发查同一条数据,缓存雪崩是不同数据都过期了,很多数据都查不到从而查数据库。

    如何避免?

    1. 缓存数据的过期时间设置随机,防止同一时间大量数据过期现象发生。
    2. 如果缓存数据库是分布式部署,将热点数据均匀分布在不同的缓存数据库中。
    3. 设置热点数据永远不过期。

    17,使用过Redis分布式锁么,它是怎么实现的?

         

    如何使用redis完成分布式锁

    1,使用setnx mylock "AAA"  等同于 set mylock "AAA" NX 设置一把锁,如果不存在可以设置,已经存在不可以设置

       set lock "111" EX  5 NX 当lock不存在时,设置lock为111 失效时间为5秒

    2,设置成功的线程执行业务,一般都是正常,如果执行业务过程中出现异常

    3,执行任务完成,使用 del mylock删除这把锁

    4,如果第2步出现异常,第3步没有执行,就会出现死锁等情况,造成大量请求等待,使用exprie把第1步锁设置上失效时间,当

      第2步出现异常,第3步不执行时,锁也会自动释放 expire mylock 30 设置失效时间,不固定,根据第2步大于执行业务的时间

    Redis为单线程模式,采用队列模式将并发访问变成串行访问,且多客户端对Redis的连接并不存在竞争关系Redis中可以使用SETNX命令实现分布式锁。

    将 key 的值设为 value ,当且仅当 key 不存在。 若给定的 key 已经存在,则 SETNX 不做任何动作 

    解锁:使用 del key 命令就能释放锁

    解决死锁:

    1)通过Redis中expire()给锁设定最大持有时间,如果超过,则Redis来帮我们释放锁。

    2) 使用 setnx key “当前系统时间+锁持有的时间”和getset key “当前系统时间+锁持有的时间”组合的命令就可以实现。

    18, 使用过Redis做异步队列(mq)么,你是怎么用的?有什么缺点?

    一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。

    缺点:

      在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq,kafka等。

    19,Redis的单线程为什么这么快

    1.redis是基于内存的,内存的读写速度非常快;

    2.redis是单线程的,省去了很多上下文切换线程的时间(上下文切换就是cpu在多线程之间进行轮流执行(抢占cpu资源),而redis单线程的,因此避免了繁琐的多线程上下文切换。);

    3.redis使用多路复用技术,可以处理并发的连接;

    多路复用技术:

    多路-指的是多个socket连接,复用-指的是复用一个线程。

    目前,多路复用主要有三种技术:select,poll,epoll。它们出现的顺序是按时间先后的,越排后的技术改正了之前技术的缺点。epoll是最新的也是目前最好的多路复用技术。

    举个例子:一个酒吧服务员,前面有很多醉汉,epoll这种方式相当于一个醉汉吼了一声要酒,服务员听见之后就去给他倒酒,而在这些醉汉没有要求的时候服务员可以玩玩手机干点别的。但是select和poll技术是这样的场景:服务员轮流着问各个醉汉要不要倒酒,没有空闲的时间。io多路复用的意思就是多个醉汉共用一个服务员。

  • 相关阅读:
    ZABBIX实现原理及架构详解
    for(;;)和while(true)的区别
    JVM
    javap的基本用法
    Java VisualVM添加Visual GC插件
    Java虚拟机监控命令
    数据类型 原始类型的方法
    数据类型 数字类型
    Object(对象):基础知识 原型对象prototype
    Object(对象):基础知识 对象方法,"this"
  • 原文地址:https://www.cnblogs.com/czs528/p/13519937.html
Copyright © 2011-2022 走看看