Redis面试题总结
Redis面试题总结1:常见考点
#### Redis 为何这么快? 1. 基于内存; 2. 单线程减少上下文切换,同时保证原子性; 3. IO多路复用; 4. 高级数据结构(如 SDS、Hash以及跳表等) #### 为何使用单线程? - 官方答案 因为 Redis 是基于内存的操作,CPU 不会成为 Redis 的瓶颈,而最有可能是机器内存的大小或者网络带宽。既然单线程容易实现,而且 CPU 不会成为瓶颈,那就顺理成章地采用单线程的方案了。 - 详细原因 1)不需要各种锁的性能消耗 Redis 的数据结构并不全是简单的 Key-Value,还有 List,Hash 等复杂的结构,这些结构有可能会进行很细粒度的操作,比如在很长的列表后面添加一个元素,在hash当中添加或者删除一个对象。这些操作可能就需要加非常多的锁,导致的结果是同步开销大大增加。 2)单线程多进程集群方案 单线程的威力实际上非常强大,每核心效率也非常高,多线程自然是可以比单线程有更高的性能上限,但是在今天的计算环境中,即使是单机多线程的上限也往往不能满足需要了,需要进一步摸索的是多服务器集群化的方案,这些方案中多线程的技术照样是用不上的。 所以单线程、多进程的集群不失为一个时髦的解决方案。 #### 缓存三大问题以及解决方案 - 缓存穿透:查询数据不存在 解决方案:缓存空值;key 值校验,如布隆筛选器 ref 分布式布隆过滤器 - 缓存击穿:缓存过期,伴随大量对该 key 的请求 解决方案:互斥锁;热点数据永不过期;熔断降级 - 缓存雪崩:同一时间大批量的 key 过期 解决方案:热点数据不过期;随机分散过期时间 #### 先删后写还是先写后删 - 先删缓存后写 DB 产生脏数据的概率较大(若出现脏数据,则意味着再不更新的情况下,查询得到的数据均为旧的数据)。 比如两个并发操作,一个是更新操作,另一个是查询操作,更新操作删除缓存后,查询操作没有命中缓存,先把老数据读出来后放到缓存中,然后更新操作更新了数据库。于是,在缓存中的数据还是老的数据,导致缓存中的数据是脏的,而且还一直这样脏下去了。 - 先写 DB 再删缓存 产生脏数据的概率较小,但是会出现一致性的问题;若更新操作的时候,同时进行查询操作并命中,则查询得到的数据是旧的数据。但是不会影响后面的查询。 比如一个是读操作,但是没有命中缓存,然后就到数据库中取数据,此时来了一个写操作,写完数据库后,让缓存失效,然后之前的那个读操作再把老的数据放进去,所以会造成脏数据。 - 解决方案 1)缓存设置过期时间,实现最终一致性; 2)使用 Cannel 等中间件监听 binlog 进行异步更新; 3)通过 2PC 或 Paxos 协议保证一致性。 #### 如何保证 Redis 的高并发 Redis 通过主从加集群架构,实现读写分离,主节点负责写,并将数据同步给其他从节点,从节点负责读,从而实现高并发 #### Redis 如何保证原子性 答案很简单,因为 Redis 是单线程的,所以 Redis 提供的 API 也是原子操作。 但我们业务中常常有先 get 后 set 的业务常见,在并发下会导致数据不一致的情况。 - 如何解决 1)使用 incr、decr、setnx 等原子操作; 2)客户端加锁; 3)使用 Lua 脚本实现 CAS 操作。 #### 有哪些应用场景? Redis 在互联网产品中使用的场景实在是太多,这里分别对 Redis 几种数据类型做了整理: - String:缓存、限流、分布式锁、计数器、分布式 Session 等。 - Hash:用户信息、用户主页访问量、组合查询等。 - List:简单队列、关注列表时间轴。 - Set:赞、踩、标签等。 - ZSet:排行榜、好友关系链表。
顶部
收展
底部
[TOC]
目录
Redis面试题总结1:常见考点
Redis面试题总结2:多线程
Redis面试题总结3:数据结构
Redis面试题总结4:数据存储
Redis面试题总结5:集群
相关推荐
Redis教程
Redis命令
Redis进阶
PHP 操作Redis