前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >缓存小结(一)

缓存小结(一)

作者头像
WindCoder
发布2020-01-21 10:34:33
4110
发布2020-01-21 10:34:33
举报
文章被收录于专栏:WindCoderWindCoder

何为缓存

缓存,是一种存储数据的组件,它的作用是让对数据的请求更快地返回,是一种常见的空间换时间的性能优化手段。

缓存不仅是指内存,凡是位于速度相差较大的两种硬件之间,用于协调两者数据传输速度差异的结构,均可称之为缓存。

缓存实例

TLB(Translation Lookaside Buffer)

计算机系统中常会借助一个叫做 TLB(Translation Lookaside Buffer)的组件来缓存最近转换过的虚拟地址和物理地址的映射,从而加快地址转换的速度。

TLB 就是一种缓存组件,缓存复杂运算的结果。

视频播放

视频平台上的短视频实际上是使用内置的网络播放器来完成的。网络播放器接收的是数据流,将数据下载下来之后经过分离音视频流,解码等流程后输出到外设设备上播放。

播放器中通常会设计一些缓存的组件,在未打开视频时缓存一部分视频数据,比如打开视频时,服务端可能一次会返回三个视频信息,我们在播放第一个视频的时候,播放器已经帮我们缓存了第二、三个视频的部分数据,这样在看第二个视频的时候就可以给用户“秒开”的感觉。

HTTP协议缓存

  • 当第一次请求静态的资源时,比如一张图片,服务端除了返回图片信息,在响应头里面还有一个“Etag”的字段。浏览器会缓存图片信息以及这个字段的值。
  • 当下一次再请求这个图片的时候,浏览器发起的请求头里面会有一个“If-None-Match”的字段,并且把缓存的“Etag”的值写进去发给服务端。
  • 服务端比对图片信息是否有变化,如果没有,则返回浏览器一个 304 的状态码,浏览器会继续使用缓存的图片信息。
  • 通过这种缓存协商的方式,可以减少网络传输的数据大小,从而提升页面展示的性能。

缓存与缓冲区

  • 缓存不仅是一种组件的名字,更是一种设计思想。可以提高低速设备的访问速度,或者减少复杂耗时的计算带来的性能问题
  • 缓冲区则是一块临时存储数据的区域,这些数据后面会被传输到其他设备上。用以弥补高速设备和低速设备通信时的速度差。

任何能够加速读请求的组件和设计方案都是缓存思想的体现。而这种加速通常是通过两种方式来实现:

  • 使用更快的介质
  • 缓存复杂运算的结果

缓存分类

日常开发中,常见的缓存主要就是 静态缓存分布式缓存热点本地缓存这三种。

静态缓存处在负载均衡层,分布式缓存处在应用层和数据库层之间,本地缓存处在应用层。我们需要将请求尽量挡在上层,因为越往下层,对于并发的承受能力越差。

缓存命中率是我们对于缓存最重要的一个监控项,越是热点的数据,缓存的命中率就越高。

静态缓存

静态缓存在 Web 1.0 时期是非常著名的,它一般通过生成 Velocity 模板或者静态 HTML 文件来实现静态缓存,在 Nginx 上部署静态缓存可以减少对于后台应用服务器的压力。

这种缓存仅能针对静态数据,面对动态数据无能为力。

分布式缓存

Memcached、Redis 是分布式缓存的典型例子。它们性能强劲,通过一些分布式的方案组成集群可以突破单机的限制。所以在整体架构中,分布式缓存承担着非常重要的角色。

热点本地缓存

热点本地缓存主要部署在应用服务器的代码中,用于阻挡热点查询对于分布式缓存节点或者数据库的压力。当遇到极端的热点数据查询的时候,可以在代码中使用一些本地缓存方案,如 HashMap,Guava Cache 或者是 Ehcache 等。

由于本地缓存是部署在应用服务器中,而我们应用服务器通常会部署多台,当数据更新时,我们不能确定哪台服务器本地中了缓存,更新或者删除所有服务器的缓存不是一个好的选择,所以我们通常会等待缓存过期。因此,这种缓存的有效期很短,通常为分钟或者秒级别,以避免返回前端脏数据。

缓存的不足

  • 缓存比较适合于读多写少的业务场景,并且数据最好带有一定的热点属性
  • 缓存会给整体系统带来复杂度,并且会有数据不一致的风险
  • 缓存通常使用内存作为存储介质,但是内存并不是无限的
  • 缓存会给运维带来一定的成本

读写策略

Cache Aside(旁路缓存)策略

更新数据时不更新缓存,而是删除缓存中的数据,在读取数据时,发现缓存中没了数据之后,再从数据库中读取数据,更新到缓存中。

读策略步骤
  • 从缓存中读取数据;
  • 如果缓存命中,则直接返回数据;
  • 如果缓存不命中,则从数据库中查询数据;
  • 查询到数据后,将数据写入到缓存中,并且返回给用户。
