Redis双写一致性,先改数据库再改缓存可以吗_有什么问题_-初秋
你国内的面试题看的太多了吧,这玩意有什么好纠结的吗。既然叫缓存,那就是有可能不存在,那你改缓存的意义是啥?而且你已经用缓存就一定写了读取部分的设置缓存的代码了,这里再写一次不显得很扯淡吗?Cache-Aside 模式为啥叫 aside,改缓存是内存数据库的使用方式。还有好多费很大劲搞什么一致性的,更扯淡,无论你怎么搞,都会有不一致的时间,除非你用锁控制 cache 的每个key的读写。
连 CPU 的缓存一致性同步都那么麻烦,还需要搞个MESI协议,这还是单独的机器内。你用 redis 同步数据库,还需要通过网络这种不稳定的东西。
真不知道纠结这玩意有啥用,还天天设计各种方案,搞得跟计算机民科一样,有那时间不如出去多了解了解其他行业,不然以后失业了连个其他出路都没有。
之前的回答太不友善了,给题主道个歉。主要知乎给我推荐了一堆这种redis的问题,答案都是什么双删,延迟删,列队一类的,看的想骂人。
来详细回答下问题:
1、先改数据库再改缓存不可以吗?
可以,没什么不可以的,你有这个需求就可以,甚至可以直接写 redis,这就是 write-through caching。不过这种方法比较麻烦,单表还好操作,如果涉及到多表的关联查询,基本上没法用。这个给你举一个 write-through 的例子:即时通讯的消息保存,聊天消息直接保存在 redis zSet 结构里,然后再开个列队写入数据库,或者定时刷新到数据库。
2、在事务方法的最后一行修改缓存
事务是数据库操作,要尽可能避免其他组件的影响。而且你这种方法,就是把数据库当个锁用了,这种方式还有个问题,就是要么你的数据都是经常修改的(如果是经常修改的,用这种方式简直就是为了个芝麻丢西瓜),要么就不能设置过期时间,否则key过期后就不能用redis了,除非等到下次更新。然后还有就是下面 薯片 提到的,服务挂了数据没提交和更长的事务执行时间。
这里贴个 quora 的 Facebook Memcached 缓存的问题
其实我不理解为啥国内那么喜欢和 redis 数据库的一致性杠,还有就是分布式事务。如果你找这种相关资料,几乎都是国内的,包括数据库中间件,知乎上就有个问题:为什么几乎所有的开源数据库中间件都是国内公司开源的。国外现在好多应用甚至SQL数据库都不用了,直接 MongoDB 或者Amazon DynamoDB。用这些 nosql,如果不是对响应时间有极致需求,根本没必要用 redis
kimmking 说没人能代表国内,对,确实。比如说双删,我有事务涉及到多个服务,但是又不希望每个服务都直接查数据库降低并发,那我改数据库之前删除redis同步下数据有什么不行吗。确实没问题,还是那句话,没什么不可以的,你有这个需求就可以。但是大哥,能有这个需求,有这个应用场景的有多少,更别提好多文章场景都说不清,让人看得云里雾里。缓存的几种操作模式为什么能成为模式,是因为经过多年的研究,实践,这几种方式最方便,易用,高效。
我之所以怼人是不想看太多人浪费时间在这种无用的事情上。尤其是新手,太容易被这种看似高大上的屠龙技吸引,纠结于一些细枝末节的技术。计算机要学的东西太多了,新的技术也一直层出不穷,有时间不如多了解下真正能提高工作效率的东西。甚至你去玩游戏,去旅游,去聚会,都比去纠结这种东西强。
评论区
阿布鲁星人: 你知道为什么那么多人在纠结redis和mysql的一致性吗?因为都是CRUD农民工,他们连基本的数据库理论都是一知半解,所以作者你别费劲了。 👍🏽48 💭新加坡 🕐2023-05-02 14:31:27
│ └── 乡村种地家: 因为面试会问[飙泪笑][飙泪笑] 👍🏽53 💭上海 🕐2023-05-03 16:06:24
│ └── 知乎用户RPZGpv: 新加坡的码农大部分被国内吊打 👍🏽10 💭湖北 🕐2023-05-11 07:58:20
│ │ └── buffer: 真搞笑啊 👍🏽0 💭山西 🕐2024-07-06 17:12:24
│ └── 十二东: 诚心求问,数据库理论是哪一方面的?是怎么写一个新的数据库?比如说我从零开始怎么写一个Mysql?还是怎么用数据库的?比如说我怎么Mysql 建表建索引写SQL? 👍🏽0 💭上海 🕐2023-07-17 17:43:22
│ └── 阿布鲁星人: 没错,就是自己写一个数据库,没自己亲自动手写过数据库的,在我看来哪怕背再多面试题也不过就是crud底层民工。 👍🏽2 💭新加坡 🕐2023-07-18 00:32:10
│ └── 栗子: 手写一个数据库也很水,应该手写操作系统,然后手写cpu,然后自己开工厂制作cpu,自己去采购cpu相关材料。 👍🏽3 💭湖北 🕐2024-09-16 20:15:34
│ └── 栗子: 所以理论学习应该从材料学开始,毕竟材料都没搞明白,怎么做出计算机需要的五大组件呢。 👍🏽1 💭湖北 🕐2024-09-16 20:17:05
│ └── 阿布鲁星人: 造数据库的材料,理论,语言都是完备的,你搞台2000块的电脑拉一条网线就能开搞,你搞不了只能说明你能力不行罢了 👍🏽0 💭新加坡 🕐2024-09-17 14:01:11
│ └── 越爷: 只会写数据库的农民工,我会从硬件到操作系统一条龙哦[惊喜] 👍🏽2 💭福建 🕐2024-12-04 13:19:40
│ └── 土豆雷进攻: 你的code在github吗,观摩一下,我很期待除了mysql之外能让大多数公司免费用的数据库。 👍🏽2 💭浙江 🕐2025-03-01 16:38:29
undefined: 我写了数据库,对照的缓存直接删除费那劲下次查询的时候,不就直接缓存上了嘛 👍🏽31 💭四川 🕐2023-05-07 20:57:47
│ └── xiusin: 他们考虑的是你删除后瞬间来了千亿并发[飙泪笑] 👍🏽0 💭河南 🕐2025-02-07 09:24:34
│ └── Tyler XIa: 有多少开发者连上千的并发都没经历过,但是考虑着上亿并发的事情[飙泪笑] 👍🏽3 💭浙江 🕐2025-02-07 15:48:30
六道轮回菠萝: 说的太对了,我一直就很疑惑,这有什么好纠结的,我写新数据之前直接把缓存删了不就完事了,我为什么要去更新缓存,你下一次查询走一次DB刷新缓存不就完了,国内这股八股之风,一些传播焦虑的公众号和培训机构功不可没 👍🏽18 💭四川 🕐2023-08-25 10:10:17
│ └── kimmking: 乱序还是会造成脏数据 👍🏽0 💭北京 🕐2023-10-25 23:56:13
│ │ └── 听酒歌: 更新做用并发标记处理还会乱序? 👍🏽0 💭浙江 🕐2023-10-28 09:48:41
│ └── 华华: 对于高频读写的数据,这样作缓存的效率就不高了 👍🏽0 💭广东 🕐2024-12-14 09:58:45
│ │ └── 六道轮回菠萝: 我们来算算,你删了redis缓存再去写数据,然后下次走一次DB存到redis里,这个过程是以ms计的,我们的QPS按秒计,一秒上千就不得了,除了那几个社交大厂之外只有某些活动才能达到这个QPS,如果只是特殊的活动,那么可以对redis做预热或者干脆延迟读,那么正常的QPS来说,按ms计的过程基本上可以忽略不计。所以效率怎么就不高了,人体对ms级别感知不到,但是你反复去对这种场景做优化反而会增加你开发的难度和维护难度 👍🏽7 💭四川 🕐2024-12-16 09:14:26
│ │ └── 喝水只和矿泉水: 先更新数据库再删redis不就完事了 👍🏽0 💭四川 🕐2025-01-17 10:46:37
│ └── 华华: 如果只是更新redis,而不是删除,即可少一次io 👍🏽0 💭广东 🕐2024-12-17 19:47:07
│ └── 未艾劈: 我一个写数据的逻辑,为什么要知道你一个读数据的cache逻辑。为了节省io,把逻辑都缠在一起可不好。 👍🏽1 💭加拿大 🕐2025-03-31 19:28:41
带带大师兄: 2020年刷八股,一大堆人写"延时双删方案的",关键还有面试官认可这种方案的。2023年再看,已经没人这么写了,再也没人问这个问题了。所以放心质疑,写八股的,问八股的,大部分都是糊弄下的 👍🏽17 💭广东 🕐2023-06-05 23:57:54
四月谷雨: 一致性是计算机领域一大难题,在各个层面都会遇到,确实很难,太纠结容易把自己陷进去[捂脸] 👍🏽17 💭湖北 🕐2023-06-01 09:22:55
│ └── 王华宁: 另一个难题是变量命名[好奇] 👍🏽5 💭上海 🕐2023-08-06 22:34:05
│ └── nefrixi: 确实,就是分布式和内存局部性下如何保持一致性问题,从底层CPU核心到上层服务器都是大麻烦,新手没必要深入。 👍🏽0 💭江西 🕐2025-04-02 10:59:56
遗迹: 其实就是卷的,再加上信息茧房,一群人抓住了一个点就卷到死,卷着卷着弄错了方向也没人在乎 👍🏽9 💭北京 🕐2023-06-08 01:52:10
kimmking: 这里的关键点并不是删或者改的问题,而是并发乱序造成的脏数据 👍🏽5 💭河南 🕐2023-04-30 09:22:07
│ └── 初秋: 用缓存了肯定会有一定程度的脏数据啊,况且还有网络延迟的存在,比如网页获取到数据,后台又改了,算脏数据吗?这种只要数据库层面能保证一致性就行了,搞很麻烦的一致性有意义吗?国内 redis 面试一直都是纠结这种一致性问题,却对 redis 的数据结构都不熟悉,用redis的方法也不过加个spring注解。说白了就是计算机基础都没学好,还非要去解决 p/np 👍🏽6 💭广东 🕐2023-04-30 11:12:17
│ └── kimmking: 题主这里讨论的场景是最大程度保证数据最终一致,比较交易场景的查询。有四种不一致一般要考虑。都有应用场景 👍🏽1 💭河南 🕐2023-04-30 15:16:30
│ └── 初秋: 哪四种?我找了下,没找到相关资料 👍🏽0 💭广东 🕐2023-04-30 15:49:45
│ │ └── 昆西昆西昆: 可能是他自己总结的业务场景,,,,也有可能是【数据库"缓存""一致"性的"四种"方案!-博客园】,希望不是后者吧 👍🏽6 💭上海 🕐2023-05-04 09:38:50
│ │ └── kimmking: 聪明如你。给你点个赞。我们团队20个人,花了一年做了一套缓存平台,所以了解这些,很多都是自己总结的。 👍🏽0 💭北京 🕐2023-05-05 12:01:11
│ │ └── 昆西昆西昆: 那跟我想的应该差不多,应该是在维护过程中通过真实的业务案例对业务进行分类,然后归纳总结出一套对应的缓存方案。开发前期用技术实现业务,后期维护通过业务场景优化技术方案,大家都是这么玩的 👍🏽3 💭上海 🕐2023-05-05 18:44:18
│ │ └── 知乎用户C5uPqr: 你自己总结的四种方案是通用的吗?有无分享学习一下?谢谢 👍🏽0 💭江苏 🕐2023-05-15 10:01:02
│ │ └── 阿biu: 有没有产出一些概述性的文档可以看看 👍🏽0 💭上海 🕐2023-07-12 10:00:59
│ └── 叫叮当的狸花猫: [捂脸][捂脸]先写数据库再更新缓存 先写数据库再删除缓存 区别能有多大?这两个方案极端点永远都会有不一致情况 国内八股走火入魔了 👍🏽13 💭江西 🕐2023-05-03 00:17:50
│ └── kimmking: 真实世界的场景千差万别,没人能代表”国内“。 👍🏽0 💭河南 🕐2023-05-03 21:32:50
│ └── 昆西昆西昆: 其实就是缓存失不失真的问题,失真就删,不失真就更新,懒得区分直接删也差不多 👍🏽1 💭上海 🕐2023-05-04 09:15:08
知乎用户YqvPPn: 我喜欢这个回答 👍🏽6 💭安徽 🕐2023-05-03 12:40:42
十二东: 对的,我去google上用英文搜,缓存雪崩啥的,根本搜索不到。搜索到的也是国内文章机翻过去了。 👍🏽6 💭上海 🕐2023-07-17 17:44:32
│ └── Momo: 同感, 所以问了这个问题 缓存穿透、击穿和雪崩术语的形成? 👍🏽3 💭中国香港 🕐2024-01-19 00:43:17
│ └── 风云劫: 这就是中国的程序员就业面试市场造就的,,生产环境里压根儿没有这些情况[捂脸]。。。 👍🏽1 💭浙江 🕐2024-10-19 20:25:13
│ │ └── Doneble: 缓存雪崩还是有可能的,我们人多[捂脸]铁路抢票场景国外也不适配 👍🏽0 💭北京 🕐2025-02-06 11:07:53
│ └── Hyperion: 有的,看看uber官方网站的系统设计,很经典 👍🏽3 💭北京 🕐2025-01-23 16:46:08
二饼下来: 严重同意 这种风气真的不知道怎么起来的 👍🏽5 💭上海 🕐2023-05-08 22:31:53
│ └── 佛山战螂: 阿里啊 👍🏽8 💭上海 🕐2023-05-08 23:25:00
│ └── 高息息: 阿里 👍🏽0 💭安徽 🕐2025-03-01 00:42:27
虾哔哔: 需要极致性能的压根就不会用数据库 👍🏽4 💭上海 🕐2023-05-23 10:43:12
buger: 话糙理不糙,哪有干干净净的数据?脏了整干净才能体现出价值 👍🏽4 💭广东 🕐2023-05-05 23:18:34
poltao: 哈哈哈,工作多年从来没遇到过这种情况,写就直接写 DB,流量高了就用消息队列限流,正经人谁搞这么复杂的方案[大笑] 👍🏽1 💭上海 🕐2024-11-07 10:46:34
好甜一块棠糕: 啊?这也能叫不友善啊?被答主说中的人心理是有多脆弱 👍🏽2 💭宁夏 🕐2023-11-25 10:18:42
韭菜: 也有可能是信息茧房了 👍🏽1 💭北京 🕐2023-05-04 11:58:13
Tyler XIa: 赞同。还有什么缓存穿透,雪崩之类的一大堆,这些场景确实客观存在,但是有多少人接触得到? 真的接触了压根就不会再问这些问题了。 天天写着用户数几千的系统,操着并发上亿的心。 👍🏽0 💭浙江 🕐2025-02-07 15:51:45
│ └── 因为不是我: 所以了解一下就好了,主要考察知识广度,知道出什么问题大概有什么方案可以选择,但一直往深了问,就真的很没必要了,除非招了就是进来处理类似问题的。其实就是卷,希望招的人经验能力尽可能强,有时候是面试官自己也不知道要问什么,总不能聊聊天吧,不过面得舒服的反而都是聊聊天,双方谈一些遇到的各种有趣的场景跟想到的方案和对策,反而更清楚是不是真才实学,不然很多都是背书 👍🏽0 💭福建 🕐2025-02-23 14:40:34
挥一挥手: 哈哈哈 都是被八股文洗脑的人。只要是双写就不可能没问题[捂脸] 👍🏽1 💭上海 🕐2024-10-02 12:22:38
HElyuM: 包括还有用redis当队列用的, 甚至于还有拿redis当分布式锁用的. 离了redis什么活也干不了是吧 👍🏽1 💭浙江 🕐2023-07-01 22:07:52
│ └── dddddd: redis做分布式锁不是很常见吗 👍🏽7 💭浙江 🕐2023-10-13 03:19:05
│ │ └── HElyuM: 这玩意不可靠, DDIA的作者专门写文章喷过redlock How to do distributed locking 只能用在无所谓可靠性的场景, 比如单纯上把锁减少服务争抢 👍🏽0 💭浙江 🕐2023-10-13 21:39:07
│ │ └── Momo: 都是取舍, etcd 性能根本不够用. 而且 redis 作者也发文回应过的 DDIA 的 👍🏽1 💭中国香港 🕐2024-01-19 00:51:11
│ │ └── HElyuM: 他的回应我看过了, 只能说从他的回复来看, antirez 看起来完全没有上过分布式系统相关的课程, 做了很多非常乐观的假设来论证不会出现死锁的情况 (例如强依赖系统时钟, 然而单机的本地时钟是完全不可靠的). 他当然是一个很棒的程序员, 水平也很高, 但是一码归一码, 在这个问题上真的很业余. 另外 Martin 也写了一篇对 antirez 回复的回复, 也很精彩. 分布式锁是个学术界研究了很久的话题了, 哪有 redlock 这么简单的算法就轻轻松松解决的事情. 👍🏽3 💭浙江 🕐2024-01-19 01:41:31
│ │ └── cqd: 用单机部署的redis做分布式锁,是否可行呢? 👍🏽0 💭浙江 🕐2024-02-24 20:57:54
│ │ └── HElyuM: 只是redis单机部署的话, 如果你能保证 redis 稳定性, 其实也没什么不好. 但是单机的话很容易有单点故障, 长期运行的程序几乎不可能完全不挂的. 他搞出redlock这种东西本来也是弥补单点故障的问题 👍🏽1 💭浙江 🕐2024-03-02 19:07:52
│ │ └── 朝天门: 是的[捂脸] 👍🏽0 💭浙江 🕐2024-03-02 22:21:50
│ └── AANDA: 那用什么组件做分布式锁比较优捏 👍🏽1 💭北京 🕐2023-10-31 19:12:41
│ │ └── HElyuM: etcd versus other key-value stores 👍🏽0 💭浙江 🕐2023-10-31 23:35:42
│ └── 而上: 当队列有什么问题么 👍🏽1 💭江苏 🕐2025-02-07 00:06:44
│ └── 因为不是我: 我们 15 年左右的时候拿来当队列也很好用啊[捂脸],其实用起来好用就好,很多极端情况那有那么容易遇到,遇到想办法解决,没有银弹的 👍🏽0 💭福建 🕐2025-02-23 14:36:16
旭雪: 在回答这个问题前要说明需要哪种一致性。 👍🏽1 💭浙江 🕐2023-05-05 00:07:11
北山: 在理 👍🏽0 💭上海 🕐2025-05-08 09:31:02
Koyomi: 我看八股也是教我写完数据库再删redis的,最多也就是延时再删一次,这还是四五年前的八股 👍🏽0 💭四川 🕐2025-04-01 10:56:29
屑站贵族在b乎: 强一致就上锁,不然其他都是扯淡,分段锁就好了呀,数据都是可分割的,请求算个hash,取模,然后分段锁。 👍🏽0 💭广东 🕐2025-03-31 10:11:34
我迪迦在东北: 好骂的 👍🏽0 💭河北 🕐2025-03-01 15:28:20
多喝冰水: 主要是很多水货趁着行业发展占了坑,当了面试官来问这种意义不大的问题,你回答不出来延迟双删和原理,他就认为你不行,没办法,时代发展的阵痛[惊喜] 👍🏽0 💭北京 🕐2025-02-22 18:28:37
行一: 你说得很对,但是面试就面这些Go东西[微笑] 👍🏽0 💭安徽 🕐2025-02-07 20:29:21
pixelstreamCN: 赞同的不能再赞同了[飙泪笑]。国内各种纠结点就是过度设计。之前面试甚至问到变量锁[飙泪笑](对一个变量到赋值上锁[飙泪笑])我特么无语了 👍🏽0 💭浙江 🕐2025-01-29 11:00:51
│ └── 初秋: 变量锁是什么?原子变量? 👍🏽0 💭广东 🕐2025-01-31 10:54:30
│ └── pixelstreamCN: 我当时也是这么理解的 反正没回答上 面试官也没给我答案。他跟我解释的意思大概是一个变量同时被2条指令修改如何确保这个变量最终值。整体上感觉面试官吧程序变量和内存取值套用redis的取值时间差的问题来考面试者。我自己没研究这么深不确定这个问题是否真的存在。 👍🏽0 💭浙江 🕐2025-01-31 11:58:06
快门民工: 哈哈哈哈哈看的我都满头问号,一堆人搁缓存上在那使劲[飙泪笑] 👍🏽0 💭山东 🕐2025-01-24 07:45:45
墨染流沙: 先更新数据库,再删缓存。各种方案你不用实践,仅从逻辑上来说就知道会有哪些问题,保证最终一致性就好了吧 👍🏽0 💭广东 🕐2025-01-22 11:41:10
喝水只和矿泉水: 一般先改数据库,再删redis. 要不然可能出现redis数据删了码上又有人查询数据库把旧数据填充到redis了。不过那些天天扯延时双删之类的都是八股文,99.99999%的场景都用不上 👍🏽0 💭四川 🕐2025-01-17 10:45:28
Inside: 补充一点,这些人纠结改缓存,是因为在系统中强依赖缓存,缓存中没数据会直接影响业务的可用性,其实根本原因还是菜,基于ACID数据库时给不出满足性能需要的架构设计,就靠redis续命强行提高性能,但又引入了一致性问题,总之就是菜,捉襟见肘活生生的体现。 👍🏽0 💭广西 🕐2024-12-06 09:39:43
Keep: 国外才多少流量额 👍🏽0 💭湖北 🕐2024-10-22 17:04:52
│ └── 大明第一深情: Facebook Twitter Youtube 全球人都在用,不比淘宝流量高? 👍🏽0 💭浙江 🕐2025-04-21 11:18:06