- Q: redis的并发是怎么样的?
- Q: 详细讲讲redis怎么利用IO多路复用实现百万级并发的?
- Q:redis如何处理锁?
- Q: 讲一下redis的主从复制策略?
- Q: 讲一下Redis有哪些缓存淘汰策略、更新策略
- Q: 讲一下redis的七种集合类型?
- Q: Redis有哪些数据结构?
- Q: 使用过Redis分布式锁么,它是什么回事?
- Q: 假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?
- Q:对方接着追问:如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?
- Q: 使用过Redis做异步队列么,你是怎么用的?
- Q: 如果对方追问可不可以不用sleep呢?
- 如果对方追问能不能生产一次消费多次呢?
- Q: 对方追问pub/sub有什么缺点?
- Q: 如果对方追问redis如何实现延时队列?
- Q: 如果有大量的key需要设置同一时间过期,一般需要注意什么?
- Q:Redis如何做持久化的?
- Q:上面持久化的过程如果突然机器掉电会怎样?
- Q: 对方追问bgsave的原理是什么?
- Q: Pipeline有什么好处,为什么要用pipeline?
- Q: Redis的同步机制了解么?
- Q:是否使用过Redis集群,集群的原理是什么?
[toc]
Q: redis的并发是怎么样的?#
A:
https://www.cnblogs.com/wanlei/p/10464517.html
redis是单线程进程, 所有操作都在1个线程内执行, 因为大部分是内存k-v操作,所以不需要太多的CPU消耗,无需多线程。
但是支持IO多路复用。epoll。
Q: 详细讲讲redis怎么利用IO多路复用实现百万级并发的?#
A:
每个网络连接本质上都是文件, 涉及IO。
当客户端与redis服务建立连接, 输入到输出都需要时间, 此时如果连接很多,会不会影响其他的连接请求?
因此为了能快速响应redis请求,以及读取数据并返回, 使用了IO多路复用epoll来响应。 即我虽然和你建立了reids连接,但我等待你发数据了我才真正处理,而不是阻塞等待。
关于epoll的原理解析, 见高并发IO之epoll
Q:redis如何处理锁?#
A:
主要使用Redis Setnx 命令
在指定的 key 不存在时,为 key 设置指定的值
设置成功,返回 1 。 设置失败,返回 0
详情
Q: 讲一下redis的主从复制策略?#
A:
redis 主从复制链接
Redis主从同步策略
主从刚刚连接的时候,进行全量同步;
全同步结束后,进行增量同步。
当然,如果有需要,slave 在任何时候都可以发起全量同步。redis 策略是,无论如何,首先会尝试进行增量同步,如不成功,要求从机进行全量同步。
Q: 讲一下Redis有哪些缓存淘汰策略、更新策略#
A:
缓存有多种策略可以配置选择
经典的有LRU、默认策略、 最短超期等六种
过期: 惰性+定时
惰性:使用的时候都先检查一下是否超期
定时:定期扫描,随机查X个键,如果发现过期比例超过1/4,继续扫+清, 最大占25ms。 他这类似于分多次小批扫描
详情
Q: 讲一下redis的七种集合类型?#
A:
Redis中7种集合类型应用场景
-
Strings——简单的key-value
Strings 数据结构是简单的key-value类型,value其实不仅是String,也可以是数字。使用Strings类型,你可以完全实现目前 Memcached 的功能,并且效率更高。还可以享受Redis的定时持久化,操作日志及 Replication等功能。可提供与 Memcached 一样的get、set、incr、decr 等操作
-
Hashs——用于结构体或者对象
在Memcached中,我们经常将一些结构化的信息打包成hashmap,在客户端序列化后存储为一个字符串的值,比如用户的昵称、年龄、性别、积分等,这时候在需要修改其中某一项时,通常需要将所有值取出反序列化后,修改某一项的值,再序列化存储回去。这样不仅增大了开销,也不适用于一些可能并发操作的场合(比如两个并发的操作都需要修改积分)。而Redis的Hash结构可以使你像在数据库中Update一个属性一样只修改某一项属性值。
每次存入一个hash对象, 接着存入键值对 key-value
即存入一个
lishaoxiao
lishaoxiao下面有很多个键值对
name lishaoxiao
age 20
-
Lists
Lists 就是链表,相信略有数据结构知识的人都应该能理解其结构。使用Lists结构,我们可以轻松地实现最新消息排行等功能。Lists的另一个应用就是消息队列,可以利用Lists的PUSH操作,将任务存在Lists中,然后工作线程再用POP操作将任务取出进行执行。Redis还提供了操作Lists中某一段的api,你可以直接查询,删除Lists中某一段的元素。
-
Sets
Sets 就是一个集合,集合的概念就是一堆不重复值的组合。利用Redis提供的Sets数据结构,可以存储一些集合性的数据,比如在微博应用中,可以将一个用户所有的关注人存在一个集合中,将其所有粉丝存在一个集合。Redis还为集合提供了求交集、并集、差集等操作,可以非常方便的实现如共同关注、共同喜好、二度好友等功能,对上面的所有集合操作,你还可以使用不同的命令选择将结果返回给客户端还是存集到一个新的集合中。
-
Sorted Sets
和Sets相比,Sorted Sets增加了一个权重参数score,使得集合中的元素能够按score进行有序排列,比如一个存储全班同学成绩的Sorted Sets,其集合value可以是同学的学号,而score就可以是其考试得分,这样在数据插入集合的时候,就已经进行了天然的排序。另外还可以用Sorted Sets来做带权重的队列,比如普通消息的score为1,重要消息的score为2,然后工作线程可以选择按score的倒序来获取工作任务。让重要的任务优先执行。
-
Pub/Sub
Pub/Sub 从字面上理解就是发布(Publish)与订阅(Subscribe),在Redis中,你可以设定对某一个key值进行消息发布及消息订阅,当一个key值上进行了消息发布后,所有订阅它的客户端都会收到相应的消息。这一功能最明显的用法就是用作实时消息系统,比如普通的即时聊天,群聊等功能。
-
Transactions
谁说NoSQL都不支持事务,虽然Redis的Transactions提供的并不是严格的ACID的事务(比如一串用EXEC提交执行的命令,在执行中服务器宕机,那么会有一部分命令执行了,剩下的没执行),但是这个Transactions还是提供了基本的命令打包执行的功能(在服务器不出问题的情况下,可以保证一连串的命令是顺序在一起执行的,中间有会有其它客户端命令插进来执行)。Redis还提供了一个Watch功能,你可以对一个key进行Watch,然后再执行Transactions,在这过程中,如果这个Watched的值进行了修改,那么这个Transactions会发现并拒绝执行。
Q: Redis有哪些数据结构?#
A: 字符串String、字典Hash、列表List、集合Set、有序集合SortedSet。
如果你是Redis中高级用户,还需要加上下面几种数据结构HyperLogLog、Geo、Pub/Sub。
如果你说还玩过Redis Module,像BloomFilter,RedisSearch,Redis-ML,面试官得眼睛就开始发亮了。
Q: 使用过Redis分布式锁么,它是什么回事?#
A:
- 先拿setnx来争抢锁,抢到之后,再用expire给锁加一个过期时间防止锁忘记了释放。
- 这时候对方会告诉你说你回答得不错,然后接着问如果在setnx之后执行expire之前进程意外crash或者要重启维护了,那会怎么样?
- 这时候你要给予惊讶的反馈:唉,是喔,这个锁就永远得不到释放了。
- 紧接着你需要抓一抓自己得脑袋,故作思考片刻,好像接下来的结果是你主动思考出来的,然后回答:我记得set指令有非常复杂的参数,这个应该是可以同时把setnx和expire合成一条指令来用的!对方这时会显露笑容,心里开始默念:摁,这小子还不错。
Q: 假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如果将它们全部找出来?#
A:使用keys指令可以扫出指定模式的key列表。
Q:对方接着追问:如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题?#
A: 这个时候你要回答redis关键的一个特性:redis的单线程的。keys指令会导致线程阻塞一段时间,线上服务会停顿,直到指令执行完毕,服务才能恢复。这个时候可以使用scan指令,scan指令可以无阻塞的提取出指定模式的key列表,但是会有一定的重复概率,在客户端做一次去重就可以了,但是整体所花费的时间会比直接用keys指令长。
Q: 使用过Redis做异步队列么,你是怎么用的?#
A:
一般使用list结构作为队列,rpush生产消息,lpop消费消息。当lpop没有消息的时候,要适当sleep一会再重试。
Q: 如果对方追问可不可以不用sleep呢?#
A:
list还有个指令叫blpop,在没有消息的时候,它会阻塞住直到消息到来。
Q:
如果对方追问能不能生产一次消费多次呢?#
A:
使用pub/sub主题订阅者模式,可以实现1:N的消息队列。
Q: 对方追问pub/sub有什么缺点?#
A:在消费者下线的情况下,生产的消息会丢失,得使用专业的消息队列如rabbitmq等。
Q: 如果对方追问redis如何实现延时队列?#
A:使用sortedset,拿时间戳作为score,消息内容作为key调用zadd来生产消息,消费者用zrangebyscore指令获取N秒之前的数据轮询进行处理。
Q: 如果有大量的key需要设置同一时间过期,一般需要注意什么?#
A: 如果大量的key过期时间设置的过于集中,到过期的那个时间点,redis可能会出现短暂的卡顿现象。一般需要在时间上加一个随机值,使得过期时间分散一些。
Q:Redis如何做持久化的?#
A:
bgsave做镜像全量持久化,aof做增量持久化。因为bgsave会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要aof来配合使用。在redis实例重启时,会使用bgsave持久化文件重新构建内存,再使用aof重放近期的操作指令来实现完整恢复重启之前的状态。
Q:上面持久化的过程如果突然机器掉电会怎样?#
A: 取决于aof日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据。
Q: 对方追问bgsave的原理是什么?#
A:
你给出两个词汇就可以了,fork和cow。fork是指redis通过创建子进程来进行bgsave操作,cow指的是copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。
Q: Pipeline有什么好处,为什么要用pipeline?#
A:
可以将多次IO往返的时间缩减为一次,前提是pipeline执行的指令之间没有因果相关性。使用redis-benchmark进行压测的时候可以发现影响redis的QPS峰值的一个重要因素是pipeline批次指令的数目。
Q: Redis的同步机制了解么?#
A:
Redis可以使用主从同步,从从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
Q:是否使用过Redis集群,集群的原理是什么?#
A:
Redis Sentinal着眼于高可用,在master宕机时会自动将slave提升为master,继续提供服务。
Redis Cluster着眼于扩展性,在单个redis内存不足时,使用Cluster进行分片存储。