为什么要用Redis
- 因为
传统的关系型数据库
如Mysql已经不能适用所有的场景,比如秒杀的库存扣减,APP首页的访问流量高峰等等,都很容易把数据库打崩,所以引入了缓存中间件
,目前市面上比较常用的缓存中间件有 Redis 和 Memcached 不过中和考虑了他们的优缺点,最后选择了Redis。
Redis有哪些数据结构
- 5个基本数据类型
String
、Hash
、List
、Set
、SortedSet
。 - 中高级用户
HyperLogLog
、Geo
、Pub/Sub
。 - 加分 Redis Module,像
BloomFilter(布隆过滤器)
,RedisSearch
,Redis-ML
,
如果有大量的key需要设置同一时间过期,需要注意什么
- 如果大量的key过期时间设置的过于集中,到
过期的时间点
,Redis可能会出现短暂的卡顿
现象。严重的话会出现缓存雪崩
,一般需要在时间上加一个随机值
,使得过期时间分散一些。 - 电商首页经常会使用
定时任务刷新缓存
,可能大量的数据失效时间十分集中
,如果失效时间一样,刚好在失效的时间点大量用户涌入,就有可能造成缓存雪崩
Redis分布式锁
- 先拿
setnx
来争抢锁,抢到之后,再用expire
给锁加一个过期时间防止锁忘记了释放。
在setnx之后执行expire之前进程意外crash或者要重启维护了,会怎么样
- 故作思考片刻,
set
指令有非常复杂的参数,应该可以同时把setnx
和expire
合成一条指令来用。
假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来
- 使用
keys
指令可以扫出指定模式的key列表。
如果这个redis正在给线上的业务提供服务,那使用keys指令会有什么问题
- Redis关键的一个特性:Redis的
单线程
的。keys
指令会导致线程阻塞
一段时间,线上服务会停顿
,直到指令执行完毕,服务才能恢复。这个时候可以使用scan
指令,scan指令可以无阻塞
的提取出指定模式的key列表,但是会有一定的重复概率
,在客户端做一次去重就可以了,但是整体所花费的时间
会比直接用keys指令长
。 - 不过,增量式迭代命令也不是没有缺点的: 举个例子, 使用
SMEMBERS
命令可以返回集合键
当前包含的所有元素
, 但是对于SCAN
这类增量式迭代
命令来说, 因为在对键
进行增量式迭代的过程中, 键可能会被修改
, 所以增量式迭代命令只能对被返回的元素提供有限的保证
。
Redis做异步队列
- 一般使用
list
结构作为队列,rpush
生产消息,lpop
消费消息。当lpop没有消息的时候,要适当sleep
一会再重试。
可不可以不用sleep
list
还有个指令叫blpop
,在没有消息的时候,它会阻塞
住直到消息到来。
能不能生产一次消费多次
- 使用
pub/sub
主题订阅者
模式,可以实现1:N
的消息队列。
pub/su b有什么缺点
- 在
消费者下线
的情况下,生产的消息会丢失
,得使用专业的消息队列如RocketMQ等
。
Redis如何实现延时队列
使用sortedset
,拿时间戳作为score
,消息内容作为key
调用zadd
来生产消息,消费者用zrangebyscore
指令获取N秒之前的数据轮询
进行处理。
Redis是怎么持久化的?服务主从数据怎么交互的?
RDB
做镜像全量持久化
,AOF
做增量持久化
。因为RDB会耗费较长时间
,不够实时,在停机
的时候会导致大量丢失
数据,所以需要AOF
来配合使用。在redis实例重启时,会使用RDB
持久化文件重新构建内存
,再使用AOF
重放近期的操作指令来实现完整恢复重启之前的状态。- 这里很好理解,把
RDB
理解为一整个表全量
的数据,AOF
理解为每次操作的日志
就好了,服务器重启的时候先把表的数据全部搞进去,但是他可能不完整,你再回放一下日志,数据不就完整了嘛。 - Redis本身的机制是 AOF持久化
开启
且存在
AOF文件时,优先
加载AOF文件;AOF关闭
或者AOF文件不存在
时,加载RDB文件;加载AOF/RDB文件城后,Redis启动成功; AOF/RDB文件存在错误
时,Redis启动失败并打印错误信息
突然机器掉电会怎样?
- 取决于
AOF
日志sync
属性的配置,如果不要求性能,在每条写指令时都sync
一下磁盘,就不会丢失数据。但是在高性能
的要求下每次都sync是不现实的,一般都使用定时
sync,比如1s1次,这个时候最多就会丢失1s的数据。
RDB的原理是什么
fork
和cow
。fork
是指redis通过创建子进程
来进行RDB
操作,cow
指的是copy on write
,子进程
创建后,父子
进程共享
数据段,父进程继续提供读写
服务,写脏的页面数据会逐渐和子进程分离
开来。AOF
和RDB
的优缺点,两者其实区别还是很大的,涉及到Redis集群
的数据同步问题等等。
Pipeline有什么好处,为什么要用pipeline
- 可以将
多次IO
往返的时间缩减
为一次,前提
是pipeline
执行的指令之间没有因果相关性
。使用redis-benchmark
进行压测的时候可以发现影响redis的QPS
峰值的一个重要因素是pipeline
批次指令的数目。
Redis的同步机制
- Redis可以使用
主从
同步,从从
同步。第一次同步时,主节点做一次bgsave
,并同时将后续修改操作记录到内存buffer
,待完成后将RDB
文件全量同步到复制节点,复制节点接受完成后将RDB镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。后续的增量数据通过AOF日志同步即可,有点类似数据库的binlog。
Redis集群,集群的高可用怎么保证,集群的原理
Redis Sentinal
着眼于高可用
,在master
宕机时会自动将slave
提升为master
,继续提供服务。Redis Cluster
着眼于扩展性
,在单个redis内存不足
时,使用Cluster
进行分片存储
。