当前位置: 首页 > news >正文

青海省建设局网站首页设计网站推荐理由

青海省建设局网站首页,设计网站推荐理由,游戏网站 模板,网站建设的一般步骤目录 1、数据不一致的原因 1.1 并发操作 1.2 非原子操作 1.3 数据库主从同步延迟 2、数据不一致的解决方案 2.1 并发操作 2.2 非原子操作 2.3 主从同步延迟 2.4 最终方案 3、不同场景下的特殊考虑 3.1 读多写少的场景 3.2 读少写多的场景 1、数据不一致的原因 导致…

目录

1、数据不一致的原因

1.1 并发操作

1.2 非原子操作

1.3 数据库主从同步延迟

2、数据不一致的解决方案

2.1 并发操作

2.2 非原子操作

2.3 主从同步延迟

2.4 最终方案

3、不同场景下的特殊考虑

3.1 读多写少的场景

3.2 读少写多的场景


1、数据不一致的原因

导致缓存和数据库数据不一致的原因有三个

  • 并发操作
  • 非原子操作
  • 数据库主从同步延迟

1.1 并发操作

假设数据库的原数据为x=0,考虑两种并发情况

  • 两个线程同时写入
  • 一个线程读,一个线程写

有以下4种方案

  • 先更新缓存,后更新数据库
  • 先更新数据库,后更新缓存
  • 先删除缓存,再更新数据库
  • 先更新数据库,再删除缓存

(1)先更新缓存,后更新数据库

两个线程同时写入

  • A更新缓存,x=1
  • B更新缓存,x=2
  • B更新数据库,x=2
  • A更新数据库,x=1

最终缓存为2,数据库为1

一个线程读,一个线程写

  • A读取缓存发现没有命中,于是读取数据库,得到x=0
  • B更新缓存,x=1
  • B更新数据库,x=1
  • A更新缓存,x=0

最终缓存为0,数据库为1

这种情况发生的概率极小,需要同时满足几个条件

  • 第一,缓存不存在
  • 第二,A的更新缓存命令 后于 B的更新缓存命令(基本不可能发生)
  • 第三,A读取数据库+更新缓存的时间 > B更新缓存+B更新数据库的时间(基本不可能发生,因为写数据库的耗时大概率是比读数据库慢)

(2)先更新数据库,后更新缓存

两个线程同时写入

  • A更新数据库,x=2
  • B更新数据库,x=1
  • B更新缓存,x=1
  • A更新缓存,x=2

最终缓存为2,数据库为1

一个线程读,一个线程写

  • A读取缓存发现没有命中,于是读取数据库,得到x=0
  • B更新数据库,x=1
  • B更新缓存,x=1
  • A更新缓存,x=0

最终缓存为0,数据库为1

这种情况发生的概率也是极小,跟方案2的发生条件一样。

(3)先删除缓存,再更新数据库

两个线程同时写入

由于是删除缓存,多线程同时更新的话,缓存都是会被删除,没有讨论意义

一个线程读,一个线程写

  • A读取缓存发现没有命中,于是读取数据库,得到x=0
  • B删除缓存
  • A更新缓存,x=0
  • B更新数据库,x=1

最终,缓存是0,数据库是1

(4)先更新数据库,再删除缓存

两个线程同时写入

由于是删除缓存,多线程同时更新的话,缓存都是会被删除,没有讨论意义

一个线程读,一个线程写

  • A读取缓存发现没有命中,于是读取数据库,得到x=0
  • B更新数据库,x=1
  • B删除缓存
  • A更新缓存,x=0

最终,缓存是0,数据库是1

这种情况发生的概率也是极小,需要同时满足几个条件

  • 第一,缓存不存在
  • 第二,B更新数据库+删除缓存的时间 < A读取数据库+更新缓存的时间 (基本不可能发生,因为写数据库的耗时大概率是比读数据库慢)

1.2 非原子操作

非原子操作很好理解,就是因为操作缓存和操作数据库是两步操作,所以当第二步操作失败时,就会导致数据不一致问题。

1.3 数据库主从同步延迟

以上都只考虑了单机数据库的情况,对于主从数据库还有另一个问题,就是主从同步延迟

考虑以下情况

一个往主库写入,一个从从库读取

  • A更新主库,x=1
  • A删除缓存
  • B查询缓存没有命中,查询从库,得到x=0
  • 从库同步主库,更新为x=1
  • B更新缓存,x=0

