新人想了一个晚上,是先操作数据库,还是先操作缓存
java吧
全部回复
仅看楼主
level 6
假设一个业务背景
目前,某东商家有30W+,为了尽可能的更新上架新商品,这些商家会进行频繁页面操作。经统计,在所有的页面操作中,定时发布(立即发布)是深受商家喜爱的经典操作,特别是大促一结束,商家会进行高并发的发布操作,如在2020.11.12的0点,大量的商家就迫不及待的开始下架活动页面,并更新为常规页,这一波骚操作QPS竟高达2W。那么在如此高的并发下,如何让发布操作更加优雅,CPU利用率并不会因商家数量的增长而线性增长,满足商家骚操作『又快又稳』,这是值得思考的一个话题。
一个方法:先删除缓存然后操作数据库。立即发布,所谓立即发布,即是秒级甚至毫秒级的范围内看到效果。为了满足高并发的写操作,显然不能直接操作mysql等数据库,最直观的感受就是找一个替代品(即写的tps高一点的中件间),redis当仁不让。方案其实也挺简单,相关的操作优先于redis操作,然后通知消息队列更新到mysql。
但是我们先删除缓存,再更新数据库,又会出现以下问题:就是在并发情况下删除缓存后,立刻读库,此时库数据还没更新,读到了老数据,又写入了缓存,导致以后所有人读到都是缓存中错误数据。
这就是为什么一般先更新数据库,再删除缓存:存在主要问题是,更新数据库后,还没删除缓存,导致部分人读到了缓存中老数据,当缓存删除后,就可以从数据库读取正确数据,缓存也就正确,以后大部分人读到正确数据。
所以正常的操作应该是怎样,新人学java半年,不知道如何解决。
2023年11月16日 12点11分 1
level 6
我们都是cache aside pattern 也就是先写库再删缓存。我好奇为什么不用redis的缓存机制
2023年11月16日 13点11分 2
level 10
mq啊 不然只能延迟双删 sleep(1) 不然都会有不一致
2023年11月16日 13点11分 3
什么意思。细说下,是mq,还是延迟双删。像这种大量查+大量改的数据情景。
2023年11月16日 14点11分
level 6
【精选】高并发的写操作如何对数据库释压_如何解决高频写入给数据库带来巨大压力-CSDN博客
这个是原博客
2023年11月16日 13点11分 4
level 6
都说缓存的前提是查多写少,但是我就只有那一段高峰的时间是写也多呢?
2023年11月16日 13点11分 5
level 13
用消息队列
2023年11月16日 14点11分 6
怎么用 说一下
2023年11月16日 14点11分
level 1
m
2023年11月16日 14点11分 7
level 1
发布这种状态值更改,不存在资源争夺问题,改库再改缓存,差不了多少时间,商品多就分表分库,或者用nosql,麻烦的是秒杀活动这种,对库存这一数据的争抢,需要用锁和队列处理,写非常慢,但依然是改库再改缓存,12306不就让你排队了吗
2023年11月16日 14点11分 8
level 10
如果严格限制问题是定时发布和更新页面信息的话,将改为旧页面条件视为商品链接不能变更这一条件,那么可以考虑存旧商品信息,新商品信息和更替时间。在后端代码根据时间条件判断改返回哪种信息,这样就可以直接避免高并发问题,之后怎么处理旧数据就看你自己慢慢来了。
2023年11月16日 15点11分 9
level 1
我们是先操作缓存(redis集群),同时往队列里丢一个信息,慢慢持久化
2023年11月16日 15点11分 10
level 1
延迟双删够用了,具体百度一下原理吧,就是先操作数据库,然后删除缓存,然后再提交一个删除操作到队列里,过几秒钟后再删除一次
2023年11月16日 15点11分 11
这个逆天方案实际开发中没什么人用的 延迟双删
2023年11月17日 19点11分
@低俗獠牙 除了一些超高并发的查询修改(一般是抢购,抢票场景),其他基本不会遇到因为修改导致的缓存不一致,要看业务场景的,不是会了就无脑用[捂嘴笑]
2023年11月18日 06点11分
level 8
写数据肯定先写库啊,直接删缓存再写库
2023年11月16日 17点11分 13
level 11
真实场景怎么可能真的删MySQL库,都是改一个SKU状态字段为不可用,20000个SKU分布在不同物理机的集群上根本没有性能瓶颈,MQ发送SKU失效消息就行了,用户一直待在商品详情页也不怕,下订单的时候你没看过转圈吗?那就是在二次确认,下单成功订单就有效,指定时间内不付款订单取消
2023年11月16日 19点11分 14
level 1
超大型网站和中小型网站即使业务模型一样,为了应对性能问题肯定要特化设计。
2023年11月17日 00点11分 16
1 2 尾页