redis面试题分析

1、什么是redis?

1、redis是一个完全开源免费的,遵循BSD协议,高性能的key-value缓存数据库

2、redis的优势?

1、高性能:redis读写速度非常快,写速度是81000次/s,读速度是110000次/s
2、丰富的数据类型:redis支持String、list、hash、set、zset等数据类型
3、支持数据持久化:redis是运行在内存中异步复制到磁盘中的,下次重启redis的时候可以重新加载继续使用
4、原子性:redis的所有基本操作都是原子性的,而且支持事务
5、丰富的特性:消息的订阅通知、key过期等策略

3、redis与其它key-value存储有什么不同?

1、高性能:redis读写速度非常快,写速度是81000次/s,读速度是110000次/s
2、丰富的数据类型:redis支持String、list、hash、set、zset等数据类型
3、支持数据持久化:redis是运行在内存中异步复制到磁盘中的,下次重启redis的时候可以重新加载继续使用
4、原子性:redis的所有基本操作都是原子性的,而且支持事务
5、丰富的特性:消息的订阅通知、key过期等策略

4、redis的数据类型?

1、string、list、hash、set、zset(基本)
2、pub/sub(中级)
3、redisSerach(高级)

5、使用redis有哪些好处?

1、高性能:redis读写速度非常快,写速度是81000次/s,读速度是110000次/s
2、丰富的数据类型:redis支持String、list、hash、set、zset等数据类型
3、支持数据持久化:redis是运行在内存中异步复制到磁盘中的,下次重启redis的时候可以重新加载继续使用
4、原子性:redis的所有基本操作都是原子性的,而且支持事务
5、丰富的特性:消息的订阅通知、key过期等策略

6、redis与Memcached有哪些优势?

1、Memcache所有的值都是字符串,redis还支持其它复杂的数据类型
2、Redis的读写速度比Memcache快很多
3、Redis支持数据的持久化,Memcache只能运行在内存中

7、Memcached与redis比有哪些区别?

1、Memcache所有的值都是字符串,redis还支持其它复杂的数据类型
2、Redis的读写速度比Memcache快很多
3、Redis支持数据的持久化,Memcache只能运行在内存中
4、底层实现不同,redis有自己的VM机制,大多数系统调用系统函数都需要浪费一定的时间去移动和请求

8、redis是单进程还是单线程的?

1、redis是单进程单线程的,利用队列技术将并发访问变为串行控制,这样一来就消除了传统数据库维护串行控制所消耗的性能开销

9、一个字符串类型的值能存储最大容量是多少?

1、512M

10、redis的持久化机制是什么?各自的优缺点?

1、rdb(Redis DataBase):记录数据库中所有的key-value,每隔一定的时间备份一次,持久化之后会产生一个dump.rdb的临时文件,会用这个临时文件替代上次的持久化文件
	优点:1、只产生一个dump.rdb文件,数据恢复容易
		 2、容灾性好,可以将这个持久化文件备份到一个安全稳定的环境中
		 3、性能最大化,因为采用rdb持久化方式会fork一个子进行,本身主进程并不进行I/O操作
	缺点:1、数据安全度低:因为是每隔一段时间备份一次,中间可能会造成数据丢失

2、aof(append-only file):以命令行的格式持久化到一个aof的文件中
	优点:1、数据安全度高,因为采用aof持久化方式可以设置appendsync属性,并将其设置为always,这样一来,每次的客户端的命令都会被持久化
		 2、即使在持久化的时候服务器宕机了,也可以使用redis-check-aof解决数据的一致性问题
		 3、aof还有一个rewrite机制,在rewrite之前可以取消某些命令(例如:flushall)
	缺点:1、aof文件比rdb文件大,数据恢复慢
		 2、当数据集比较大时,aof比rdb启动效率低

11、redis常见的性能问题以及解决方案?

1、Master节点尽量不要做持久化操作(例如内存快照),持久化操作save会调用bgsava,此时就会导致主线程阻塞,造成redis会暂停服务
2、如果数据很重要,需要在slave节点开启aof持久化机制,因为rdb持久化数据有可能会丢失
3、为了主从复制的速度以及连接的稳定性,尽量将master和slave放到一个局域网内
4、尽量不要在压力很大的主库上增加从库
5、主从结构采用单行链表和不要采用图状结构,因为单链表占用内存小,操作方便,还能解决单点故障问题,即使master节点挂了,下一个slave节点就会变成master节点,其它不变

12、redis过期键的删除策略?

