redis最全面试题

1、redis使用的是单线程为什么还这么快

  •  redis是基于内存操作的读写快
  • redis使用的io多路复用的内存模型
  • 单线程好处减少多线程之间切换带来的资源消耗 2 

2、redis的数据结构及其使用场景       

   string,hash,list,set,sortset                  

    string是以一种纯字符串作为value的形式存在的。也是这几种之中使用最多的数据结构。value可以存储json格式、数值型等。

string使用场景            

    string使用场景一般是存储简单的键值类型。比如用户信息,登录信息,配置信息等。还有一种用得比较多的是string的incr/decr操作,即自减/自增操作。调用它是原子性的,无论调用多少次,都一一计算成功。例如需要增减库存的操作。

尽管string的value可以存储很大,甚至500多MB的容量。但是在性能上来说,我们尽量存储value的值不要过1MB。

    hash是一个集合,使用过hash的人都知道,hash的读取性能都一样快。在redis中,hash因为是一个集合,所以有两层。第一层是key:hash集合value,第二层是hashkey:string value。所以判断是否采用hash的时候可以参照有两层key的设计来做参考。并且注意的是,设置过期时间只能在第一层的key上面设置。

hash使用场景                         

    使用hash,一般是有那种需要两层key的应用场景,也可以是‘删除一个key可以删除所有内容’的场景。例如一个商品有很多规格,规格里面有不同的值。

   如果需要删除商品时,可以一次性删除‘商品id’的key,则商品里面的所有规格也会删除,而不需要找到对应的规格再做处理。如果查找商品id与规格id1的商品时,则通过两个key查找即可。或者查找所有商品的规格,查找商品id即可。

    需要注意的是,经过测试,在性能上来说一般hash里面的第二层key,不要超过200个为佳。尽管hash里面的key-value能达到500多MB的存储容量。

 

  list是一个集合,而在redis中,list的使用场景多种多样。在redis中,插入list中的值,只需要找到list的key即可,而不需要像hash一样插入两层的key。list是一种有序的、可重复的集合。

list使用场景                       

    list可以使用左推、左拉、右推、右拉的方式。所以你可以使用list作为集合存储,比如存储某宝商铺里面的所有商品。

    也可以用作轻量级别的队列来使用。左推左拉、右推右拉。

   需要注意的是尽管redis可以使用推拉的队列模式,但是一定要注意场景。因为redis的队列是一种轻量级别的,没有队列重试、队列重放机制。消费完队列消息在redis代表已经删除了。

消息队列之发布订阅模式           

    redis除了list的推拉队列模式之外,还有一种是发布订阅的模式。发布订阅模式有是publish/subscribe的命令。与推拉队列模式不同之处在于,订阅者可以订阅多个频道,发布者可以向指定的频道或者所有频道发送消息。

    之所以在上面的list中结束这种队列模式,主要为了对比这两种的区别。

3、redis持久化方式

   1、redis提供两种方式进行持久化,一种是RDB持久化(原理是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化)

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

        ①、redis在进行数据持久化的过程中,会先将数据写入到一个临时文件中,待持久化过程都结束了,才会用这个临时文件替换上次持久化好的文件。正是这种特性,让我们可以随时来进行备份,因为快照文件总是完整可用的。
        ②、对于RDB方式,redis会单独创建(fork)一个子进程来进行持久化,而主进程是不会进行任何IO操作的,这样就确保了redis极高的性能。
        ③、如果需要进行大规模数据的恢复,且对于数据恢复的完整性不是非常敏感,那RDB方式要比AOF方式更加的高效。

   2、另外一种是AOF(append only file)持久化(原理是将Reids的操作日志以追加的方式写入文件)。

       ①、AOF命令以redis协议追加保存每次写的操作到文件末尾.Redis还能对AOF文件进行后台重写,使得AOF文件的体积不至于过大.默认的AOF持久化策略是每秒钟fsync一次(fsync是指把缓存中的写指令记录到磁盘中),因为在这种情况下,redis仍然可以保持很好的处理性能,即使redis故障,也只会丢失最近1秒钟的数据。
如果在追加日志时,恰好遇到磁盘空间满、inode满或断电等情况导致日志写入不完整,也没有关系,redis提供了redis-check-aof工具,可以用来进行日志修复。
   ②、因为采用了追加方式,如果不做任何处理的话,AOF文件会变得越来越大,为此,redis提供了AOF文件重写(rewrite)机制,即当AOF文件的大小超过所设定的阈值时,redis就会启动AOF文件的内容压缩,只保留可以恢复数据的最小指令集。举个例子或许更形象,假如我们调用了100次INCR指令,在AOF文件中就要存储100条指令,但这明显是很低效的,完全可以把这100条指令合并成一条SET指令,这就是重写机制的原理。
    ③、在进行AOF重写时,仍然是采用先写临时文件,全部完成后再替换的流程,所以断电、磁盘满等问题都不会影响AOF文件的可用性。

preview

4、过期键删除策略

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

5、内存淘汰机制

最大内存的设置是通过设置maxmemory来完成的,格式为maxmemory bytes ,当目前使用的内存超过了设置的最大内存,就要进行内存释放了, 当需要进行内存释放的时候,需要用某种策略对保存的的对象进行删除。Redis有六种策略(默认的策略是volatile-lru)。

