Redis专题面试题

谈谈你对Redis的理解?

Redis(Remote Dictionary Server,远程字典服务)是一个开源的底层使用C语言编写的key-value存储数据库

为什么要用?优缺点?

1)性能极高 – Redis能读的速度是110000次/s,写的速度是81000次/s 。

2)丰富的数据类型 – Redis支持二进制案例的 Strings, Lists, Hashes, Sets 及 Ordered Sets 数据类型操作。

3)原子性 – Redis的所有操作都是原子性的,意思就是要么成功执行要么失败完全不执行。单个操作是原子性的。多个操作也支持事务,即原子性,通过MULTI和EXEC指令包起来。

4)丰富的特性 – Redis还支持发布订阅(publish/subscribe), 通知, key 过期等等特性。

Redis的主要缺点是数据库容量受到物理内存的限制,不能用作海量数据的高性能读写,因此Redis适合的场景主要局限在较小数据量的高性能操作和运算上。

什么时候要用?使用场景?

1) 缓存(数据查询,新闻内容,商品内容,短连接等等)

2) 任务队列(秒杀,抢购,12306等等),在某个时刻访问量极大而且更新也很频繁的数据。在秒杀那一刻,可能有N倍于平时的流量进来,系统压力会很大。但是这种数据使用的缓存不能和普通缓存一样,这种缓存必须保证不丢失,否则会有大问题。

3) 数据过期处理(可以精确到毫秒)

4) 不需要实时更新但是又极其消耗数据库的数据。比如网站上商品销售排行榜,这种数据一天统计一次就可以了,用户不会关注其是否是实时的。

扫描二维码关注公众号,回复: 9248377 查看本文章

5) 网站访问统计

6) 发布/订阅

7) 分布式集群架构中的session分离

8)需要实时更新,但是更新频率不高的数据。比如一个用户的订单列表,他肯定希望能够实时看到自己下的订单,但是大部分用户不会频繁下单。

项目中使用redis一般作为缓存来使用,缓存的目的就是为了减轻数据库压力,提高存取的效率。

 Redis有哪些数据结构?

string(字符串)、hash(哈希)、list(列表)、set(无序集合)、zset(sorted set:有序集合)

如果你是Redis中高级用户,还需要加上下面几种数据结构HyperLogLog、Geo、Pub/Sub。如果你说还玩过Redis Module,像BloomFilter,RedisSearch,Redis-ML,面试官得眼睛就开始发亮了。

redis 事务?常见命令?

单个 Redis 命令的执行是原子性的,但 Redis 没有在事务上增加任何维持原子性的机制,所以 Redis 事务的执行并不是原子性的。

事务可以理解为一个打包的批量执行脚本,但批量指令并非原子化的操作,中间某条指令的失败不会导致前面已做指令的回滚,也不会造成后续的指令不做。

菜鸟教程Redis事务 ——

https://www.runoob.com/redis/redis-transactions.html

Redis是单线程程序,速度为什么会这么快?

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

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

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

4、使用异步非阻塞IO(重点说)

介绍:

同步/异步:是否主动读取数据;

阻塞/非阻塞:是否需要等待;

同步:执行一个操作后,等待结果,然后才继续执行后续的操作;

异步:执行一个操作后,可以去执行其他的操作,然后等待通知再回来执行刚才没执行完的操作;

阻塞:进程给CPU传达一个任务之后,一直等待CPU处理完成,然后才执行后面的操作。

非阻塞:进程给CPU传达任务后,继续处理后续的操作,隔段时间再来询问之前的操作是否完成。这样的过程其实也叫轮询。

5Redis直接自己构建了VM 机制 ,因为一般的系统调用系统函数的话,会浪费一定的时间去移动和请求;

Redis是nosql数据库,是否适合存储大数据?

Redis是nosql数据库,但是redis是key-value形式的nosql数据库,数据是存储到内存中的,适用于快速存取,一般作为缓存使用,所以不适合于大数据的存储。并且redis是单线程的,如果某个操作进行大数据的存储的话,其他的进程都处于等待状态,这样就降低了性能,所以redis不适合于大数据的存储。如果是类似商品评价这样的,价值不高的大批量数据,我们的做法是采用mongodb。

