【面蹄】Redis总结

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/tian330726/article/details/84332830

总结实际项目中及面试中所可能遇到的问题,总结之,记录之,并即时更新补充。

开始面试前,先通过三段式(是什么、为什么、怎么用)简单了解Redis:
Java

主菜开始(主要结合自己项目中的实际使用情况,答案不唯一,仅供参考):

1、Redis在你项目中的实际应用

(1) 缓存热数据,如数据库中的字典表信息
(2) 完成统计(计数)功能
可以加快数据的访问速度,还能有效地降低后端数据源的压力

2、使用什么数据格式,并谈谈其他数据格式,及其使用场景

主要使用哈希(hash)格式,形如value={{field1,value1},{field2, value2},…{fieldN, valueN}}
下面谈谈其他数据格式:
redis数据结构
参考自----《Redis开发与运维》图2-1
Redis使用场景

3、为什么使用Redis,而不用Memcached?

(1) Memcached所有的值均是简单的字符串,Redis作为其替代者,支持更为丰富的数据类型
(2) Redis的速度比Memcached快很多
(3) Redis可以持久化其数据

4、为什么Redis的速度快?

(1) 完全基于内存,绝大部分请求是纯粹的内存操作,非常快速。数据存在内存中,类似于HashMap,HashMap的优势就是查找和操作的时间复杂度都是O(1);
(2) 采用单线程,避免了不必要的上下文切换和竞争条件,也不存在多进程或者多线程导致的切换而消耗 CPU,不用去考虑各种锁的问题,不存在加锁释放锁操作,没有因为可能出现死锁而导致的性能消耗;
(3) 使用多路I/O复用模型,非阻塞IO;

5、讲讲你对多路 I/O 复用模型的理解

多路I/O复用模型是利用 select、poll、epoll 可以同时监察多个流的 I/O 事件的能力,在空闲的时候,会把当前线程阻塞掉,当有一个或多个流有 I/O 事件时,就从阻塞态中唤醒,于是程序就会轮询一遍所有的流(epoll 是只轮询那些真正发出了事件的流),并且只依次顺序的处理就绪的流,这种做法就避免了大量的无用操作。
这里“多路”指的是多个网络连接,“复用”指的是复用同一个线程。

6、说说Redis的持久化

Redis支持RDBAOF两种持久化机制,持久化功能有效地避免因进程退出造成的数据丢失问题,当下次重启时利用之前持久化的文件即可实现数据恢复。
RDB(Redis DataBase)持久化是将Reids在内存中的数据库记录定时dump到磁盘上的RDB持久化。
AOF(Append Only File)持久化是将Reids的操作日志以追加的方式写入文件。
详细说明可参考:Redis持久化

7、Redis的数据是一直存在吗?(问数据淘汰策略)

使用过期策略以及内存淘汰机制 ---- 定期删除+惰性删除策略

8、Redis支持的Java客户端都有哪些?

Redisson、Jedis、lettuce等等,官方推荐使用Redisson。
在项目开发中使用了Jedis,栗子:JedisPool工具类及使用

9、Redis使用中的注意事项

(1) 缓存和数据库双写一致性问题


高级题

Ⅰ.慢查询分析

通过慢查询分析可以找到有问题的命令进行优化。
预设阈值:slowlog-log-slower-than 它的单位是微秒(1秒=1000毫秒=1000000微秒),默认值是10000,假如执 行了一条“很慢”的命令(例如keys*),如果它的执行时间超过了10000微秒,那么它将被记录在慢查询日志中。
slowlog-log-slower-than配置建议:默认值超过10毫秒判定为慢查询,需要根据Redis并发量调整该值。由于Redis采用单线程响应命令,对于高流量的场景,如果命令执行时间在1毫秒以上,那么Redis最多可支撑OPS不到1000。因此对于高OPS场景的Redis建议设置为1毫秒。
日志存放:slowlog-max-len是列表的最大长度。一个新的命令满足慢查询条件时被插入到这个列表中,当慢查询日志列表已处于其最大长度时,最早插入的一个命令将从列表中移出,例如slowlog-max-len设置为5,当有第6条慢查询插入的话,那么队头的第一条数据就出列,第6条慢查询就会入列。
slowlog-max-len配置建议:线上建议调大慢查询列表,记录慢查询时Redis会对长命令做截断操作,并不会占用大量内存。增大慢查询列表可以减缓慢查询被剔除的可能,例如线上可设置为1000以上。

Ⅱ. Pipeline(流水线)机制

Pipeline在某些场景下非常有用,比如有多个command需要被“及时的”提交,而且他们对相应结果没有互相依赖,对结果响应也无需立即获得,那么pipeline就可以充当这种“批处理”的工具;而且在一定程度上,可以较大的提升性能,性能提升的原因主要是TCP连接中减少了“交互往返”的时间。
栗子:redis中pipeline用法需要注意的地方

Ⅱ. 使用Redis怎么实现分布式事务锁?有了解过?

Ⅲ. 什么是缓存穿透?如何避免?

缓存穿透
一般的缓存系统,都是按照key去缓存查询,如果不存在对应的value,就应该去后端系统查找(比如DB)。一些恶意的请求会故意查询不存在的key,请求量很大,就会对后端系统造成很大的压力。这就叫做缓存穿透。
如何避免?
1:对查询结果为空的情况也进行缓存,缓存时间设置短一点,或者该key对应的数据insert了之后清理缓存。
2:对一定不存在的key进行过滤。可以把所有的可能存在的key放到一个大的Bitmap中,查询时通过该bitmap过滤。

Ⅳ. 什么是缓存雪崩?如何避免?

缓存雪崩
由于缓存层承载着大量请求,有效地保护了存储层,但是如果缓存层由于某些原因不能提供服务,于是所有的请求都会达到存储层,存储层的调用量会暴增,造成存储层也会级联宕机的情况。缓存雪崩的英文原意是stampeding herd(奔逃的牛),指的是缓存层宕掉后,流量会像奔逃的野牛一样,打向后端存储。
如何避免?
1:在缓存失效后,通过加锁或者队列来控制读数据库写缓存的线程数量。比如对某个key只允许一个线程查询数据和写缓存,其他线程等待。
2:做二级缓存,A1为原始缓存,A2为拷贝缓存,A1失效时,可以访问A2,A1缓存失效时间设置为短期,A2设置为长期
3:不同的key,设置不同的过期时间,让缓存失效的时间点尽量均匀。

猜你喜欢

转载自blog.csdn.net/tian330726/article/details/84332830
今日推荐