1.Redis中的数据结构
答:字符串String、字典Hash、列表List、集合Set、有序集合SortedSet、HyperLogLog(基数统计)、Geo(地理位置)、Pub/Sub(发布订阅)。Redis Module、RedisSearch、Redis-ML是什么鬼,后续要学习一下。BlomFilter过滤器即多个Hash函数判定一个Key是否存在,在允许一定误判场景下,BloomFilter是有用的,扩展BloomFilter等。
2.Redis分布式锁
setnx + expire命令或者set ex nx命令,推荐使用后者。因为,setnx + expire为两条指令并非原子操作,在setnx命令执行成功,expire命令执行失败的情况下会导致该key被一直锁住,因为平常使用分布式锁时,推荐使用set ex nx命令的原子操作。
3. Redis key处理相关
Redis中提供了keys命令可以我们按照指定模式进行key查找。例如,查找某一前缀的所有key,可以这么搞keys prefix。像这种按模式匹配key查找的命令是要进行整个键空间的扫描的且Redis是单线程的,扫描大量的键空间,会导致线上服务停顿,直到该指令执行完毕,服务才能恢复。通常采用scan这种无阻塞的方法进行整个键空间的增量式迭代。例如,scan mykey 0 match prefix,返回指定匹配模式的键,采用这种方法可能存在key重复的情况,应用程序代码中需要进行去重处理。
4.Redis异步队列
Redis中一般使用List作为队列,rpush生产消息,lpop消费消息,阻塞式消费消息采用blpop或brpop命令。如果需要实现一对多的生产消费,则需要结合Redis的Pub/Sub发布订阅机制,实现1:N的消息队列。使用发布订阅机制,在消费者下线的情况下,生产的消息将会丢失,必须使用专业的消息队列。
Redis中延时队列的实现方法:采用sortedset(有序集合),其中score值采用时间戳,应用程序代码按照时间段轮询,每次通过sortedset提供的zrangebyscore命令获取某段时间内相关的key,进行相应处理
5. Redis过期处理
Redis在处理某一时刻大量key过期的情况下,会存在短暂的卡顿现象。正确地设置过期时间的方法是在某一固定时间的基础上增加一个随机偏移。
6. Redis持久化
bgsave做镜像全量持久化,aof做增量持久化。因为bgsave会耗费较长时间,不够实时,在停机的时候会导致大量丢失数据,所以需要aof来配合使用。在redis实例重启时,优先使用aof来恢复内存的状态,如果没有aof日志,就会使用rdb文件来恢复。
如果再问aof文件过大恢复时间过长怎么办?你告诉面试官,Redis会定期做aof重写,压缩aof文件日志大小。如果面试官不够满意,再拿出杀手锏答案,Redis4.0之后有了混合持久化的功能,将bgsave的全量和aof的增量做了融合处理,这样既保证了恢复的效率又兼顾了数据的安全性。这个功能甚至很多面试官都不知道,他们肯定会对你刮目相看。
如果对方追问那如果突然机器掉电会怎样?取决于aof日志sync属性的配置,如果不要求性能,在每条写指令时都sync一下磁盘,就不会丢失数据。但是在高性能的要求下每次都sync是不现实的,一般都使用定时sync,比如1s1次,这个时候最多就会丢失1s的数据。
如果对方追问bgsave的原理是什么?你给出两个词汇就可以了,fork和cow。fork是指redis通过创建子进程来进行bgsave操作,cow指的是copy on write,子进程创建后,父子进程共享数据段,父进程继续提供读写服务,写脏的页面数据会逐渐和子进程分离开来。
7. Redis pipeline
Redis pipeline可以将多次I/O往返的时间缩减为一次,能够使用pipeline的前提是各个指令之间没有因果关系。redis-benchmark进行压测的时候显示影响redis qps峰值的一个重要因素是pipeline批次指令的数目。
8. Redis同步机制
Redis可以使用主从同步,从从同步。第一次同步时,主节点做一次bgsave,并同时将后续修改操作记录到内存buffer,待完成后将rdb文件全量同步到复制节点,复制节点接受完成后将rdb镜像加载到内存。加载完成后,再通知主节点将期间修改的操作记录同步到复制节点进行重放就完成了同步过程。
9. Redis集群
Redis Sentinal着眼于高可用,在master宕机时自动将slave提升为master,继续提供服务。
Redis Cluster着眼于扩展性,在单机内存不足的情况下,使用Cluster进行数据分片存储。