1、redis数据结构
string, list, set, SortSet, hash
HyperLogLog:适用于基数体积很大的统计
Geo:用于坐标,显示周边信息
发布/订阅
2、击穿/穿透/雪崩
缓存击穿
在缓存过期的时刻,同时有大量请求达到DB,对DB造成请求大,压力大。
- 设置热点数据永不过期
- 互斥锁。如果为null,加锁,设置值之后释放锁
缓存穿透
查询一个不存在的数据,一直请求。比如id=0的数据。
- 布隆过滤器
- 设置key对应的value=null
缓存雪崩
大量的key设置了相同的缓存时间,在同一时间失效,造成瞬间DB的大量请求,压力骤增,引发雪崩。
- 过期时间随机
分析:
以上三种情况,实际归根结底,都是redis无数据,给DB造成压力。
3、redis分布式锁
使用setnx
获取锁,再使用expire
加一个过期时间,以防没有释放,造成堵塞。并同时将setnx
和expire
合并成一条指令,防止setnx
执行完毕,expire
未执行造成堵塞。
4、假如Redis里面有1亿个key,其中有10w个key是以某个固定的已知的前缀开头的,如何将它们全部找出来?
使用keys
命令查找具有相同开头的数据。
由于redis是单线程的,所以如果是线上的数据,keys
命令会造成停顿。需要加上scan
命令,这样可以无阻塞的获取到数据,但是获取到的数据可能有一定的重复, 在程序中做一次去重。
由于scan
命令是增量式迭代命令,不能保证返回后的数据被修改,所以该命令只能对返回的数据有限的保证。
5、redis异步队列
使用list存储数据,使用rpush
生产消息,使用lpop
消费消息。当lpop
没有消息的时候,可以使用sleep
,一会再重试。也可以使用blpop
命令,block left pop
,可以阻塞直到消息到来。
实现1:N
使用pub/sub
发布订阅模式实现一对多。但是当消费者下线时,消息会丢失。
6、Redis如何实现延时队列?
使用sortset
数据结构,用时间戳作为score
,信息内容作为key
来zadd
生产消息。消费时,使用zrangebyscore
获取N秒之前的数据,轮询处理 。
7、redis日志
redis有RDB
和AOF
两种保存日志的方式。
RDB
就是保存在磁盘上,可以选择没两个小时归档最近一天的数据。RDB
实际上是fork
一个子进程,使用子进程备份数据,然后替换之前的文件,使用二进制进行压缩存储。
AOF
则是以日志形式记录每一个写,删命令,以文本的方式记录,可以看到详细的执行记录。AOF
可以选择一秒记录一次,这样最多丢失一秒的数据。
RDB
以二进制存储,所以文件会更小。其执行方式使它在效率上会更快,但是在数据保存时效性上,没有AOF
强,对比2小时归档和1s执行记录。
在实际应用中,我们一般两种方式都会使用,并且使用异地容灾
的存储方式,比如一个服务器在上海,复制一份数据到北京的服务器。这样当服务器炸了,也有数据可以备份。AOF
可以保证数据的即时性,不会丢失很多数据。RDB可以尽量的保证全量性。