Redis的持久化是什么?

持久化简单来说就是把程序数据长久保存

Redis 中存在两种方式的备份:一种是快照恢复(RDB,通过快照(snapshotting)实现的,它是备份Redis在某个时间点上的数据集

另一种是只追加文件(Append-Only FileAOF,其作用就是 Redis 执行写命令后,在一定的条件下将执行过的写命令依次保存在 Redis 的文件中,将来就可以依次执行那些保存的命令恢复 Redis 的数据Redis还可以在后台对AOF文件进行重写(rewrite),使得AOF文件的体积不会超出保存数据集状态所需的实际大小。

AOFRDB的同时应用:Redis重启时,它会优先使用AOF文件来还原数据集,因为AOF文件保存的数据集通常比RDB文件所保存的数据集更完整。

RDB的优缺点?

优点RDB是一个非常紧凑(compact)的文件,它保存了Redis在某个时间点上的数据集。这种文件非常适合用于进行备份:比如说,你可以在最近的24小时内,每小时备份一次RDB文件,并且在每个月的每一天,也备份一个RDB文件。这样的话,即使遇上问题,也可以随时将数据集还原到不同的版本。RDB非常适用于灾难恢复disaster recovery):它只有一个文件,并且内容都非常紧凑,可以(在加密后)将它传送到别的数据中心,或者亚马逊S3中。RDB可以最大化Redis的性能:父进程在保存RDB文件时唯一要做的就是fork出一个子进程,然后这个子进程就会处理接下来的所有保存工作,父进程无须执行任何磁盘I/O操作。RDB在恢复大数据集时的速度比AOF的恢复速度要快

缺点:如果你需要尽量避免在服务器故障时丢失数据,那么RDB不适合你。虽然Redis允许你设置不同的保存点(save point)来控制保存RDB文件的频率,但是,因为RDB文件需要保存整个数据集的状态,所以它并不是一个轻松的操作。因此你可能会至少5分钟才保存一次RDB文件。在这种情况下,一旦发生故障停机,你就可能会丢失好几分钟的数据。每次保存RDB的时候,Redis都要fork()出一个子进程,并由子进程来进行实际的持久化工作。在数据集比较庞大时,fork()可能会非常耗时,造成服务器在某某毫秒内停止处理客户端;如果数据集非常巨大,并且CPU时间非常紧张的话,那么这种停止时间甚至可能会长达整整一秒。

AOF的优缺点?

优点:使用AOF持久化会让Redis变得非常耐久much more durable):可以设置不同的fsync策略,比如无fsync,每秒钟一次fsync,或者每次执行写入命令时fsync。AOF的默认策略为每秒钟fsync一次,在这种配置下,Redis仍然可以保持良好的性能,并且就算发生故障停机,也最多只会丢失一秒钟的数据fsync会在后台线程执行,所以主线程可以继续努力地处理命令请求)。AOF文件是一个只进行追加操作的日志文件append onlylog),因此对AOF文件的写入不需要进行seek,即使日志因为某些原因而包含了未写入完整的命令(比如写入时磁盘已满,写入中途停机,等等),redis-check-aof工具也可以 轻易地修复这种问题。

Redis可以在AOF文件体积变得过大时,自动地在后台对AOF进行重写:重写后的新AOF文件包含了恢复当前数据集所需的最小命令集合。整个重写操作是绝对安全的,因为Redis在创建新AOF文件的过程中,会继续将命令追加到现有的AOF文件里面,即使重写过程中发生停机,现有的AOF文件也不会丢失。而一旦新AOF文件创建完毕,Redis就会从旧AOF文件切换到新AOF文件,并开始对新AOF文件进行追加操作。

缺点:对于相同的数据集来说,AOF文件的体积通常要大于RDB文件的体积根据所使用的fsync策略,AOF的速度可能会慢于RDB。在一般情况下,每秒fsync的性能依然非常高,而关闭fsync可以让AOF的速度和RDB一样快,即使在高负荷之下也是如此。不过在处理巨大的写入载入时,RDB可以提供更有保证的最大延迟时间(latency)。

