缓存的更新策略:(主要解决数据不一致问题)
(一):先更新数据库,再更新缓存(一般不建议使用)
业务角度,对于读操作很少的,造成性能浪费;
线程安全角度,容易产生数据脏读(线程A更新了数据库,线程B更新了数据库,B更新了缓存,A更新了缓存);
(二):先删除缓存,再更新数据库
错误情况:
请求A进行写操作,删除缓存
请求B查询发现缓存不存在,读取数据库,写入缓存
请求A将数据写入数据库
解决方法:
采用延时双删除法(在A写入数据库后,等待一段时间,再删除一次缓存)
等待时间设置:如果读写同步,那么时间为读数据业务逻辑的耗时+几百毫秒;如果读写分离,主从同步的延时+几百毫秒
吞吐量降低解决方法:
第二次删除用异步删除法,开一个线程,异步删除。
第二次删除失败:
尝试重新删除,具体使用消息队列
(三):先更新数据库,再删除缓存(大公司都采用这种方法)
错误情况:
缓存失效,请求A查询数据库
请求B写入数据库,请求B删除缓存
请求A将查到的值写入缓存
只有当读操作比写操作慢时,请求A才会最后写入缓存
解决并发:
异步延时删除策略
删除失败导致不一致:
重试机制:使用消息队列,嵌套到业务代码中(不好);使用订阅程序去订阅数据库的binlog,另起一个程序处理缓存删除。MySQL订阅程序插件:canal