后台系统可扩展性学习笔记(十三)缓存

文章目录

  • 在哪儿加缓存
  • 缓存什么内容
    • 缓存原始查库结果
    • 缓存数据对象
  • 怎么查询缓存结果
    • 预留缓存模式
    • 直读模式
    • 直写模式
    • 回写式缓存
    • 绕写式缓存
    • 提前刷新模式
  • 缓存满了如何处理
  • 参考

读写分离、分库分表、反范式化、采用 NoSQL……如果这些扩展手段全都上了,数据响应依旧越来越慢,还有什么解决办法吗?
有,加缓存。 利用缓存层来吸收不均匀的负载和流量高峰

在哪儿加缓存

理论上,在数据层之前的任意一层加缓存都能够阻挡流量,减少最终抵达数据库的操作请求:
在这里插入图片描述
按缓存所处位置分为 4 种:

  • 客户端缓存:包括HTTP 缓存、浏览器缓存等
  • Web 缓存:例如CDN、反向代理服务等
  • 应用层缓存:例如Memcached、Redis等键值存储
  • 数据库缓存:一些数据库提供了内置的缓存支持,比如查询缓存(query cache)

为了减轻数据库的负载,我们在应用程序和数据存储之间加个键值存储作为缓冲层:通过内存中缓存的数据来响应一部分请求,而不必实际执行查库操作,从而提升数据响应速度。

缓存什么内容

  • Cached Database Queries:缓存原始查库结果
  • Cached Objects:缓存应用程序中的数据模型,比如重新组装过的数据集,或者整个数据模型类实例

缓存原始查库结果

根据查询语句生成key,将查库结果缓存起来,例如:

key = "user.%s" % user_id
user_blob = memcache.get(key)
if user_blob is None:user = mysql.query("SELECT * FROM users WHERE user_id=\"%s\"", user_id)if user:memcache.set(key, json.dumps(user))return user
else:return json.loads(user_blob)

这种模式的主要缺陷在于难以处理缓存过期,因为数据与key(即查询语句)之间并没有明确的关联,数据发生变化后,很难精确地删掉缓存中的所有相关条目。试想,一个单元格发生变化,会影响哪些查询语句?
尽管如此,这仍然是最常用的缓存模式,因为可以做出妥协,比如:

  • 只缓存与查询语句有直接关联的数据,排序、统计、筛选之类的计算结果统统都不存了
  • 不求精确,把所有可能受影响的缓存条目都删掉

缓存数据对象

另一种思路是将应用程序中的数据模型对象缓存起来,这样原始数据与缓存之间就有了逻辑关联,从而轻松解决缓存更新的难题。
无论数据是如何查询,如何加工转换的,只把最终得到的数据模型对象缓存起来,原始数据发生变化时,直接把相应的数据对象整个移除。对应用程序而言,数据对象比原始数据更容易管理和维护,因此,建议缓存数据对象,而不是原始数据。

怎么查询缓存结果

常见的缓存数据访问策略有 6 种:

  • Cache-aside/Lazy loading:预留缓存
  • Read-through:直读式
  • Write-through:直写式
  • Write-behind/Write-back:回写式
  • Write-around:绕写式
  • Refresh-ahead:刷新式

预留缓存模式

在这里插入图片描述
数据请求优先走缓存,未命中缓存时才查库,并把结果缓存起来,所以缓存是按需的(Lazy loading),只有实际访问过的数据才会被缓存起来。缓存与数据库之间没有直接关系(缓存位于一旁,所以叫 Cache-aside),由应用程序将需要的数据从数据库中读出并填充到缓存中。
主要问题在于:

  • 未命中缓存时需要 3 步,延迟不容忽视(对于冷启动可以手动预热)
  • 缓存可能会变旧(一般通过设置 TTL 来强制更新)

直读模式

在这里插入图片描述
直读模式下,缓存挡在数据库之前,应用程序不与数据库直接交互,而是直接从缓存中读取数据。
未命中缓存时,由缓存负责查库,并自己缓存起来。与预留缓存唯一的区别在于查库的工作由缓存来完成,而不是应用程序。

直写模式