1、定时删除:在为key设置过期时间的同时为key设置个定时器,当key即将过期的时候就触发定时器将key删除
2、惰性删除:放任key的过期时间不管,但是每次从键空间获取键时都会检查键是否过期,如果过期了就删除,如果没过期就返回
3、定期删除:每隔一段时间就去数据库里检查一遍,并删除里面的过期键,至于要删除多少过期键以及检查多少库则由算法决定

13、redis的回收策略(淘汰策略)?

1、volatile-lru:在设置过期的时间里删除最近最少使用的数据
2、volatile-random:在设置过期的时间里随机选择数据删除
3、volatile-ttl:在设置过期的时间里删除即将过期的数据
4、allkeys-lru:在所有的数据里选择最近最少使用的数据删除
5、allkeys-random:在所有的数据里随机选择数据删除
6、no-envictin:永不淘汰

14、为什么要把redis需要的所有数据放到内存中?

1、redis是运行在内存中异步持久化到磁盘中,所以redis就有了高性能以及持久化的特性,因为把需要的数据放到内存中可以减少从磁盘的I/O操作,并且在内存越来越便宜的今天,redis肯定越来越受欢迎,但是达到内存的上限时写操作就会异常但是读操作仍然会正常返回

15、redis的同步机制了解吗?

1、redis有主从同步,从从同步。在第一次同步时,主节点会调用bgsave,以后的修改操作都会被记录到内存的buffer中,完成之后rdb文件会同步到复制节点,同步完成后会将rdb镜像加载到内存中,加载完成后通知主节点将期间的修改操作同步到复制节点,这样就完成了同步过程

16、Pipeline有什么好处,为什么要用pipeline?

1、Pipeline可以将多次的I/O操作简化为一次,但是前提时这些Pipeline指令之间没有因果关系

17、是否使用过redis集群?集群的原理是什么?

1、redis-sentinal高可用集群,当主节点挂了的时候,从节点可以替为主节点继续提供服务
2、redis-cluster可扩展集群,当主节点内存不够时,可以使用cluster节点进行分片存储

18、redis集群方案什么情况下会导致整个集群不可用?

1、假如有A、B、C三个节点的集群,中间B节点挂了,整个集群就以为缺少了从5501到11000之间的哈希槽而不可用

19、redis支持的java客户端都有哪些?官方推荐用哪个?

1、redission、jedis、lettuce
2、官方推荐使用redission

20、jedis与Redission对比有什么优缺点?

1、jedis提供更为全面的javaApi
2、redission提供了分布式可扩展的java数据结构,和jedis相比功能较为简单,不支持事务、
分片、通知等功能,但是redission的最终目的是让使用者的关注度分离,把主要精力放在业务逻辑上

21、redis如何设置密码及验证密码?

1、config set requriepass 123456
2、auth 123456

22、说说redis哈希槽的概念?

1、redis并没用使用数据的强一致性保证数据不丢失,而是引入了哈希槽的概念,redis一共有16384个哈希槽,每个key都先经过CRC-16校验之后对16384取模来决定放入哪个槽,redis集群中每个节点都负责一部分哈希槽

23、redis集群的主从复制模型是怎样的?

1、redis集群为了使部分节点挂了或者大部分节点都不能通信集群仍然能够正常工作,所以集群就采用了主从复制模型,即每个节点都有n-1个复制节点

24、redis集群会有写操作丢失吗?为什么?

1、会丢失
2、因为redis没有使用强一致性,所以在数据rdb持久化的时候,每隔一定时间备份一次,中间可能会有写操作丢失

25、redis集群之间是如何复制的?

1、异步复制

26、redis集群最大节点个数是多少?

1、16384个

27、redis集群如何选择数据库?

1、redis集群目前无法做到数据库的选择,默认是在0号库

28、怎么测试redis的连通性?

1、使用ping命令

29、怎么理解redis的事务?

1、redis的事务具有隔离性,就是在一个事务里命令执行的时候不会被其他客户端发送类命令所打断
2、redis的事务具有原子性,就是一个事务里的命令要么全部执行,要么全部不执行

30、redis事务相关的命令有哪几个?

1、multi、exec、watch、discard

31、redis key的过期时间和拥有有效分别怎么设置?

1、设置过期时间用expire指令
2、设置永不过期用persist指令

32、redis如何做内存优化?

1、尽可能的使用散列表,因为散列占用的内存非常少,所以应该尽可能的将数据都存放到散列表里;例如你有一个user对象,该对象有姓名、性别、邮箱、爱好等属性,你不必为每一个属性都设置一个key,而是应该考虑将这些属性都存到一个散列表里

33、redis回收进程如何工作的?

