缓存由于其高性能,支持高并发的特性,在高并发的项目中不可或缺。被大家广泛使用的有Redis,Memcached等。本文主要探讨几种常见的缓存的读写模式,以及如何来保证缓存和数据库的数据一致性。

这里大家可以关注一下我的个人专栏《PHP进阶集中营》,每天会给大家即时分享一个最新的php技术资讯,有优秀的PHP技术内容,也欢迎分享在我的专栏。

PHP进阶集中营​zhuanlan.zhihu.com

Cache-Aside

Cache-Aside可能是项目中最常见的一种模式。它是一种控制逻辑都实现在应用程序中的模式。缓存不和数据库直接进行交互,而是由应用程序来同时和缓存以及数据库打交道。Cache-Aside的名字正体现了这个模式,Cache在应用的一旁(aside)。

读数据时

  1. 程序需要判断缓存中是否已经存在数据。
  2. 当缓存中已经存在数据(也就是缓存命中,cache hit),则直接从缓存中返回数据
  3. 当缓存中不存在数据(也就是缓存未命中,cache miss),则先从数据库里读取数据,并且存入缓存,然后返回数据

写数据时,我们可以有以下两种策略:

第一种策略:

  1. 更新数据库
  2. 更新缓存

但这种策略有线程安全的问题,可能出现缓存和数据库不一致。试想有两个写的线程,线程A和线程B

  1. A写数据库
  2. B后于A写数据库
  3. B写缓存
  4. A写缓存
  5. 缓存和数据库中的数据不一致,缓存中的是脏数据

要解决线程安全的问题,我们可以加锁,不过实现起来比较麻烦,因此我们不考虑这种写策略,而使用第二种策略。

第二种策略:

  1. 更新数据库
  2. 删除缓存中对应的数据

那么这种写策略会有线程安全的问题吗?有,试想一下有两个线程,线程A读,线程B写

  1. A读数据,由于未命中那么从数据库中取数据
  2. B写数据库
  3. B删除缓存
  4. A由于网络延迟比较慢,将脏数据写入缓存

但是这种情况可能性非常的小,需要同时满足很多条件,近乎不太可能发生,所以我们一般都采用这种写策略。另外可以对缓存中的数据设置合适的过期时间,即使发生的脏数据的情况,也不会发生很长时间。

应用场景

应用于缓存不支持Read-Through/Write-Through的系统。

优点

  • 缓存仅仅保存被请求的数据,属于懒加载模式(Lazy Loading),和下文的Write-Through模式相比,避免了任何数据都被写入缓存造成缓存频繁的更新。

缺点

  • 当发生缓存未命中的情况时,则会比较慢,因为要经过三个步骤:查询缓存,从数据库读取,写入缓存。
  • 复杂的逻辑都在应用程序中,如果实现微服务,多个微服务中会有重复的逻辑代码

Read-Through/Write-Through

这种模式中,应用程序将缓存作为主要的数据源,而数据库对于应用程序是透明的,更新数据库和从数据库的读取的任务都交给缓存来代理了,所以对于应用程序来说,简单很多。

Read-Through

由缓存配置一个读模块,它知道如何将数据库中的数据写入缓存。在数据被请求的时候,如果未命中,则将数据从数据库载入缓存。

Write-Through

缓存配置一个写模块,它知道如何将数据写入数据库。当应用要写入数据时,缓存会先存储数据,并调用写模块将数据写入数据库。

应用场景

Read Through/Write Through适用于写入之后经常被读取的应用。

优点

  • 缓存不存在脏数据
  • 相比较Cache-Aside懒加载模式,读取速度更高,因为较少因为缓存未命中而从数据库中查找
  • 应用程序的逻辑相对简单

缺点

  • 对于总是写入却很少被读取的应用,那么Write-Through会非常浪费性能,因为数据可能更改了很多次,却没有被读取,白白的每次都写入缓存造成写入延迟。

除了Write-Through以外,我们还有另外的两种写模式可以和Read-Through一起来配合使用,分别是Write-Back和Write-Around。

Write-Back

又叫做Write-Behind。和Write-Through写入的时机不同,Write-Back将缓存作为可靠的数据源,每次都只写入缓存,而写入数据库则采用异步的方式,比如当数据要被移除出缓存的时候再存储到数据库或者一段时间之后批量更新数据库。

应用场景

读写效率都非常好,写的时候因为异步存储到数据库,提升了写的效率,适用于读写密集的应用。

优点

  • 写入和读取数据都非常的快,因为都是从缓存中直接读取和写入。
  • 对于数据库不可用的情况有一定的容忍度,即使数据库暂时不可用,系统也整体可用,当数据库之后恢复的时候,再将数据写入数据库。

缺点

  • 有数据丢失的风险,如果缓存挂掉而数据没有及时写到数据库中,那么缓存中的有些数据将永久的丢失了

Write-Around

和Write-Through不同,更新的时候只写入数据库,不写入缓存,结合Read-Through或者Cache-Aside使用,只在缓存未命中的情况下写缓存。

应用场景

适合于只写入一次而很少被读取的应用。

优点

  • 相比较Write-Through写入的时候的效率较高,如果数据写入后很少被读取,缓存也不会被没用到的数据占满。

缺点

  • 如果数据会写入多次,那么可能存在缓存和数据库不一致

