目录
21.Redis如何实现服务高可用?
22.什么是集群中的脑裂?
23.脑裂导致数据丢失怎么办?
24.Redis使用的过期删除策略是什么?
25.什么是惰性删除?
26.什么是定期删除?
27.Redis持久化时,对过期键会如何处理?
28.Redis主从模式中,对过期的key如何处理?
29.Redis内存满了,会发生什么?
30.Redis内存淘汰策略有哪些?
31.LRU算法和LFU算法有什么区别?
32.什么是缓存雪崩?如何避免?
33.什么是缓存击穿?如何避免?
34.什么是缓存穿透?如何避免?
35.如何设计一个缓存策略,可以动态缓存热点数据?
36.常见的缓存更新策略有哪些?
37.Redis管道有什么用?
38.Redis事务支持回滚吗?
21.Redis如何实现服务高可用?
Redis的主从复制、哨兵模式、切片集群。
1)主从复制
设置一台主Redis服务器,同步数据到多台从Redis服务器,主服务器可以进行读写操作,当写操作到来时会自动同步写操作命令到从服务器上,从服务器一般只读,并接受主服务器同步过来的写命令,然后执行。
主从服务器之间的写操作命令是异步执行的。主服务器执行完写操作命令后会立即返回结果给客户端,并不会等待从服务器完成写命令后再返回结果给客户端。 无法保证主从服务器之间的数据一致性。
2)哨兵模式
Redis的主从服务器模式,可能会发生主从服务器故障的问题,哨兵模式可以监控主从服务器,并提供主从服务器之间的故障转移功能。
3)切片集群(Redis Cluster )模式
当一台Redis服务器的缓存数据太大时,将大量数据分布在不同的服务器上,降低单服务器的压力,提高读写性能。
切片集群采用哈希槽来处理数据与节点的映射关系。一个切片集群共有16384个哈希槽,每个键值对会根据其key分配到不同的哈希槽中。
哈希槽映射到不同Redis节点上的方案有两种:
平均分配:使用cluster create命令创建集群时,会自动将哈希槽平均分配到不同的节点上,比如有6个节点,那么每个节点有16384/6个哈希槽。
手动分配:使用cluster meet命令手动建立节点间的连接,创建集群,再使用cluster addslots命令指定节点上的哈希槽个数。手动分配必须将16384个槽都分配完,否则集群无法正常工作。
22.什么是集群中的脑裂?
Redis主从架构中,一般是一个主节点,多个从节点。客户端和主节点之间的网络连接正常,主节点和从节点之间的网络连接发生了问题,导致主节点和从节点发生失联,哨兵会在从节点中选出一个新的主节点,从而产生了2个主节点,这就是脑裂。
Tips:如果产生了脑裂问题,这是会有一个旧的主节点A和一个新的主节点B。客户端和旧的主节点(A)连接正常,客户端会向A发送写数据,因为A与从节点之间失联,无法同步,所以会将数据保存在自己的缓冲区中。网络突然好了,这时已经有了新的主节点B了,那么A节点就会被退为从节点,向B节点请求数据同步,此时的A节点就会清空自己缓冲区的内容,再进行全量数据同步。从而造成客户端与A之间数据的丢失。
23.脑裂导致数据丢失怎么办?
在 Redis 的配置文件中有两个参数我们可以设置:
1)min-slaves-to-write x,主节点必须要有至少 x 个从节点连接,如果小于这个数,主节点会禁止写数据。
2)min-slaves-max-lag x,主从数据复制和同步的延迟不能超过 x 秒,如果超过,主节点会禁止写数据。
如果不满足上面设置的配置,那么主节点就会返回错误给客户端,禁止写操作。当新的主节点上线后,就只有新的主节点接受客户端的请求。
24.Redis使用的过期删除策略是什么?
惰性删除 + 定期删除配合使用。
25.什么是惰性删除?
不主动删除key,每次从数据库访问key时,检测key是否过期,如果没有过期,就返回key对应的value,如果过期了,就删除该key,返回nil。
优点:每次访问时才检查key是否过期,所以使用很少的资源,对CPU友好。
缺点:如果长时间没有访问一个已经过期的key,那么该key会一直存储在数据库中,浪费空间资源。
26.什么是定期删除?
每隔一段时间随机从数据库中取出一定数量的key,检查它们是否过期。
定期删除的流程:
1)从数据库中随机取20个key;
2)检查它们是否过期,并删除过期的key;
3)如果过期的key超过了25%,则继续重复步骤1(循环删除的时长默认不超过25ms)。如果小于25%,则停止,等待下一轮检查。
优点:减少过期key占用空间,限制循环删除的时长减少对CPU的影响。
缺点:难以确定删除操作的时长和频率,太频繁,对CPU不友好,太低,浪费空间资源。
27.Redis持久化时,对过期键会如何处理?
RDB持久化中,分为生成阶段和加载阶段:
1)RDB生成阶段,会检查key是否过期,如果过期,就不会保存到RDB文件中。
2)RDB加载阶段,如果Redis是主服务器,那么就会检查加载的key是否过期,如果过期就不会载入到数据库中;如果Redis是从服务器,无论key是否过期,都载入到数据库中,但是由于主从服务器在数据同步时,从服务器的数据会别情况,所以过期的key对从服务器没有影响。
AOF持久化中,分为写入阶段和重写阶段:
1)AOF写入阶段,如果服务器的过期key没有被删除,那么会保留过期key,当服务器中的key被删除后,Redis会向AOF写入DEL命令删除过期的key。
2)AOF重写阶段,对AOF执行重写时,会检查key是否过期,如果过期了就不会保存到重写后的AOF文件中。
28.Redis主从模式中,对过期的key如何处理?
从服务器不会进行过期扫描,如果某个key过期了,客户端访问从服务器的过期key,也是可以访问到的。从服务器对过期key的处理依靠主服务器,主服务器的key过期后,会在AOF文件中更新DEL命令删除过期的key,同步到所有的从服务器,从服务器根据该命令删除过期key。
29.Redis内存满了,会发生什么?
触发内存淘汰机制。
30.Redis内存淘汰策略有哪些?
分为不进行数据淘汰和进行数据淘汰策略。
1)不进行数据淘汰
i)noeviction(Redis 3.0之后,默认的策略):当内存满时,不淘汰任何数据,而是不再提供服务,直接返回错误。
2)进行数据淘汰:细分为在设置了过期时间的数据中淘汰和在所有数据范围内淘汰。
在设置了过期时间的数据中淘汰:
i)volatile-random:随机淘汰任意key-value
ii)volatile-ttl:优先淘汰更早过期的key-value
iii)volatile-lru(Redis 3.0之前默认的淘汰机制):淘汰最近最久未使用的key-value
iiii)volatile-lfu(Redis 4.0后新增的淘汰策略):淘汰最少使用的key-value
在所有数据范围内淘汰:
i)allkeys-random:随机淘汰任意key-value
ii)allkeys-lru:淘汰最近最久未使用的key-value
iii)allkeys-lfu(Redis 4.0后新增的淘汰策略):淘汰最少使用的key-value
31.LRU算法和LFU算法有什么区别?
LRU,最近最久未被使用,在Redis的对象结构体中国添加一个额外字段,记录此数据的最后一次访问时间。
LFU,最近最少使用,记录数据的访问次数。
32.什么是缓存雪崩?如何避免?
缓存雪崩:大量的缓存数据在同一时间全部过期,如果此时有大量是用户请求数据,无法在Redis中获得数据,全部请求都直接访问数据库,导致数据库压力变大,可能会造成数据库宕机,形成一系列连锁反应,造成整个系统崩溃,这就是缓存雪崩。
解决方案:将缓存过期时间随机打散,防止缓存在同一时间一起过期;设置缓存不过期。
33.什么是缓存击穿?如何避免?
缓存击穿:当Redis中的某个热点数据过期了,有大量的请求访问该热点数据,就只能访问数据库,数据库很容易就被高并发请求冲垮,这就是缓存击穿。
解决方案:设置热点数据不过期。
34.什么是缓存穿透?如何避免?
缓存穿透:访问的数据在Redis和数据库中都不存在,大量的请求造成数据库压力变大,这就是缓存穿透。
解决方案:在缓存中设置数据对应的值为空值。
35.如何设计一个缓存策略,可以动态缓存热点数据?
通过数据的最新访问时间作为排名,并过滤掉不常访问的数据,只留下最常访问的数据。
以电商平台为例,只缓存用户经常访问的1000个商品:
1)先通过缓存系统创建一个排序队列(1000容量),系统根据商品访问时间进行排序,越是最近访问的商品,越在队列前面。
2)同时系统定期过滤队列最后面的200个商品,然后从数据库中随机读取200个商品加入队列。
3)每次请求到达时,先访问队列是否存在被访问的商品ID,如果存在,则就从另一个缓存数据结构中读取实际商品信息。
36.常见的缓存更新策略有哪些?
1)Cache Aside(旁路缓存)策略,应用程序直接和缓存、数据库交互,具体细分为写策略和读策略。适合读多写少的场景,实际开发中,Redis和MySQL的缓存更新策略。
写策略:必须先更新数据库中的数据,再删除缓存。
读策略:先读取缓存中的数据,如果命中则直接返回,如果没命中,则访问数据库,并将数据写到缓存中。
2)Read/Write Through(读穿/写穿)策略,应用程序只与缓存交互,缓存和数据库交互,并更新数据库。
3)Write Back(写回)策略:只更新缓存数据,并将数据设置为脏数据,立即返回,并不更新数据库的数据。数据库的更新,会采用批量异步更新。 该策略适合写多的场景。
37.Redis管道有什么用?
客户端提供的一种批处理技术,可以一次处理多个命令,提高Redis性能,可以解决多个命令执行时的网络等待。
普通模式下:
管道模式下:
38.Redis事务支持回滚吗?
支持。
当执行事务的过程中,如果存在执行出错,则事务执行的操作全部撤销,恢复到执行事务的开始状态。