1、redis是运行在内存中并异步持久化到磁盘中,客户端每执行一条命令都会插入一条数据,主线程每次都会检查内存是否占用满时,当内存占用满时,主线程就会通知回收线程按照预先规定好的回收策略回收

34、都有哪些办法可以降低redis的内存使用状况?

1、当你使用的是32位redis实例时,应该多考虑使用list、hsah、set等数据结构,因为通常情况下很小的key-value都可以使用更紧凑的方式来存储

35、redis的内存用完了会发生什么?

1、写操作会报错,读操作能正常返回

36、一个redis实例最多能存放多少的keys?List、Set、Sorted Set他们最多可以存放多少元素?

1、一个redis实例最多能存放2^32个keys
2、List、Set、Sorted Set都可以存放2^32个元素
3、换句话说,redis能存放多少元素的瓶颈在于系统的可用内存

37、Mysql里有2000w数据,redis只存20w的数据,如何保证redis中的数据都是热点数据?

1、redis有自己的淘汰策略,可以在redis里设置当存放的数据达到一定数据时采用allkeys-lru(在所有的数据里选择最近最少使用的数据淘汰)

38、redis最合适的应用场景?

1、会话缓存:redis存放数据更加安全,因为redis可以做到数据的持久化,可以将用户的个人会话缓存到磁盘中而不必担心数据丢失问题
2、页面缓存:可以用redis将某些静态页面缓存起来,下次在读的时候直接从缓存中取
3、队列:redis提供了大量的list和set操作(pop/push),这使得redis可以作为一个消息队列来使用
4、排行榜/计数器:redis在自增和自减方面也有相关的指令,所以redis可以很轻松的用set/sorted set等有序集合获取排名靠前的多少位
4、消息订阅:redis自带pub/sub数据结构

39、假如redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将他们全部找出来?如果这个redis正在给线上的业务提供服务,使用keys指令会有什么影响?

1、使用keys指令可以找出所有指定模式的key
2、因为redis是单进程单线程的,使用keys指令会导致线程阻塞一段时间,这样redis就会暂停提供服务直到keys指令执行完成,这时候应该考虑使用scan指令,scan指令也可以扫描出顶顶模式的keys,但是scan模式就一个缺陷就是扫描出来的数据有可能重复,这时候需要在客户端去重操作,导致了scan指令比keys指令执行的时间要长些,所以应该根据具体场合来考虑使用那种模式

40、如果有大量的key需要设置同一过期时间,一般需要注意什么?

1、大量的key设置的过期时间过于集中的化,有可能导致redis会间断性的暂停服务
2、一般我们都在过期时间后面加上一个随机值,就是为了让过期时间均匀分布

41、使用redis做过异步队列吗?你是怎么用的?无消息消费时可不可以不用sleep呢?可不可以生产一次消费多次呢?pub/sub有什么缺点?redis如何做延迟队列?

1、做过
2、用list作队列,rpush生产消息,lpop消费消息,当没有消息消费时,要sleep一会再重试
3、用blpop,在没有消息消费的时候也可以不用sleep
4、可以使用pub/sub模式做到1:n的消息队列做到只生产一次而消费多次
5、pub/sub有一个问题就是当消费者下线时,生产者生产出来的消息会丢失,此时就要考虑使用专门的消息中间件了(例如:rabbitMq,rocketMq)
6、使用sorted set,用时间戳作为score,消息内容作为key调用zadd来生产消息,而消费者只需要通过zrangebyscore来获取N秒之前的数据轮询处理

42、使用redis做过分布式锁吗?它是怎么回事?如果在setnx之后,expire之前那个进程挂了或者意外的重启会产生什么后果,怎么解决?

1、做过
2、先使用setnx指令获取锁,然后使用expire指令为锁加上一个过期时间来防止锁忘记删除而长时间占有
3、setnx之后,expire之前进程挂了就会导致锁无法释放产生死锁现象
4、在redis2.1.6版本之后就有了set指令可以将setnx和expire指令合为一个原子指令了(set key value setnx expire)

43、为什么redis是单线程的?但是性能非常高,而且还能处理高并发的问题?

1、redis单线程说的是在网络模块使用的是一个线程处理所有的网络请求,在其它模块使用的还是多线程;而且官方也说影响redis的性能不是CPU而是硬件的可用内存以及网络的延迟,所以redis就使用简单易操作的单线程了
2、redis使用单线程没有繁杂的加锁解锁过程,所以性能高
3、redis使用单线程没有线程之间的切换操作,所以性能高
4、redis是基于内存运行的,所以性能高
5、redis使用多路复用的非阻塞I/O(epoll)来处理并发问题
原文地址:https://www.cnblogs.com/liulong99/p/13060806.html