以上内容希望帮助到大家,很多PHPer在进阶的时候总会遇到一些问题和瓶颈,业务代码写多了没有方向感,不知道该从那里入手去提升,对此我整理了一些资料,包括但不限于:分布式架构、高可扩展、高性能、高并发、服务器性能调优、TP6,laravel,YII2,Redis,Swoole、Swoft、Kafka、Mysql优化、shell脚本、Docker、微服务、Nginx等多个知识点高级进阶干货需要的可以免费分享给大家,需要点击

net.conn read 判断数据读取完毕_高并发:缓存模式以及缓存的数据一致性相关推荐

  1. net.conn read 判断数据读取完毕_单方验方|如何应对千万级工商数据抓取(一)

    最近主要在处理有关企业信用的工商数据库,朋友列出的名单在200万家上下,字段共有13个维度,数据规模粗略计算好几千万了.起初自己懵懵懂懂的爬了200万,经过不断调试改进,发现大规模抓取数据门门道道还真 ...

  2. net.conn read 判断数据读取完毕_1.5 read, write, exit系统调用

    接下来,我将讨论对于应用程序来说,系统调用长成什么样.因为系统调用是操作系统提供的服务的接口,所以系统调用长什么样,应用程序期望从系统调用得到什么返回,系统调用是怎么工作的,这些还是挺重要的.你会在第 ...

  3. 高并发处理方案_高并发系统下的缓存解决方案

    什么样的数据适合做缓存? 缓存和DB数据一致性在之前已讲过,详细可参考下面阅读推荐<如何保障mysql和redis之间的数据一致性>,我们这里讲一讲缓存穿透.缓存雪崩和击穿的三种场景解决方 ...

  4. Java架构师,大数据架构师,高并发设计模式,机器学习知识点分享

    第一章:java精品课程目录大全 1.亿级流量电商详情页系统的大型高并发与高可用缓存架构实战 1课程介绍以及高并发高可用复杂系统中的缓存架构有哪些东西?32分钟 2基于大型电商网站中的商品详情页系统贯 ...

  5. 筛选平台数据包丢弃_高并发电商平台设计

    作者:Newway 1.概述 Legendshop B2B2C电商平台具有大用户量.大业务量和高并发的特点.常规条件下,大数据量将使B2B2C电商平台性能下降,系统响应速度变慢.而对电子商务网站,用户 ...

  6. java内存分配模型优点_高并发实战(二)-并发基础 缓存 MESI 内存模型

    左图为高速缓存 右图为多级缓存 数据的读取和存储都经过高速缓存,CPU核心与高速缓存有一条特殊的快速通道.主存与高速缓存都是连接在系统总线上,当然其他组件也是在此基础上进行通信的. 在高速缓存出现后不 ...

  7. libevent c++高并发网络编程_高并发编程学习(2)——线程通信详解

    前序文章 高并发编程学习(1)--并发基础 - https://www.wmyskxz.com/2019/11/26/gao-bing-fa-bian-cheng-xue-xi-1-bing-fa-j ...

  8. java设计模式并发_[高并发Java 七] 并发设计模式

    [高并发Java 七] 并发设计模式 [高并发Java 七] 并发设计模式 为什么80%的码农都做不了架构师?>>> 在软件工程中,设计模式(design pattern)是对软件设 ...

  9. mysql并发量_高并发秒杀系统架构解密,不是所有的秒杀都是秒杀!

    推荐阅读: 学会这些微服务+Tomcat+NGINX+MySQL+Redis,再去面试阿里P7岗吧 "火爆"的微服务架构你还不会?从基础到原理的PDF文档快来学! Nginx负载均 ...

最新文章

  1. BZOJ-1854-[Scoi2010]游戏(并查集)
  2. (转)轻量级 UML 建模工具JUDE 介绍(二)
  3. 前端那么多框架,我们到底学哪一个
  4. [导入]关于复制目录架构
  5. SSH登录太慢(等很久才提示输入密码)的问题
  6. Windows server2008 搭建ASP接口訪问连接oracle数据库全过程记录
  7. (Python)Pandas reset_index()用法总结
  8. 设计模式之-生成器模式
  9. matlab 阶乘函数
  10. 松本行弘的程序世界读书笔记
  11. HTML5-坦克大战一完成坦克上下左右移动的功能(一)
  12. echarts实现各省市地图、中国地图
  13. ssm毕设项目酒店管理系统08281(java+VUE+Mybatis+Maven+Mysql+sprnig)
  14. 2020-08-21
  15. 对话美团 CEO 王兴:太多人关注边界,而不关注核心
  16. 随手记获2亿美元C轮融资,随手记投资安全吗?
  17. OpenCV-Python (官方)中文教程(部分二)
  18. HTML基础知识汇总
  19. 浅谈一下:运营网站的一些经历和故事
  20. anaconda 创建虚拟环境报错

热门文章

  1. ORA-12514: TNS:监听程序当前无法识别连接描述符中请(转)
  2. 话里话外: 信息化与高层参与度的关系
  3. 如何使用js动态显示或隐藏DIV
  4. http协议工作流程
  5. 什么是数据的完整性约束
  6. ipv4到ipv6的过渡
  7. scrapy框架异常--no more duplicates will be shown (see DUPEFILTER_DEBUG to show all duplicates)
  8. jstl处理栏目与子栏目_芬顿氧化法废水处理工程技术规范(征求意见稿)
  9. html中通过点击button标签实现页面跳转的三种方法
  10. sprintf用法详解