正文
解决问题的思路是
如果缓存是因为网络问题没有更新成功数据,那么建议重试几次,如果依然没有更新成功则认为缓存系统出错不可用,这时候客户端会将数据的KEY插入到消息系统中,消息系统可以过滤相同的KEY,只需保证消息系统不存在相同的KEY,当缓存系统恢复可用的时候,依次从MQ中取出KEY值然后从数据库中读取最新的数据更新缓存。
注意:更新缓存之前,缓存中依然有旧数据,所以不会造成缓存穿透。
下图展示了整个思路的过程:
看完上面的方案以后,又会有不少朋友提出疑问,如果我是第一次使用缓存或者缓存中暂时没有我需要的数据,那又该如何处理呢?
在这种场景下,客户端从缓存中根据KEY读取数据,如果读到了数据则流程结束,如果没有读到数据(可能会有多个并发都没有读到数据),这时候使用缓存系统中的setNX方法设置一个值(这种方法类似加个锁),没有设置成功的请求则sleep一段时间,设置成功的请求读取数据库获取值,如果获取到则更新缓存,流程结束,之前sleep的请求这时候唤醒后直接再从缓存中读取数据,此时流程结束。
在看完这个流程后,我想这里面会有一个漏洞,如果数据库中没有我们需要的数据该怎么处理,如果不处理则请求会造成死循环,不断的在缓存和数据库中查询,这时候我们会沿用我之前文章中的如果没有读到数据则往缓存中插入一个NULL字符串的思路,这样其他请求直接就可以根据“NULL”进行处理,直到后台系统在数据库成功插入数据后同步更新清理NULL数据和更新缓存。