在这里插入图片描述
类似于直读模式,缓存也挡在数据库之前,数据先写到缓存,再写入数据库。
也就是说,所有写操作必须先经过缓存。
一般与直读式缓存相结合,虽然写操作多过一层缓存(存在额外的延迟),但保证了缓存数据的一致性(避免缓存变旧)。此时,缓存就像数据库的代理,读写都走缓存,缓存再查库或将写操作同步到数据库。

回写式缓存

在这里插入图片描述
与直写式唯一的区别在于异步写入数据库,进而允许批处理以及写操作合并。同样能够与直读式缓存结合使用,而且不存在直写式中写操作的性能问题,但仅保证最终一致性。

绕写式缓存

所谓绕写式缓存就是写操作不经过(绕过)缓存,由应用程序直接写入数据库,仅缓存读操作。可与预留缓存或直读缓存结合使用:
在这里插入图片描述

提前刷新模式

在这里插入图片描述
提前刷新,在缓存过期之前,自动刷新(重新加载)最近访问过的条目。甚至可以通过预加载来减少延迟,但如果预测不准反而会导致性能下降。

缓存满了如何处理

当然,缓存空间是极其有限的,所以还要有逐出策略(Eviction Policy),从缓存中剔除一些不太可能用到的条目,常用策略如下:

  • LRU(Least Recently Used):最常用的一种策略,根据程序运行时的局部性原理,在一段时间内,大概率访问相同的数据,所以将最近没有用到的数据剔除出去
  • LFU(Least Frequently Used):根据使用频率,将最不常用的数据剔除出去
  • MRU(Most Recently Used):在有些场景下,需要删掉最近用过的条目
  • FIFO(First In, First Out):先进先出,剔除最早访问过的数据

参考

http://www.ayqy.net/blog/caching/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/376564.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

后台系统可扩展性学习笔记(十四)异步机制与MQ

对于 Web 服务而言,提升可扩展性的主要途径是将耗时的同步工作改成异步处理,从而允许将这些工作“外包”给多个 Worker 去做,或者提前完成能够预知的部分。 异步机制与可扩展性之间的关系需要从(异步)并行处理的优势说…

光标闪烁问题的解决办法

在调用Windows API函数SetCursor设置光标时,可能会碰到闪烁的问题:移动鼠标,光标在Class Cursor(即注册窗口类时指定的Cursor)与预设Cursor之间闪烁。 在MSDN上有关SetCursor函数的备注中强调,如果Class Cursor非空,那…

视频编解码基础

文章目录前戏编解码技术流程主流视频编码标准视频传输面临的问题视频传输差错控制视频传输Qos质量保证参数人类视觉系统HVS 以及相应编码措施正餐编码层次与码流结构PB帧编码IBBP序列编码结构图像编码结构条带编码结构宏块编码结构块编码结构预测技术码率控制实例H264前戏 编解…

实时语音通讯丢包补偿技术

文章目录基于发送端丢包补偿技术原理与媒体无关的前向差错纠正媒体相关前向差错纠正交织技术基于接受端丢包补偿技术基于插入方法基于插值方法基于重构的方法应用建议非交互式交互式拓展阅读参考丢包补偿技术可以分为两类:基于发送端补偿、基于接受端补偿 基于发送…

关于并发概念的一些笔记

目录1、基于锁的并发数据结构1、并发计数器2、懒惰计数器3、并发链表4、并发队列5、并发散列表总结2、条件变量使用(POSIX)生产者/消费者 (有界缓冲区问题)覆盖条件扩展3、信号量使用二值信号量(锁)0值信号…

对于线程并发模型与事件并发模型的思考

这里将以对话的形式进行: A: 普通的线程是可以被其他线程中断掉的,而基于select、epoll的事件处理函数实际上是不可以被其他事件(线程)中断的。 我这个理解对吗? B: 图片里的应该是对是否…

Ubuntu 14.10 -- 异次元软件世界