写策略步骤
  • 更新数据库中的记录;
  • 删除缓存记录。
不足

当写入比较频繁时,缓存的数据会被频繁的清理,从而影响缓存命中率。解决方案有如下两种:

  • 在更新数据时也更新缓存,只是在更新缓存前先加一个分布式锁 ,因为这样在同一时间只允许一个线程更新缓存,就不会产生并发问题了。但对于写入的性能会有一些影响
  • 在更新数据时更新缓存,只是给缓存加一个较短的过期时间,这样即使出现缓存不一致的情况,缓存的数据也会很快地过期,对业务的影响也是可以接受。

Read/Write Through(读穿 / 写穿)策略

核心原则是用户只与缓存打交道,由缓存和数据库通信,写入或者读取数据

Write Through(写穿)策略

先查询要写入的数据在缓存中是否已经存在,如果已经存在,则更新缓存中的数据,并且由缓存组件同步更新到数据库中,如果缓存中数据不存在,我们把这种情况叫做“Write Miss(写失效)”。

一般来说,可以选择两种“Write Miss”方式:

  • “Write Allocate(按写分配)”,做法是写入缓存相应位置,再由缓存组件同步更新到数据库中
  • “No-write allocate(不按写分配)”,做法是不写入缓存中,而是直接更新到数据库中

在此策略中一般选用后者,原因是无论采用哪种方式都需要同步到数据库,“No-write allocate”方式相比“Write Allocate”还减少了一次缓存的写入,能够提升写入的性能

Read Through策略

先查询缓存中数据是否存在,如果存在则直接返回,如果不存在,则由缓存组件负责从数据库中同步加载数据。

在使用本地缓存的时候可以考虑使用这种策略,比如本地缓存 Guava Cache 中的 Loading Cache 就有 Read Through 策略的影子。

不足

Write Through 策略中写数据库是同步的,这对于性能来说会有比较大的影响,因为相比于写缓存,同步写数据库的延迟就要高很多了。

Write Back(写回)策略

这个策略的核心思想是在写入数据时只写入缓存,并且把缓存块儿标记为“脏”的。而脏块儿只有被再次使用时才会将其中的数据写入到后端存储中。

写策略

在“Write Miss”的情况下,采用的是“Write Allocate”的方式,即在写入后端存储的同时要写入缓存,这样在之后的写请求中都只需要更新缓存即可,而无需更新后端存储了。

读策略
  • 在读取缓存时如果发现缓存命中则直接返回缓存数据。
  • 如果缓存不命中则寻找一个可用的缓存块儿:
    • 如果这个缓存块儿是“脏”的,就把缓存块儿中之前的数据写入到后端存储中,并且从后端存储加载数据到缓存块儿;
    • 如果不是脏的,则由缓存组件将后端存储中的数据加载到缓存中;
    • 最后将缓存设置为不是脏的,返回数据。

操作系统层面的 Page Cache、日志的异步刷盘、消息队列中消息的异步写入磁时大多采用了这种策略,避免了直接写磁盘造成的随机写问题。故在向低速设备写入数据的时候,可以在内存里先暂存一段时间的数据,甚至做一些统计汇总,然后定时地刷新到低速设备上。

缺点是一旦缓存机器掉电,就会造成原本缓存中的脏块儿数据丢失。

三种策略使用场景

  • Cache Aside 是在使用分布式缓存时最常用的策略,可以在实际工作中直接拿来使用。
  • Read/Write Through 和 Write Back 策略需要缓存组件的支持,所以比较适合在实现本地缓存组件的时候使用;
  • Write Back 策略是计算机体系结构中的策略,不过写入策略中的只写缓存,异步写入后端存储的策略有很多的应用场景。

参考资料

高并发系统设计40问

Tip: 本文是极客时间高并发系统设计40问学习笔记。

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 何为缓存
  • 缓存实例
    • TLB(Translation Lookaside Buffer)
      • 视频播放
        • HTTP协议缓存
        • 缓存与缓冲区
        • 缓存分类
          • 静态缓存
            • 分布式缓存
              • 热点本地缓存
              • 缓存的不足
              • 读写策略
                • Cache Aside(旁路缓存)策略
                  • 读策略步骤
                  • 写策略步骤
                  • 不足
                • Read/Write Through(读穿 / 写穿)策略
                  • Write Through(写穿)策略
                  • Read Through策略
                  • 不足
                • Write Back(写回)策略
                  • 写策略
                  • 读策略
                • 三种策略使用场景
                • 参考资料
                相关产品与服务
                数据库
                云数据库为企业提供了完善的关系型数据库、非关系型数据库、分析型数据库和数据库生态工具。您可以通过产品选择和组合搭建,轻松实现高可靠、高可用性、高性能等数据库需求。云数据库服务也可大幅减少您的运维工作量,更专注于业务发展,让企业一站式享受数据上云及分布式架构的技术红利!
                领券
                问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档