zoukankan      html  css  js  c++  java
  • Redis面试题汇总

    1. 什么是 Redis?

     Redis(Remote DIctionary Server)是完全开源免费的,使用ANSI C语言编写、遵守 BSD(伯克利软件发行版)协议,是一个高性能的 key-value 数据库, 并提供多种语言的API调用。

     Redis 与其他 key-value 缓存产品有以下三个特点:
      Redis 支持数据的持久化,可以将内存中的数据保存在磁盘中,重启的时候可以再次加载进行使用。
      Redis 不仅仅支持简单的 key-value 类型的数据,同时还提供 Sting,list,set,zset,hash 等数据结构的存储。
      Redis 支持数据的备份,即 master-slave 模式的数据备份。

     Redis 优势
      Redis的性能极高,Redis 能读的速度是 110000 次/s,写的速度是 81000 次/s 。丰富的数据类型 。
      Redis 的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过 MULTI 和 EXEC指令包起来。
      丰富的特性 – Redis 还支持 publish/subscribe, 通知, key 过期等等特性。
     
    2. Redis 与其他 key-value 存储有什么不同?
      Redis 有着更为复杂的数据结构并且提供对他们的原子性操作,这是一个不同于其他数据库的进化路径。Redis 的数据类型都是基于基本数据结构的同时对程序员透明,无需进行额外的抽象。Redis 运行在内存中但是可以持久化到磁盘,所以在对不同数据集进行高速读写时需要权衡内存,因为数据量不能大于硬件内存。在内存数据库方面的另一个优点是,相比在磁盘上相同的复杂的数据结构,在内存中操作起来非常简单,这样 Redis可以做很多内部复杂性很强的事情。同时,在磁盘格式方面他们是紧凑的以追加的方式产生的,因为他们并不需要进行随机访问。

    3. Redis 的数据类型有哪些?
       Redis 支持五种数据类型:string(字符串),hash(哈希),list(列表),set(集合)及 sorted set :有序集合)。
       我们实际项目中比较常用的是 string,hash 如果你是 Redis 中高级用户,还需要加上下面几种数据结构 HyperLogLog、Geo、Pub/Sub(发布/订阅),BloomFilter(布隆过滤器)。
         还有Redis Module(Redis4.0引入的,可以通过编写插件的模式,来动态扩展redis的能力, https://redis.io/topics/modules-intro), RedisSearch(是一款基于Redis的搜索引擎,主要支持一些富文本的的搜索),Redis-ML(机器学习)等其它生态工具。

    4. 使用 Redis 有哪些好处?
      1、速度快,因为数据存在内存中,类似于 HashMap,HashMap 的优势就是查找和操作的时间复杂度都是 O1)
      2、支持丰富数据类型,支持 string,list,set,Zset,hash 等
      3、支持事务,操作都是原子性,所谓的原子性就是对数据的更改要么全部执行,要么全部不执行
      4、丰富的特性:可用于缓存,消息,按 key 设置过期时间,过期后将会自动删除。


    5. Redis 相比 Memcached 有哪些优势?
      1、Memcached 所有的值均是简单的字符串,redis 作为其替代者,支持更为丰富的数据类型。
      2、Redis 的速度比 Memcached 快很。
      3、Redis 可以持久化其数据 。

    6. Redis 是单进程单线程的?
      Redis 是单进程单线程的(注意这里不是指Redis单实例中只有一个线程,而是表示核心操作模块由单线程完成,当然另外还有一些辅助线程从旁协助,比如LRU的淘汰过程,异步复制),Redis 利用队列技术将并发访问变为串行访问,消除了传统数据库串行控制的开销。现在最新版本的Redis6.0开始支持多线程了。

    7. Redis为什么这么快?

      1、完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1)。

      2、数据结构简单,对数据操作也简单,Redis中的数据结构是专门进行设计的;

      3、采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;

      4、使用多路I/O复用模型,非阻塞IO,这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。

      5、使用底层模型不同,它们之间底层实现方式以及与客户端之间通信的应用协议不一样,Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求。

    8. Redis中String类型的Value最大容量多少?

        512M

       

       来源于官网文档:https://redis.io/topics/data-types

    9. Redis持久化机制

      Redis是一个支持持久化的内存数据库,通过持久化机制把内存中的数据同步到硬盘文件来保证数据持久化。当Redis重启后通过把硬盘文件重新加载到内存,就能达到恢复数据的目的。

      Redis有两种持久化方式:
      
        1. RDB(Redis DataBase)是Redis默认的持久化方式。按照一定的时间周期策略把内存的数据以快照的形式保存到硬盘的二进制文件。即Snapshot快照存储,对应产生的数据文件为dump.rdb,通过配置文件中的save参数来定义快照的周期。( 快照可以是其所表示的数据的一个副本,也可以是数据的一个复制品。)

        实现过程:单独创建fork()一个子进程,将当前父进程的数据库数据复制到子进程的内存中,然后由子进程写入到临时文件中,持久化的过程结束了,再用这个临时文件替换上次的快照文件,然后子进程退出,内存释放。
        2. AOF(Append-only file):Redis会将每一个收到的写命令都通过Write函数追加到文件最后,类似于MySQL的binlog。当Redis重启是会通过重新执行文件中保存的写命令来在内存中重建整个数据库的内容。

        当上面两种方式同时开启时,数据恢复Redis会优先选择AOF恢复数据。

      Redis持久化机制RDB和AOF各自优缺点是什么?
      RDB优点:
        1、只有一个文件 dump.rdb,方便持久化。
        2、容灾性好,一个文件可以保存到安全的磁盘。
        3、性能最大化,fork 子进程来完成写操作,让主进程继续处理命令,所以是 IO最大化。使用单独子进程来进行持久化,主进程不会进行任何 IO 操作,保证了 redis的高性能。

        4.相对于数据集大时,比 AOF 的启动效率更高。
      RDB缺点:
        1、数据安全性低。RDB 是间隔一段时间进行持久化,如果持久化之间 redis 发生故障,会发生数据丢失。所以这种方式更适合数据要求不严谨的时候,同时也容易遭黑客攻击。
        
      AOF优点:

        1、数据安全,aof 持久化可以配置 appendfsync 属性,有 always,每秒进行一次命令操作就记录到 aof 文件中一次。
        2、通过 append 模式写文件,即使中途服务器宕机,可以通过 redis-check-aof工具解决数据一致性问题。
        3、AOF 机制的 rewrite 模式。AOF 文件没被 rewrite 之前(文件过大时会对命令进行合并重写),可以删除其中的某些命令(比如误操作的 flushall)。

      AOF缺点:
        1、AOF 文件比 RDB 文件大,且恢复速度慢。
        2、数据集大的时候,比 rdb 启动效率低。

    10. Redis过期键的删除策略

      1、定时删除: 在设置键的过期时间的同时,创建一个定时器 timer,让定时器在键的过期时间来临时,立即执行对键的删除操作。
      2、惰性删除: 放任键过期不管,但是每次从键空间中获取键时,都检查取得的键是否过期,如果过期的话,就删除该键,如果没有过期,就返回该键。
      3、定期删除:每隔一段时间程序就对数据库进行一次检查,删除里面的过期键。至于要删除多少过期键,以及要检查多少个数据库,则由算法决定。


      三种删除策略对比:

        1. 定时删除特点

         优点:对内存友好,通过定时器可以保证过期键过期键会尽可能快的删除,并释放过期键占用的空间。

         缺点:

          1)cpu不友好,在过期键比较多的情况下,删除过期键可能会占用相当一部分cpu时间, 在内存不紧张cpu紧张的情况下,将cpu时间用在删除和当前任务无关的过期键上,无疑会对服务器响应时间和吞吐量造成影响。

          2)创建定时器需要Redis服务器中的时间事件,而现在时间事件的实现方式是无序链表(UnorderedLIst),查找一个事件的时间复杂度为O(N),并不能高效的处理大量时间事件。

        2. 惰性删除特点

           优点:对cpu友好,程序只在取出键时才对建进行过期检查,删除的目标仅限于当前处理的键。

           缺点:对内存不友好,当数据库中有大量的过期键,而这些键又没有被访问到,那么他们也许会永远不会被删除。

        3 定期删除:是前两种删除策略的一种折中。会每隔一段时间执行一次删除过期键操作,并通过限制操作执行的时长和频率来减少删除操作对cpu时间的影响。

           难点:确定删除策略的时长和频率

          1)如果删除操作太过频繁,或者执行时间太长,定期删除策略就会退化成定时删除策略。

          2)如果删除执行得太少,或者执行时间太短,定期删除策略又会和惰性删除策略一样,出现浪费内存现象。

         在上述的三种策略中定时删除和定期删除属于不同时间粒度的 主动删除,惰性删除属于 被动删除

    11.  Reids6种淘汰策略:

      当现有内存大于 maxmemory 时,便会触发redis主动淘汰内存方式,通过设置 maxmemory-policy ,有如下几种淘汰方式:

        1. no-eviction: 不删除策略, 达到最大内存限制时, 如果需要更多内存, 直接返回错误信息。大多数写命令都会导致占用更多的内存。

        2. volatile-lru: 从已设置过期时间的 key 集中优先对最近最少使用(less recently used, LRU)的数据淘汰。

        3. volitile-ttl : 从已设置过期时间的 key 集中优先对剩余时间短(time to live,,TTL)的数据淘汰。

        4. volitile-random : 从已设置过期时间的 KV 集中随机选择数据淘汰。

        5. allkeys-lru : 从所有 key 集中优先对最近最少使用(less recently used)的数据淘汰。

        6. allKeys-random: 从所有 key 集中随机选择数据淘汰。

       设置Redis最大内存及设置淘汰策略
       在配置文件redis.conf 中,可以通过参数 maxmemory 来设定最大内存,下图

      

    12. Pipeline(管道) 有什么好处,为什么要用 pipeline?

      可以将多次 网络IO 往返的时间缩减为一次,前提是 pipeline 执行的指令之间没有因果相关性。使用 redis-benchmark 进行压测的时候可以发现影响 redis 的 QPS峰值的一个重要因素是 pipeline 批次指令的数目。

    13. 为什么 Redis 需要把所有数据放到内存中?

      Redis 为了达到最快的读写速度将数据都读到内存中,并通过异步的方式将数据写入磁盘。所以Redis 具有快速和数据持久化的特征。如果不将数据放在内存中,磁盘 I/O 速度为严重影响 Redis 的性能。在内存越来越便宜的今,Redis 将会越来越受欢迎。如果设置了最大使用的内存,则数据已有记录数达到内存限值后不能继续插入新值。

    14. Redis 如何设置密码及验证密码?

      1. 命令行设置密码方式

        查看密码:config get requirepass命令查看密码

        设置密码:config set requirepass 123456
        授权密码:auth 123456

      2. 配置文件设置密码方式
        在Redis根目录下找到redis.conf配置文件,搜索requirepass,找到注释密码行,添加密码如下:

    # requirepass foobared
    requirepass 123456     //注意,行前不能有空格

       然后重启Redis服务器(指定配置文件)。

    15. Redis集群模式是什么?

      单机版Redis的缺点:

       1. 一般学习的 Redis 都是单机版 的,这也就意味着一旦我们所依赖的 Redis 服务宕机了,我们的主流程也会受到一定的影响,这当然是我们不能够接受的。

       2. 单个redis存在不稳定性。当redis服务宕机了,就没有可用的服务了。

       3. 单个redis的读写能力是有限的。

      而Redis集群(Redis cluster)是提供一种方式自动将数据分布在多个Redis节点上,并且可以保障数据的高可用和安全性。

       1.  Redis Sentinal 着眼于高可用,在 master 宕机时会自动将 slave 提升为master,继续提供服务。
       2. Redis Cluster 着眼于扩展性,在单个 redis 内存不足时,使用 Cluster 进行分片存储。

    16. Redis 中的 DB

      Redis默认的db数量是16(编号0-15)个,redis.conf配置文件下的databases参数可以设置,默认情况下一个客户端连接到数据库0。 可以select 命令来选择用那一号 DB,每个 DB是相互独立存在的,所以每个DB中可以存在重复的Key。

      注意:

        flushdb命令清除数据,只会清除当前的数据库下的数据,不会影响到其他数据库。而flushall命令会清除这个实例的数据,在执行这个命令前要格外小心。

    18. Redis 哈希槽的概念

        Redis集群没有使用一致性hash,而是引入了哈希槽的概念,Redis 集群有16384 个哈希槽,每个 key 通过 CRC16 校验后对 16384 取模来决定放置哪个槽,集群的每个节点负责一部分 hash 槽。

    20. Redis连接池

      使用golang客户端。

      下载包

    go get github.com/gomodule/redigo/redis
  • 相关阅读:
    ajax翻页效果模仿yii框架
    一个伪ajax图片上传代码的例子
    php下intval()和(int)转换有哪些区别
    php中iconv函数使用方法
    php字符串截取问题
    ASP.net UrlRewrite的防盗链功能
    ASP.NET中application对象
    javascript回车完美实现tab切换功能
    有关c#装箱和拆箱知识整理
    PHP四大安全策略
  • 原文地址:https://www.cnblogs.com/songgj/p/13038116.html
Copyright © 2011-2022 走看看