最终,缓存是0,数据库是1

2、数据不一致的解决方案

2.1 并发操作

根据1.1的几种方案,『先更新数据库,再删除缓存』是最好的。

2.2 非原子操作

最简单的解决办法就是重试,但是重试也要考虑一些问题:

  • 立即重试的话大概率会失败;
  • 重试次数设置多少比较合适;
  • 同步重试会一直占用资源;
  • 重试的过程中服务重启,会导致重试的操作消失,数据会一直不一致

所以就能想到异步重试方法,也就是把重试的这个操作写入到消息队列里,由另一个线程专门来处理重试的操作,而且消息队列本身可以保证消息不丢失(不丢失有两个方面,一是消息持久化,二是只有正确被消费掉了才会删除)

除了消息队列这中异步重试方案外,业界还有一种监听数据库bin log的方式,监听到变化后再去操作缓存,但是这种会额外引入其他的中间件而且实现复杂,综合而言没有消息队列的方案好用。

2.3 主从同步延迟

主从同步延迟的解决方案也很明显,就是延迟删除缓存,但是延迟多久再执行删除呢?这个就要靠经验了,一般来说1~5秒不等,看具体业务

所以在之前方案的基础上,引入延迟删除可以解决主从同步延迟的问题。

2.4 最终方案

1)更新数据库

2)删除缓存

3)如果删除失败则额外写入一条重试删除命令到消息队列

4)最后写入一个延迟删除命令到消息队列

3、不同场景下的特殊考虑

3.1 读多写少的场景

这种场景下,redis的作用是为了减轻数据库读取压力、加速读取,往往能接受一定的数据延迟,即保证最终一致性即可。

  • 读多,所以删除缓存操作会导致缓存穿透问题(key不存在,大量请求命中数据库)
  • 写少,所以基本不存在并发写入的问题,但是会存在并发读取和写入的问题

所以,读多写少的场景下,方案3和4是容易出现大问题的。

方案1和方案2是相对能接受的,但是也会有一定概率存在并发写入导致数据不一致的问题。

此时我们可以通过给缓存设置过期时间,使得数据保证最终一致性。

3.2 读少写多的场景

这种场景下,redis的作用是为了减轻数据库写入压力,对数据的一致性要求较高。

  • 读少,所以并发读取和写入的情况比较少
  • 写多,所以并发写入的情况比较多

由于并发写入情况比较多,此时方案3和4比较好,根据上文的分析,方案4比方案3更好。

http://www.yayakq.cn/news/121346/

相关文章:

  • 网站建设2000元qt 网站开发
  • 国外网站顶部菜单设计上海公司注册代理公司注册
  • 网站发布与推广广东建设工程信息网站6
  • 网站建设的技术保证怎么写项目网络图怎么绘制
  • 网站开发语言选择河北省网络科技网站
  • 哪些网站会盗取门户网站建设流程
  • 爱看视频的网站wordpress小工具最近评论
  • 网站的推广上海外贸企业
  • 重庆seo网站推广工具网络公司怎样推广网站
  • 临汾网站建设价格手机软件推广平台
  • 出版社网站建设方案视频下载网站免费
  • 网站自定义代码网站做好了怎么上线
  • 希音电商网站开发app流程
  • 网站建设培训目标中国空间站对接成功
  • 做纺织的用什么网站做钻石资讯网站
  • wordpress在线问答插件沧州网站seo公司
  • 上海网站建设过程基金会网站建设
  • 苗木企业网站建设源代码 园林网站源码程序 苗圃花卉网站制作源码做网站 赚钱多吗
  • asp钓鱼网站开发广州越秀区二手房
  • 百斯特网站建设asp 开发的大型网站
  • 网站改版建设征求意见书新手怎么做淘宝店铺
  • 网站备案流程app怎么推广
  • 大气门户网站青岛广新信建设咨询公司网站
  • 锡盟建设工程网站企业网站流量怎么做
  • 丹阳建站推广管理网页设计培训学校
  • 吉林品牌网站建设商家wordpress企业免费主题
  • 网站打开是目录结构图村庄建设网站
  • 钟表网站模板牟长青 做网站推广的四个基本要点
  • 摄影网站首页设计网站推广软文
  • 北京企业网站推广价格网站建设的项目亮点怎么写