美团面试题:缓存一致性,我是这么回答的!
源 / 月伴飞鱼 文/ 日常加油站
人生本就是苦还是只有童年苦?生命就是如此! -----这个杀手不太冷
前言
如何保证缓存和数据库的一致性?
方案分析
先更新缓存,再更新数据库 先更新数据库,再更新缓存 先删除缓存,再更新数据库 先更新数据库,再删除缓存
updateDB();
updateRedis();
deleteRedis();
updateDB();
请求A进行写操作,删除缓存 请求B查询发现缓存不存在 请求B去数据库查询得到旧值 请求B将旧值写入缓存 请求A将新值写入数据库
updateDB();
deleteRedis();
缓存刚好失效 请求A查询数据库,得一个旧值 请求B将新值写入数据库 请求B删除缓存 请求A将查到的旧值写入缓存
方案对比
线程A更新了数据库 线程B更新了数据库 线程B更新了缓存 线程A更新了缓存
主从延时问题:不管是先删除还是后删除,数据库主从延时可能导致脏数据的产生。 缓存删除失败:如果缓存删除失败,则都会产生脏数据。
总结
推荐方案
延迟双删
public void write(String key,Object data){
redis.del(key);
db.update(data);
Thread.sleep(1000);
redis.del(key);
}
先淘汰缓存 再写数据库 休眠1秒,再次淘汰缓存
Thread.currentThread().sleep(1000);
实际场景
写缓存策略
缓存key设置失效时间 先DB操作,再缓存失效 写操作都标记key(美团中间件)强制走主库 接入美团中间件监听binlog(美团中间件)变化的数据在进行兜底,再删除缓存
读缓存策略
先判断是否走主库 如果走主库,则使用标记(美团中间件)查主库 如果不是,则查看缓存中是否有数据 缓存中有数据,则使用缓存数据作为结果 如果没有,则查DB数据,再写数据到缓存
注意
最后
好文推荐
北大女生:我被字节 PUA 了!
【自述】 大专毕业的爬虫工程师被裁,却拒绝了42K的Offer?
试用期没过,只因在公司上了1024?
一键三连「分享」、「点赞」和「在看」
技术干货与你天天见~
评论