redis中当内存超过限制时,按照配置的策略,淘汰掉相应的key-value,使得内存可以继续留有足够的空间保存新的数据。redis 确定驱逐某个键值对后,会删除这个数据并,并将这个数据变更消息发布到本地(AOF 持久化)和从机(主从连接)。

  1. volatile-lru:使用LRU算法进行数据淘汰(淘汰上次使用时间最早的,且使用次数最少的key),只淘汰设定了有效期的key ;
  2. allkeys-lru:使用LRU算法进行数据淘汰,所有的key都可以被淘汰;
  3. volatile-random:随机淘汰数据,只淘汰设定了有效期的key;
  4. allkeys-random:随机淘汰数据,所有的key都可以被淘汰;
  5. volatile-ttl:淘汰剩余有效期最短的key;
  6. no-enviction:不删除任意数据(但redis还会根据引用计数器进行释放),这时如果内存不够时,会直接返回错误 

一、LRU数据淘汰机制

在服务器配置中保存了 lru 计数器 server.lrulock,会定时(redis 定时程序 serverCorn())更新,server.lrulock 的值是根据 server.unixtime 计算出来的。

另外,从 struct redisObject 中可以发现,每一个 redis 对象都会设置相应的 lru。可以想象的是,每一次访问数据的时候,会更新 redisObject.lru。

LRU 数据淘汰机制是这样的:

在数据集中随机挑选几个键值对,取出其中 lru 最小的键值对淘汰。所以,你会发现,redis并不是保证取得所有数据集中最近最少使用(LRU)的键值对,而只是随机挑选的几个键值对中的。

二、TTL数据淘汰机制

redis 数据集数据结构中保存了键值对过期时间的表,即 redisDb.expires。和 LRU 数据淘汰机制类似。

TTL 数据淘汰机制是这样的:

从过期时间的表中随机挑选几个键值对,取出其中 ttl 最大的键值对淘汰。同样你会发现,redis并不是保证取得所有过期时间的表中最快过期的键值对,而只是随机挑选的几个键值对中的。

过期键删除策略和内存淘汰机制之间的关系:

  • 过期健删除策略强调的是对过期健的操作,如果有健过期了,而内存还足够,不会使用内存淘汰机制,这时也会使用过期健删除策略删除过期健。
  • 内存淘汰机制强调的是对内存的操作,如果内存不够了,即使有的健没有过期,也要删除一部分,同时也针对没有设置过期时间的健。
1、什么是 Redis? 2、Redis 相比 memcached 有哪些优势? 3、Redis 支持哪几种数据类型? 4、Redis 主要消耗什么物理资源? 5、Redis 的全称是什么? 6、Redis 有哪几种数据淘汰策略? 7、Redis 官方为什么不提供 Windows 版本? 8、一个字符串类型的值能存储大容量是多少? 9、为什么 Redis 需要把所有数据放到内存中? 10、Redis 集群方案应该怎么做?都有哪些方案? 11、Redis 集群方案什么情况下会导致整个集群不可用? 12、MySQL 里有 2000w 数据,Redis 中只存 20w 的数据, 如何保证 Redis 中的数据都是热点数据? 13、Redis 有哪些适合的场景? 14、Redis 支持的 Java 客户端都有哪些?官方推荐用哪个? 15、Redis Redisson 有什么关系? 16、Jedis 与 Redisson 对比有什么优缺点? 17、Redis 如何设置密码及验证密码? 18、说说 Redis 哈希槽的概念? 19、Redis 集群的主从复制模型是怎样的? 20、Redis 集群会有写操作丢失吗?为什么? 21、Redis 集群之间是如何复制的? 22、Redis 集群大节点个数是多少? 23、Redis 集群如何选择数据库? 24、怎么测试 Redis 的连通性? 25、Redis 中的管道有什么用? 26、怎么理解 Redis 事务? 27、Redis 事务相关的命令有哪几个? 28、Redis key 的过期时间永久有效分别怎么设置? 29、Redis 如何做内存优化? 30、Redis 回收进程如何工作的? 31、Redis 回收使用的是什么算法? 32、Redis 如何做大量数据插入? 33、为什么要做 Redis 分区? 34、你知道有哪些 Redis 分区实现方案? 35、Redis 分区有什么缺点? 36、Redis 持久化数据缓存怎么做扩容? 37、分布式 Redis 是前期做还是后期规模上来了再做好?为 什么? 38、Twemproxy 是什么? 39、支持一致性哈希的客户端有哪些? 40、Redis 与其他 key-value 存储有什么不同? 41、Redis 的内存占用情况怎么样? 42、都有哪些办法可以降低 Redis 的内存使用情况呢? 43、查看 Redis 使用情况及状态信息用什么命令? 44、Redis 的内存用完了会发生什么? 45、Redis 是单线程的,如何提高多核 CPU 的利用率? 46、一个 Redis 实例多能存放多少的 keys?List、Set、 Sorted Set 他们多能存放多少元素? 47、Redis 常见性能问题解决方案? 48、Redis 提供了哪几种持久化方式? 49、如何选择合适的持久化方式? 50、修改配置不重启 Redis 会实时生效吗?
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值