1.什么是缓存穿透?怎么解决?
缓存穿透指的是输入一个不存在的数据,缓存中查询不到,就会导致每次去数据库查询。
解决方法:
1.缓存一个空值。
2.使用布隆过滤器
布隆过滤器的原理就是查询一个数据在不在一个集合中吗,如果在就继续进行后续的查询操作,如果不在就直接返回。
2.什么是缓存击穿?怎么解决?
缓存击穿指的是对于设置过期时间的key,在过期的时间,对于这个key有大量并发请求打来,这些请求会直接进入数据库加载数据并返回,大量的并发请求可能会把数据库压垮。
解决方法:
1.设置互斥锁
2.逻辑过期
3.什么是缓存雪崩?怎么解决?
缓存雪崩指的是大量的key在同一时间过期,这时有大量关于这些key的请求打过来,这些请求会直接去数据库查询,造成数据库压力过大,从而导致雪崩。
解决办法:
设置不同的过期时间,在原有过期时间上添加一个随机时间。
4.redis作为缓存,mysql数据如何与redis进行同步呢?(双写一致性)
1.可以采用redisson实现的读写锁保持双写一致,在读的时候添加共享锁,这样可以保证读读不互斥,读写互斥。在更新数据的时候添加排它锁,他可以保证读读互斥,读写也互斥,这样就可以在写数据的时候避免其他线程读数据,避免了脏读。
排他锁的底层是sentx,保证了同时只有一个线程能够锁住的方法。
2.可以使永阿里云组件canal实现数据同步,不需要更改业务代码,部署一个canal后,canal会把自己伪装成一个Mysql节点。
5.redis作为缓存,数据的持久化是怎么做的?
提供了两种持久化方式,RDB,AOF
6.这两种持久化方式有什么区别?
RDB:一种快照文件,把redis内存存储的数据写到磁盘上,当redis宕机重启后通过快照恢复。
AOF:是一种日志文件,他将redis操作的命令都记录道文件中,当redis实例宕机重启后,通过这个文件执行其中的命令来恢复。
7.这两种方式那种恢复的比较快?
RDB方式恢复的比较快,因为他是二进制文件,保存的时候体积小,但是容易丢失数据,所以我们一般用AOF恢复数据。
8.redis过期策略有哪些?
redis中提供了两种过期删除策略,一种是惰性删除,一种是定期删除。
惰性删除:不使用不检查,当使用这个key时在检查其是否过期,如果过期则删除,不过期就返回Key.
定期删除:设置过期时间后,每隔一段时间检车key是否过期,过期就删除。定期删除有两种模式一个是slow模式定时任务,执行频率固定,一种是fast模式执行频率不固定。
9.redis数据淘汰策略有哪些?
数据淘汰策略有很多种,他默认的是noeviction,不删出任何人数据,当内存b不够就直接报错。
我们常用的淘汰策略有两种,一种是lru,一种是lfu。
lru:最近最少使用,用当前时间减去最后一次访问的时间,值越大淘汰的优先级越高。
lfu:最少频率使用,统计每个key的访问频率,值越小淘汰的优先级越高。
10.redis内存用完会发生什么?
这个要看使用的数据淘汰策略了,如果是默认淘汰策略,他会直接报错。我们为保证数据不报错,当时使用的是allkeys-lru策略,内存不够就删除最近使用最少的数据。
11.redis分布式锁如何实现?
在redis中提供了一个setnx命令,因为redis是单线程的,在使用命令后只能有一个客户端对某个key进行设置,在key没有用过期或者删除之前其他客户端不能对这个key进行设置。
12.如何控制redis分布式锁有效时长?
因为setnx命令不好解决这个问题,所以我们用redis中的一个框架redisson解决这个问题,redisson中引入了一个看门狗机制,在一个业务持有锁的时候,他会定期检查这个业务是否还持有锁,如果持有则继续增加其锁的时间,直到业务完成后释放锁。使用redisson还有一个好处是可以提高性能,当业务1还在持有锁的时候业务2获取这个锁时并不会马上拒绝,而是不断的自旋获取锁,当业务1释放锁后业务2可以立刻获取锁。
13.redisson实现的分布式锁是可以重入的吗?
是可重入的,这样做是为了避免死锁问题,其实就是在内部判断是否是当前线程持有锁,如果是当前线程持有锁,则会记数,如果释放锁就会在记数上减一。
14.redisson实现的分布式锁能解决主从一致性问题吗?
这个是不能解决的,比如线程1加锁之后,master节点会异步复制到slave节点,这时如果master节点宕机,slave节点就会被升为新的msater节点,这时如果来了线程2进行加锁,那么会在新的master节点加锁,这就造成了两个线程持有同一把锁。
可以使用红锁来解决这个问题,他可以避免线程1加锁宕机后,线程2再次加到当前锁的情况,但是使用红锁,需要在多个节点上都加锁,这就造成性能低的情况,而且其维护成本高,所以我们一般不会直接使用红锁,并且官方也暂时废除了这个功能。
15.如果业务要保证数据的强一致性,这个该怎么解决?
因为redis本身就支持高可用的,如果要做到强一致的话,就非常影响性能了,所以我们可以使用zookeeper实现的分布式锁,他可以实现强一致性。
16.redis集群有哪些方案?
redis集群有三种:主从复制,哨兵模式,分片集群。
17.介绍一下主从同步,并说一下主从同步的流程。
主从同步分为两个阶段:一个是全量同步,一种是增量同步
全量同步:
首先从节点会请求主节点进行数据同步,携带自己的replication id 和offset偏移量,然后主节点会根据id是否一致判断是否是第一次同步,如果不一致就说明是第一次同步,主节点就会发送自己的replication id 和offset偏移量给从节点,从而保持数据一致。在发送的同时主节点会执行bgsave,生成rdb文件,发送给从节点,从节点先把自己的数据清空,然后在执行rdb文件,从而保持数据一致。
如果在生成rdb期间有请求到了主节点,主节点就会把它以命令的方式记录到缓冲区,缓冲区是一个日志文件,最后把这个文件发送给从节点,就保证了数据一致,我们后期在同步数据的时候都是依赖这个日志文件的。
增量同步:
从节点服务重启之后数据就不一致了,这个时候请求主节点同步,主节点还是判断是不是第一次同步,不是的话就获取offset值,然后主节点从命令文件中获取offset之后的数据发送给从节点。
18.怎样报持redis的高并发高可用?
通过主从加哨兵模式保持redis的高并发高可用,哨兵模式可以实现主从集群的自动故障恢复,当主节点宕机,哨兵会推选新的从节点为主节点,故障恢复后也是以新的主节点为主,同时哨兵也充当redis服务发现来源,当redis发生故障转移时,哨兵会发送最新的信息给客户端,所以我们一般使用哨兵模式来保证redis的高并发高可用。
19.你们使用redis是单点还是集群,那种集群?
我们当时使用的是主从加哨兵,一般单节点不会超过10G,如果内存不够的话,可以给不同的服务器分配独立的主从节点,尽量不要用分片集群,因为集群维护起来比较麻烦。
20.redis集群脑裂该怎么解决?
这个很少见,是这样的,我们现在用的是redis哨兵模式集群的,由于网络故障原因,使得主节点,从节点和哨兵处于不同的网络区段,这时哨兵就感觉不到主节点的心跳,他就会从新选取一个新的从节点作为主节点,这样就造成了有两个主节点存在,这就是脑裂,当网络故障恢复后,旧的主节点会被降级为从节点,以新的主节点为主,这样就会造成数据的大量丢失。
解决的话可以通过redis配置:第一:设置最少有一个从节点才能够进行数据同步,第二个:设置主从数据复制和同步的延迟时间,达不到要求就拒绝同步,可以避免大量数据丢失。
21.redis分片集群有什么作用?
分片集群主要解决海量数据储存问题,分片集群有多个主节点,每个主节点存贮不同的数据,并且可以给每个主节点设置多个从节点,就可以继续增加高并发能力。
22.redis分片集群中数据是怎样存储和读取的?
redis引入了哈希槽,有16384个哈希槽,每个主节点绑定了一定范围的哈希槽范围,key通过CRC16校检,取模来决定放入那个槽,通过槽找到对应的节点进行存储。
23.redis是单线程为什么还那么快?
1.纯内存操作,c语言编写。
2.采用单线程,避免不必要的上线文切换、
3.使用多路i/o复用类型,非阻塞io。
24.能解释一下i/o多路复用模型吗?
i/o多路复用就是通过单个线程监听多个socket,并在某个socket可写,可读时得到通知,避免了不必要的等待,充分利用了cpu资源。现在i/o多路复用基本his通过empoll模式实现的,他可以通知进程socket的同时,把已就绪的socket写入空间,不需要在遍历每个socket判断是否就绪,提高了性能。