Redis 4.0 对于持久化机制的优化

Redis 4.0 开始支持 RDB AOF 的混合持久化(默认关闭,可以通过配置项 aof-use-rdb-preamble 开启)。如果把混合持久化打开,AOF 重写的时候就直接把 RDB 的内容写到 AOF 文件开头。这样做的好处是可以结合 RDB AOF 的优点, 快速加载同时避免丢失过多的数据。当然缺点也是有的, AOF 里面的 RDB 部分是压缩格式不再是 AOF 格式,可读性较差。

使用过Redis分布式锁么,它是什么回事?

先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。

这时候对方会告诉你说你回答得不错,然后接着问如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?

这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。紧接着你需要抓一抓自己得脑袋,故作思考片刻,好像接下来的结果是你主动思考出来的,然后回答:我记得set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!对方这时会显露笑容,心里开始默念:嗯,这小子还不错。

 项目实战:调货生成申请单的时候得用到锁,不能重复点击生成申请单

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

512M

redis memcached 的区别

1)redis支持更丰富的数据类型(支持更复杂的应用场景):Redis不仅仅支持简单的k/v类型的数据,同时还提供list,set,zset,hash等数据结构的存储。memcache支持简单的数据类型,String。

2)Redis支持数据的持久化,可以将内存中的数据保持在磁盘中,重启的时候可以再次加载进行使用,而Memecache把数据全部存在内存之中。

3)集群模式:memcached没有原生的集群模式,需要依靠客户端来实现往集群中分片写入数据;但是 redis 目前是原生支持 cluster 模式的.

4)Memcached是多线程,非阻塞IO复用的网络模型;Redis使用单线程的多路 IO 复用模型。

 

Redis支持的Java客户端都有哪些?官方推荐用哪个?

Redisson、Jedis、lettuce等等,官方推荐使用Redisson。

Redis和Redisson有什么关系?

Redisson是一个高级的分布式协调Redis客服端,能帮助用户在分布式环境中轻松实现一些Java的对象 (Bloom filter, BitSet, Set, SetMultimap, ScoredSortedSet, SortedSet, Map, ConcurrentMap, List, ListMultimap, Queue, BlockingQueue, Deque, BlockingDeque, Semaphore, Lock, ReadWriteLock, AtomicLong, CountDownLatch, Publish / Subscribe, HyperLogLog)。

Jedis与Redisson对比有什么优缺点?

Jedis是Redis的Java实现的客户端,其API提供了比较全面的Redis命令的支持;

Redisson实现了分布式和可扩展的Java数据结构,和Jedis相比,功能较为简单,不支持字符串操作,不支持排序、事务、管道、分区等Redis特性。Redisson的宗旨是促进使用者对Redis的关注分离,从而让使用者能够将精力更集中地放在处理业务逻辑上。

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

设置密码:config set requirepass 123456

授权密码:auth 123456

为什么要用 redis 而不用 map/guava 做缓存?

缓存分为本地缓存和分布式缓存。以 Java 为例,使用自带的 map 或者 guava 实现的是本地缓存,最主要的特点是轻量以及快速,生命周期随着 jvm 的销毁而结束,并且在多实例的情况下,每个实例都需要各自保存一份缓存,缓存不具有一致性。

使用 redis memcached 之类的称为分布式缓存,在多实例的情况下,各实例共用一份缓存数据,缓存具有一致性。缺点是需要保持 redis memcached服务的高可用,整个程序架构上较为复杂。

参考:

30道Redis面试题,面试官能问的都被我找到了--

https://www.jianshu.com/p/36a646cef11a

面试题 动力节点 --

http://www.bjpowernode.com/tutorial_baseinterviewquestions/225.html

Redis面试题总结 --

https://www.jianshu.com/p/65765dd10671

 

猜你喜欢

转载自www.cnblogs.com/liaowenhui/p/12329171.html