1.单线程的redis为什么这么快:
redis纯内存操作;单线程操作,避免了频繁的上下文切换;采用了非阻塞I/O多路复用机制。(I/O多路复用:单线程通过跟踪每个I/O流的状态来管理多个I/O流)
1.redis和数据库双写一致性问题:
一致性问题是分布式常见问题,还可以分为最终一致性和强一致性。数据库和缓存双写,就必然会存在不一致的问题,如果对于数据有强一致性要求,就不能放缓存,我们所做的一切只可以保证最终一致性。我们所做的方案其实从根本上来说,只是可以降低不一致发放的概率,并不会避免。因此如果有强一致性要求的数据,不能放缓存。
首先,采取正确的更新策略,先更新数据库,再删除缓存。其次有可能会出现删除缓存失败的问题,可以利用消息队列进行补偿措施。
2.redis的过期策略以及内存淘汰机制:
redis采用 定期删除+惰性删除的策略,定期删除:redis默认每隔100ms检查是否有过期的key,有过期的key则删除。需要说明的是redis不是将所有的key全都扫一次,而是随机进行检查,这样的话会有很对key到期而没有删除。此时惰性删除就会排上用处,当我们获取某个key的时候,redis就会检查一下,如果这个key设置了过期时间并且过期了,就会删除。即使使用 定期删除+惰性删除的策略,也不可能保证所有的key在过期时间到了及时删除。因为当定期删除没有随机扫到,并且没有查询的时候,这些key就不会删除,这时我们可以通过 内存淘汰机制 redis.conf maxmemory-policy allkeys-lru : 当内存不足的时候,在键空间中,移除最近最少使用的key。
3.如何应对缓存穿透和缓存雪崩问题:
缓存穿透:黑客故意去请求缓存中不存在的数据,导致所有的请求都怼到数据库上,导致数据库连接异常。
缓存雪崩:缓存同一时间大面积的失效,这个时候又来了一大波请求,结果请求都怼到数据库上,从而导致数据库连接异常。
缓存雪崩的解决方案:1.给缓存的失效时间加一个随机值,避免集体失效;2.双缓存,我们有两个缓存A和B。缓存A的失效时间为20分钟,缓存B不设置失效时间。自己做预热操作, 其中:从缓存A中读取数据,有则直接返回;A没有数据,直接从B读取数据,直接返回,并且异步启动一个更新线程;更新线程同时更新缓存A和缓存B。