缓存笔记(一)--描述

缓存笔记(一)

缓存是通过将频繁读取的数据复制到应用程序的快速存储中,实现提高系统的性能和可伸缩性的技术。

当应用实例重复访问相同数据时,特别是原始数据源相对较慢受竞态条件限制时,或当网络延迟可能导致访问速度慢时,缓存最有有效。

缓存类型

常见的缓存有两种:

  • 内存缓存(In-Memory Caching)。其数据在运行应用实例的计算机本地保存
  • 共享缓存(Shared Caching)。可在不同计算机上运行并可由多个实力访问的应用程序(如redis)

内存缓存

缓存的最基本类型是内存存储,存储在单个进程的地址空间中,并由该进程中运行的代码直接访问。内存缓存访问非常快,并有多种策略来保证存储少量的静态数据(缓存大小通常受托管进程的计算机上可用内存限制)。如果使用该模型同时运行的应用程序的多个实例,则每个应用程序实例将拥有自己的独立缓存,其中包含自己的数据副本。

内存缓存

图-1 内存缓存模型

内存缓存是数据某个时刻的快照,并不是动态的。在不同实例中保存的数据可能出现版本不同,实例查询出来的数据也不同

共享缓存

共享缓存通过将缓存放置在单独的位置(进程、服务器),来确保不同的应用实例访问相同的缓存数据。不用担心每个应用实例拿到的缓存数据不同。

共享缓存

图-2 共享缓存模型

共享缓存提供非常好的延展性,可由单机或者集群实现。但访问速度慢于内存缓存。

注意事项

缓存适用于读多写少的数据。

数据类型与填充策略

正确使用缓存的关键在于确定合适的数据,并在合适的时间对其缓存。通常使用两种填充策略:

  • 数据在第一次被访问时写入缓存。只需要访问一次底层数据源。
  • 数据在程序启动时全部(部分)写入缓存。不建议在大型缓存中使用,启动时会给底层数据源施加高负载。

填充策略的选择通常需要使用模式进行分析。

缓存可以处理不可变或者不常变的数据,但对与动态数据不太有用。缓存动态数据,当原始数据变更时,缓存数据会很快过期,保持缓存与原始数据同步的开销会降低缓存的效率。

缓存中的数据都是临时的,不要将有价值的数据存储在缓存中。如缓存不可用,可用最大程度的保证数据不丢失。

直读(Read-Through)、直写(Write-Through)和回写(Write-behind)

  • Read-throug

    当应用系统向缓存服务请求数据时(例如使用key=x向缓存请求数据),如果缓存中并没有对应的数据存在(key=x的value不存在),缓存服务将向底层数据源的读取数据。如果数据在缓存中存在(命中key=x),则直接返回缓存中存在的数据。直读有效地按需缓存数据。

    访问无效key可能缓存穿透

  • Write-Through

    当应用实例对缓存中的数据进行更新时(例如调用put方法更新或添加条目),缓存系统会同步更新缓存数据和底层数据源。

    Write-Through

    图-3 直写流程

  • Write-behind

    当应用系统对缓存中的数据进行更新时(例如调用put方法更新或添加条目),缓存系统会在指定的时间后向底层数据源更新数据。

    Write-behind

    图-4 回写流程

通常情况下,直读直写模式就能满足缓存需求。在数据变动频繁,不需要立即更新数据的情况下,使用回写更优。如应用实例修改缓存中的数据,并很快再次更新,运用回写就能避免一次数据源的写操作,较少数据竞争,提升性能。但如果缓存服务宕机后无法重建,或者系统要求数据变化日志的,无法使用该模式。

数据过期

通常情况下,缓存都是数据副本。在更新或者数据过期时,缓存数据将被删除,当应用实例重新查询是重新写入缓存。

合理的过期时间设置变得尤为重要。如果将其设置得太短,则对象将很快过期,从而降低使用缓存的好处,增加数据源读取。如果将时间段设置得太长,则可能会导致与数据源不同步。

数据长时间保持驻留,可能缓存写满,此时需要一个合理的数据淘汰策略,防止程序崩溃。

单数据过期可能缓存击穿,大量过期可能雪崩

并发管理

缓存通常供多个实例共享读取和修改其中的数据,也逃不过并发问题。根据数据的性质和冲突的可能性,可以采用两种并发方法之一:

  • <b>乐观(Optimistic)</b> 应用程序更新缓存之前要检查缓存中的数据是否被更新改过。如果数据仍然相同,则可以进行更改。否则,应用程序必须决定是否对其进行更新。此方法适用于不经常更新或不太可能发生冲突的情况。
  • <b>悲观(Pessimistic)</b> 应用程序在查询数据时将其锁定缓存中数据,以防止另一个实例更改数据。此过程可确保不会发生冲突,但会阻止其他需要处理相同数据的实例。悲观并发会影响解决方案的可伸缩性,并且仅应用于短暂的操作。此方法可能适用于发生冲突的可能性更高的情况,尤其是当应用程序更新缓存中的多个项目,并且必须确保一致性时。

参考资料

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章