问题:
应用中用redis或者memcached等DB缓存方案,当更新数据时,是先更新数据库后失效缓存,还是先失效缓存,再更新数据库?
以下分别展开描述:
1,先更新数据库,后失效缓存:方案的优点是缓存不miss,缺点是数据更新成功但缓存更新失败,会导致后面读取到的是更新前的脏数据;
2,先失效缓存,后更新数据库:方案的优点是避免了方案1的问题;正常情况下仅仅是多了一次缓存miss;但如果在并发的情况下,连接1更新数据库,连接2在连接1更新完成之前访问DB并读取到了更新前的数据,并写入缓存,这样会导致获取到脏数据;
基于上面的情况,如果在缓存DB一致性要求不高的场景,可以允许有一个缓存周期的脏数据的话,则无需考虑;
如果是要求强一致性,则方案1的情况下,后续的读请求会读到cache脏数据,设置全局flag强制不走cache,直接DB,且同时不断尝试更新缓存;直至缓存失效或更新成功;此思路简便但具有一定不确定性;
上述方案2的话,则需要在并发写、读情况下,对数据库的操作需要保证序列化,也就是保证先写后读,按顺序执行;改造方案:①,保证在单机应用上数据库连接写读复用,GetDBConnection(longid);②,分布式应用保证相同ID的请求路由到同一服务实例上GetServiceConnection(longid);也就是分别改动获取service连接和获取DB连接的实现方式;