Ubuntu 14.10 中文桌面版/服务器正式版下载 - 华丽免费易于入门的 Linux 操作系统 [ 系统工具 - Linux // 2014-10-25 ]一说到 Linux,就不得不提目前最红火的 Ubuntu 发行版了!它拥有绚丽的界面,甚至跟以时尚为卖点的 Mac OSX 相比也有过之而…

System Design笔记:在线售票系统设计

文章目录何为在线售票系统?系统目标和要求1、功能要求2、非功能性需求3、设计注意事项4、容量估算5、系统API1.SearchMovies2.ReserveSeats6、数据库设计7、高级设计8、细节模块设计9、流程服务器如何跟踪所有尚未预订的active预订?服务器如何跟踪所有等…

流媒体协议初探(MPEG2-TS、RTSP、RTP、RTCP、SDP、RTMP、HLS、HDS、HSS、MPEG-DASH)

目录一、综述需求分析协议定制二、MPEG2-TS协议三、RTSP协议、RTP、RTCP、SDPRTSPRTP、RTCP、SDP四、RTMP五、HLS、HDS、HSSHLSHDS和HSS六、MPEG-DASH协议具体内容应用七、流媒体服务器流媒体服务器的功能与挑战客户端支持协议支持应用场景应用特点扩展技术广告投放录屏其他一、…

eclipse偶尔会反映迟钝,直接无视其报错

比如,你在web.xml中配置了什么东西,在有的时候不一定就会立即被eclipse察觉到,即便你的配置正确了,甚至重启了几次服务器,它仍然给你报错 比如说,刚才我在web.xml中配置了一个taglib,并且tld文件…

Qos(Quality of Service)

QOS(即Quality of Service,服务质量)主要指网络环境下服务满足用户的程度,在视频服务的语境下也可认为是Quality of Streaming,即流媒体服务的质量。通常,QOS可以由一系列指标表达,如传输的速度…

Popline:帅气的浮动 HTML5 文本编辑器工具栏

Popline 是一个基于 HTML5 实现的富文本编辑器工具栏,设计灵感来自 PopClip ,相比传统的文本编辑器工具,Popline 能够浮动在编辑的文本周围,操作起来十分方便。 您可能感兴趣的相关文章Metronic – 基于 Bootstrap 响应式后台管理…

流媒体技术优化

文章目录1、下载策略优化CDN选择策略错误处理策略码率选择策略2、协议和架构优化HTTP2TCP变种拥塞控制QUIC架构流媒体协议的选择与分发体系架构的设计对优化起着关键作用。 HLS和DASH协议在点播和OTT直播服务中已逐渐占据主流,其思想主要是将视频转为不同码率并切为…

API设计笔记:pimpl技巧

pimpl pointer to implementation:指向实现的指针,使用该技巧可以避免在头文件暴露私有细节,可以促进API接口和实现保持完全分离。 Pimpl可以将类的数据成员定义为指向某个已经声明过的类型的指针,这里的类型仅仅作为名字引入&am…

《设计模式》-责任链模式

责任链模式是一种对象的行为模式【GOF95】。在责任链模式里,很多对象由每一个对象对其下家的用而链起来形成一条链,请求在这个链上传递,直到链上的某一个对象决定处理此请求。 发出请求的客户端并不知道链上的哪一个对象终处理这个请求&#…

【机器学习】EM最大期望算法

EM, ExpectationMaximization Algorithm, 期望最大化算法。一种迭代算法,用于含有隐变量(hidden variable)的概率参数模型的最大似然估计或极大后验概率估计,其概率模型依赖于无法观测的隐变量。 经常用在ML与计算机视觉的数据聚类领域。 EM应用&#xf…

做一个给自己手机免费发送“天气预报”信息的软件

实现一个以下截图这样的功能!没错,就是你手机可以收到“免费”的天气预报短信! 一、在做之前必须了解以下四个功能: 1、WebService 2、Quartz.Net(定时任务框架) 3、SMTP:简单邮件传输协议,它是…

Android_Chronometer计时器

最近做一个项目用到Handler 和Message ,开始时不是很明白,不了解其中的内部机制,所以开发起来有点难度,之后自己找了Android 时间服务 这一节的内容,总结了一点关于时间的知识,在这里大概写一下&#xff0c…

置顶 | wolai博客

最近用wolai记录笔记较多,这里放一下我wolai的地址,当然csdn这边也会同时更文。 hanhan的博客

为你的程序添加监听器

平时在写程序时经常会遇到监听器,比如按钮的click监听器,按键监听器等等。而android中的监听器和java中的回调函数是同一个概念,都是在底层代码中定义一个接口来调用高层的代码。那么什么是回调函数呢?网上说的是“在WINDOWS中&am…