Redis相关
Redis:
1.String:最基本的数据类型,二进制安全
记录用户每天访问网站的次数
通过 incr + 拼接用户id userID + 时间戳 精确到日 来记录并统计
然后通过日期和用户id查询用户的访问次数
2.Hash:String元素组成的字典,适合用于存储对象
3.List
能实现stack的功能,因此用来实现了网站的最新公告排行榜功能
4.Set (通过 sadd创建)
微博开发 将一个用户的所有关注人存在一个set中,也可以将其所有粉丝再存入一个
集合中,这样通过并集,差集,交集等来实现共同关注和喜好之类的功能
5.Sorted Set (通过zadd创建) 有序不重复的Set 从小到大排序 值得集合根据Score排序
应用: 不同用户有不同的权限,通过SortedSet来做消息队列, 普通用户score为1,会员用户为2,然后工作线程按score的大小来获取工作的任务,这样会员用户就能优先执行
6.HyperLogLog---用于计数
7.Geo----用于存储地理位置信息
面试问题1:从海量数据里查询某一固定前缀的key?
-
先问面试官数据量大概多少
如果不多则可以直接通过 keys + 正则表达式方式筛选
如果多则通过
scan + cursor + match + count 值的命令返回
如 scan 0 match k1* count 10
结果会返回已经迭代的游标(cursor)和结果集,返回数量不一定是10个
下次再查询的时候把之前得到的cursor加上
但是注意:这个cursor不一定是递增的,因此这就意味着数据可能重复,所以需要自己实现去重操作如使用hashset.
面试问题2:如何通过Redis实现分布式锁?
1.分布式需要解决的问题
- 互斥性
- 安全性
- 死锁
- 容错
解决:
1.setnx locknx key 通过返回值判断是否成功,返回1则没有被占用,0则被占用
2.expire locknx 2 设置过期时间2s
缺陷:1和2操作都是原子性,但组合起来不一定是原子性,所以该方法可能仍旧存在key会被一直占用的问题.
更好的解决方法:
SET key value[EX seconds] [PX milliseconds] [NX|XX]
如 set locktarget 12345 ex 10 nx
- EX second:设置键的过期时间为second秒
- PX millisecond : 设置键的过期时间为millisecond 毫秒
- NX : 只在键不存在时,才对键进行设置操作
- XX: 只在键已存在时,才对键进行设置操作
- SET 操作成功完成时,返回OK, 否则返回nil
面试问题3:大量的key同时过期的注意事项?
答: 集中过期,由于清除大量的key很耗时,因此会出现短暂的卡顿现象
解决方案:在设置key的过期时间时,给每个key加上随机值,使得过期时间分散些即可在很大程度上避免卡顿现象发生
面试问题4:如何使用Redis做异步队列?
答:使用List作为队列,RPUSH生产消息,LPOP消费消息
缺点:LPOP没有等待队列里有值,而直接消费
弥补:可以通过在应用层引入Sleep机制去调用LPOP重试
不通过sleep方式解决:
LIST里还有一条指令
BLPOP key[key...] timeout: 阻塞直到队列有消息或者超时
缺点:只能供一个消费者消费
实现一对多的消息队列:
pub/sub主题订阅者模式:
发布者(pub)向topic(频道)发布消息,多个客户端(订阅者sub)可以订阅topic的消息
缺点:消息的发布是无状态的,无法保证可达----对于发布者来说,消息即发即收的,如果发布消息后,消费者(订阅者下线),再重新上线是无法收到消息的,解决这种问题就需要更专业的消息队列,如kafka
面试问题5:Redis如何做持久化?
1.RDB(快照)持久化: 保存某个时间点的全量数据快照
在redis.conf里有默认三种策略 ,自动触发RDB持久化时候会采用这里的策略通过BGSAVE生成dump.rdb存储
- SAVE: 阻塞Redis的服务器进程,直到RDB文件被创建完毕
- BGSAVE: Fork出一个子进程来创建RDB文件,不阻塞服务器进程
RDB持久化缺点:
- 内存数据的全量同步,数据量大会由于I/O而严重影响性能
- 可能会因为Redis挂掉而丢失从当前至最近一次快照期间的数据
2.AOF持久化:保存写状态(默认关闭,通过修改redis.conf里的配置开启)
- 记录下除了查询以外的所有更变数据库状态的指令
- 以append的形式追加保存到AOF文件中(增量)
RDB和AOF文件共存情况下的Redis数据恢复
- 1.优先加载AOF文件
- 2.若不存在AOF则加载RDB
RDB和AOF的优缺点:
- RDB优点: 全量数据快照,文件小,恢复快
- RDB缺点: 无法保存最近一次快照之后的数据
- AOF优点: 可读性高,适合保存增量数据,数据不易丢失
- AOF缺点: 文件体积大,恢复时间长
redis4.0后采用默认的RDB-AOF混合持久化方式
- BGSAVE做镜像全量持久化,AOF做增量持久化
面试问题6:为什么使用pipeline?(pipeline的好处?)
- Pipeline和Linux的管道类似
- Redis基于请求/响应模型,单个请求处理需要一一答应
- Pipeline允许批量执行指令,而不需要等待上一条指令的结果,节省多次I/O往返的时间
- 有顺序依赖的指令建议分批发送
Redis的同步机制
主从同步原理
image.png