redis常见问答

共计 2773 个字符,预计需要花费 7 分钟才能阅读完成。

看到你用过redis,说说为啥用redis?

这是啥问题,大家不都是用redis的吗?但是心里再怎么暗骂,还是不能表现出来,建议这样回答。因为业务到了一定程度,传统型的关系型数据库已经不能满足所有场景了,面对高并发的秒杀,首页的访问流量高峰等,都是很容易一下子把你的DB打崩,所以引入redis这样的缓存中间件,保证系统能顶住压力。市面上还有Memcached这样的缓存系统,但是考虑到redis支持更丰富的数据结构(Memcached只支持保存字符串),支持持久化和简单的事务,所以选择了redis。

注:redis不仅仅是用来做缓存的,还可以做session共享,购物车,验证码等功能,具体看你的项目

那你知道redis有哪些数据结构吗

这个问题太简单,redis有5种数据结构,分别是字符串string,哈希hash,列表list,集合set,有序集合zset。重点是要去了解一下每种数据结构的使用场景,本文暂不讨论,可以参考redis五种数据结构的使用场景。还有一些额外加分项的回答,HyperLogLog,pub/sub,再说还玩过BloomFilter就更好了,如果不了解就别说了,不然给自己挖坑了反而不好。

如果需要设置大量的key同时过期,需要注意什么?

大量的key同时过期,在那个时间点会因为需要淘汰大量过期数据,占用CPU资源,可能会出现短暂的卡顿现象,严重的话会出现缓存雪崩,大量请求直接打到数据库,导致系统崩溃。一般的做法是给过期时间加上随机值,尽量使过期时间分散些。

那你使用过redis分布式锁吗?

先用setnx来争抢锁,再用expire给锁加上过期时间防止忘记释放。(其实使用这个办法加锁是有缺陷的,就看面试官会不会继续问了,就是下面的问题)

照你这么说,那如果setnx设置锁之后,执行expire之前进程奔溃了或者重启了,怎么办?

那确实这个锁就永远得不到释放了,就会产生一个死锁。解决办法,加入锁超时时间的判断,如果锁的超时时间大于当前的系统时间,说明锁的使用权失效,就可以做相应的处理了。或者直接使用set命令,可以同时设置锁和过期时间,相当于把setnx和expire命令放在一个事务里执行。

假如redis有一亿个key,其中有100w个key以固定开头,怎么把他们找出来?

可以使用keys命令全部扫出来,不过用keys写正则匹配危险很大,慎用!!!在业内,使用redis有一条铁律:禁止在生产环境使用keys命令写正则。原因很简单,redis是单线程的,使用keys指令的耗时操作会堵塞线程,服务会停滞,直到指令执行完毕,才会恢复。

还有一个办法,使用增量式命令scan,scan指令可以无堵塞的去除指定模式的key列表,但是有一定的重复概率,在客户端要做去重的处理,不过对键进行增量式迭代的过程中,键可能被更改,增量式的命令只能对被返回的元素提供有限额保证。

使用过Redis做异步队列吗?

一般使用list结构作为队列,rpush生产消息,lpop消费消息,lpop没有消息的话,要sleep一会再重试,或者直接使用blpop,在没有消息的时候,会堵塞线程直到消息到来。

那能不能生产一次消息,多次消费呢?

可以使用pub/sub发布订阅模式

pub/sub发布订阅模式有什么缺点吗?

在消费者下线了,就会丢失消息。可以使用更加专业的消息队列,如kafka,RocketMQ等

那你知道redis如何实现延时队列吗?

可以使用有序集合sorted set来实现,用时间戳做score,也就是对执行时间先后进行排序,取出消息如果当前时间 >= score就消费删掉,这样就达到延时的目的,不过建议还是用rabbitMQ来实现,rabbitMQ天然具备分布式的特性。专业的事用专业的工具。

Redis会怎么持久化的,服务主从数据如何交互?

redis使用RDB做全量持久化,AOF做增量持久化。RDB比较耗时,停机会丢失大量数据,所以要配合AOF来使用。在redis实例重启时,会使用RDB持久化文件重新构建内存,再使用AOF持久化文件重放近期的操作指令来完整恢复数据。

Redis本身的机制是 AOF持久化开启且存在AOF文件时,优先加载AOF文件;AOF关闭或者AOF文件不存在时,加载RDB文件;加载AOF/RDB文件城后,Redis启动成功; AOF/RDB文件存在错误时,Redis启动失败并打印错误信息

如果redis服务器断电会丢失数据吗?

这个取决于AOF日志sync属性的配置了,如果配置为1s,就丢失1s的数据

那你知道RDB实现的原理吗?

两个重点词,fork和cow(copy on write)

  1. 父进程fork出子进程,这个过程中,父进程是堵塞的,不会接受任何命令;
  2. 父进程fork后,bgsave命令会返回”Background saving started”信息并不再阻塞父进程,并可以响应其他命令;
  3. 子进程创建RDB文件,根据父进程内存快照生成临时文件,完成后对原有文件进行原子替换;
  4. 子进程发送信号给父进程表示完成,父进程更新统计信息

用过redis pipline吗?有什么好处?

redis的pipline在命令行是没有的,不过redis支持pipline功能,在每个语言的client里都有做实现。pipline可以对redis的多条指令进行批处理,队列的原理,先放入的先处理,可以提升性能,减少了TCP链接的次数,不需要每执行一条执行就建立一次链接。不过使用pipline 的前提是,这些指令没有因果相关性。使用redis-benchmark进行压测时,可以发现影响redis的QPS峰值的一个重要因素就是pipline批次指令的数目。

说说 Redis 同步机制

redis可以使用主从同步,从从同步。第一次同步时,主节点做一次bgsave,并同时将修改操作记录写到内存buffer,待完成后,将RDB文件全量同步到复制节点,复制节点接收后,将RDB文件加载到内存,加载完成后,再通知主节点将期间修改的操作日志同步过来,在复制节点完成重放就完成同步的过程。后续的增量数据通过AOF日志同步即可。

是否使用过redis集群,集群高可用如何保证?

redis sentinal用于高可用,在master宕机时,自动提升slave为master,继续提供服务。

redis cluster用于扩展性,在单个redis内存不足时,使用cluster进行分片存储。

参考整理自:https://github.com/AobingJava/JavaFamily/blob/master/docs/redis/Redis%E5%9F%BA%E7%A1%80.md

redis官方中文教程网站:https://www.redis.net.cn/tutorial/3501.html

正文完
 
Dustin
版权声明:本站原创文章,由 Dustin 2020-01-25发表,共计2773字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。