故而使用缓存来收缩数据库压力与抓牢访谈品质,能够间接通过缓存获取到供给的多少

澳门新葡8455最新网站 13

对于时效性很高,内容跨度很大,并且访问量不高的应用来说缓存命中率可能长期很低,可能预热后的缓存还没来得被访问就已经过期了。

缓存的使用可以出现在1到4的各个环节中,每个环节的方案他们都各有特点。

如何提高缓存命中率

从应用架构的角度 ,
要尽可能的使得应用通过缓存来直接获得数据并避免缓存失效.当然这需要对业务需求,
缓存粒度, 缓存策略,技术选型等各个方面通盘考虑权衡的 ,
尽可能聚焦在高频访问且时效性不高的热点业务上 , 通过缓存预加载,
增加存储容量, 调整缓存粒度, 更新缓存等手段来提高命中率.

不命中:无法直接通过缓存获取到想要的数据,需要再次查询数据库或者执行其它的操作。原因可能是由于缓存中根本不存在,或者缓存已经过期。

特征

  • 命中率 = 命中数 / (命中数 + 没有命中数)
  • 最大空间:缓存最大空间一旦缓存中元素数量超过这个值(或者缓存数据所占空间超过其最大支持空间),那么将会触发缓存启动清空策略根据不同的场景合理的设置最大元素值往往可以一定程度上提高缓存的命中率,从而更有效的时候缓存。
  • 清空策略:FIFO/LFU/LRU/过期时间/随机

FIFO:最先进入缓存的数据,在缓存空间不足时被清除,为了保证最新数据可用,保证实时性

LFU(Least Frequently
Used):最近最不常用,基于访问次数,去除命中次数最少的元素,保证高频数据有效性

LRU(Least Recently
Used):最近最少使用,基于访问时间,在被访问过的元素中去除最久未使用的元素,保证热点数据的有效性

缓存的特征
  • 命中率 = 命中数 / (命中数+ 没有命中数)
    澳门新葡8455最新网站,命中率越高 , 说明使用缓存的收益越好 , 应用性能越好, 响应的时间越短 ,
    吞吐量越高 ,抗并发的能力越强

  • 最大元素(空间)
    代表缓存中可以存放的最大元素的数量 ,
    一旦缓存中元素的数量超过最大空间
    ,是指缓存数据所在空间超过最大支持的空间, 将会触发清空策略 .
    根据不同的场景合理的设置最大元素值,
    可以在一定程度上提高缓存的命中率, 从而更有效的使用缓存 .

  • 清空策略

    • FIFO first in first out先进先出
      最先进入缓存空间的数据 , 在缓存不够的情况下,
      或者缓存数量超过最大元素的情况下 ,会被优先清除掉 ,
      以腾出空间缓存新的数据,
      这个清除算法主要是比较缓存元素的创建时间.在数据实时性要求场景下可以使用该策略
      ,优先保证最新数据可用 .
    • LFU least frequently used最少使用策略
      该策略是根据元素的使用次数来判断 , 无论缓存元素是否过期 ,
      清除使用次数最少的元素来释放空间.这个策略的算法主要比较元素的命中次数.在保证高频数据有效性的场景下
      , 可以使用此类策略.
    • LRU Least Recently Used 最近最少使用策略
      它是指无论是否过期 , 根据元素最后一次被使用的时间戳 ,
      清除最远使用时间戳的元素 ,
      这个策略的算法主要比较元素的最近一次被 get使用时间,
      在热点数据的场景下较适用 , 优先保证热点数据的有效性 .
    • 过期时间
      根据过期时间来判断 , 清理过期时间最长的元素,
      还可以根据过期时间来判读, 来清理最近要过期的元素 .
    • 随机
      随机清理元素

缓存适合读多写少的业务场景,反之,使用缓存的意义其实并不大,命中率会很低。

本地缓存Guava Cache

Guava
Cache是Google开源的Java重用工具集库Guava里的一款缓存工具,它的设计灵感是CuncurentHashMap

澳门新葡8455最新网站 1

Guava
Cache继承了ConcurrentHashMap的思路,使用多个segments方式的细粒度锁,在保证线程安全的同时,支持高并发场景需求。Cache类似于Map,它是存储键值对的集合,不同的是它还需要处理evict、expire、dynamic
load等算法逻辑,需要一些额外信息来实现这些操作。对此,根据面向对象思想,需要做方法与数据的关联封装.

其主要实现的缓存功能有:

  • 自动将entry节点加载进缓存结构中;
  • 当缓存的数据超过设置的最大值时,使用LRU算法移除;
  • 具备根据entry节点上次被访问或者写入时间计算它的过期机制;
  • 缓存的key被封装在WeakReference引用内;
  • 缓存的Value被封装在WeakReference或SoftReference引用内;
  • 统计缓存使用过程中命中率、异常率、未命中率等统计数据。

memcached是应用较广的开源分布式缓存产品之一,它本身其实不提供分布式解决方案。在服务端,memcached集群环境实际就是一个个memcached服务器的堆积,环境搭建较为简单;cache的分布式主要是在客户端实现,通过客户端的路由处理来达到分布式解决方案的目的。客户端做路由的原理非常简单,应用服务器在每次存取某key的value时,通过某种算法把key映射到某台memcached服务器nodeA上,因此这个key所有操作都在nodeA上,结构图如图6、图7所示。

澳门新葡8455最新网站 2

     memcached客户端路由图

澳门新葡8455最新网站 3

     memcached一致性hash示例图

memcached客户端采用一致性hash算法作为路由策略,相对于一般hash(如简单取模)的算法,一致性hash算法除了计算key的hash值外,还会计算每个server对应的hash值,然后将这些hash值映射到一个有限的值域上(比如0~2^32)。通过寻找hash值大于hash(key)的最小server作为存储该key数据的目标server。如果找不到,则直接把具有最小hash值的server作为目标server。同时,一定程度上,解决了扩容问题,增加或删除单个节点,对于整个集群来说,不会有大的影响。最近版本,增加了虚拟节点的设计,进一步提升了可用性。

缓存命中率的影响因素
  • 业务场景和业务需求
    缓存适合 读多写少 的业务场景, 否则使用其意义不大,命中率会很低
    .业务需求也决定了对实时性的要求,
    直接影响到缓存的过期时间和更新策略,实时性要求越低就越适合缓存
    .在相同 key 和相同请求数的情况下 ,缓存的时间越长, 命中率就会越高.

  • 缓存的设计(粒度和策略)
    通常情况下 , 缓存的粒度越小, 命中率就会越高.

  • 缓存的容量和基础设施
    缓存的容量有限, 就容易引起缓存的失效和淘汰.
    目前多少的缓存框架都使用了 LRU 这个算法
    .同时缓存的技术选型也是很重要的
    .比如采用应用内置的本地缓存,就容易出现单机瓶颈 , 而采用分布式缓存
    ,它就更容易扩展, 所以要做好系统容量的规划 ,并考虑是否可以扩展 ,
    另外不同的缓存中间件, 其效率和稳定性都是有差异的.除此之外,
    还有其他的一些会影响缓存命中率 , 比如某个缓存节点挂掉的时候 ,
    要避免缓存失效, 并最大程度的降低影响 . 比较典型的做法就是
    一致性hash算法 , 或者通过节点冗余的方式来避免这个问题 .

当然,我们也可以通过一些开源的第三方工具对整个memcached集群进行监控,显示会更直观。比较典型的包括:zabbix、MemAdmin等。

一致性哈希算法原理

memcached是一个高效的分布式内存cache,了解memcached的内存管理机制,才能更好的掌握memcached,让我们可以针对我们数据特点进行调优,让其更好的为我所用。我们知道memcached仅支持基础的key-value键值对类型数据存储。在memcached内存结构中有两个非常重要的概念:slab和chunk。

澳门新葡8455最新网站 4

每个page的默认大小是1M,trunk是真正存放数据的地方,memcache会根据value值的大小找到接近大小的slab

 

使用缓存的场景

一般来说, 现在网站 或者 app 的整体流程可以用下图来表示.
用户从浏览器或者app 发起请求 > 到网络转发 > 到服务 > 再到数据库
, 接着再返回把请求内容呈现给用户.但是随着访问量的增大 , 访问内容的增加,
应用需要支撑更多的并发,
同时应用服务器和数据库服务器所要做的计算越来越多,
但是应用服务器的资源有限, 文件内容的读写也是有限的 .
如何利用有限的资源提高更大的吞吐量 , 那就是引入缓存 ,
打破标准的流程, 在每个环节中 , 请求可以从缓存中直接获取目标数据并返回 ,
从而减少应用的计算量, 提升应用的响应速度 , 让有限的资源服务更多的用户.
如下图, 缓存可以出现在 1 ~ 4 的各个环节中.

澳门新葡8455最新网站 5

缓存

其他因素

Redis缓存

Redis是一个远程内存数据库(非关系型数据库),性能强劲,具有复制特性以及解决问题而生的独一无二的数据模型。它可以存储键值对与5种不同类型的值之间的映射,可以将存储在内存的键值对数据持久化到硬盘,可以使用复制特性来扩展读性能,还可以使用客户端分片来扩展写性能。

澳门新葡8455最新网站 6

Redis具备以下特点:

  • 异常快速: Redis数据库完全在内存中,因此处理速度非常快,每秒能执行约11万集合,每秒约81000+条记录。
  • 数据持久化: redis支持数据持久化,可以将内存中的数据存储到磁盘上,方便在宕机等突发情况下快速恢复。
  • 支持丰富的数据类型: 相比许多其他的键值对存储数据库,Redis拥有一套较为丰富的数据类型。
  • 数据一致性: 所有Redis操作是原子的,这保证了如果两个客户端同时访问的Redis服务器将获得更新后的值。
  • 多功能实用工具: Redis是一个多实用的工具,可以在多个用例如缓存,消息,队列使用(Redis原生支持发布/订阅),任何短暂的数据,应用程序,如
    Web应用程序会话,网页命中计数等。

适用场景:

1.取最新N个数据的操作

2.排行榜类似的应用

3.精准设定过期时间的应用

4.计数器的应用

5.唯一性检查

6.实时系统,队列系统,最基础的缓存功能

 澳门新葡8455最新网站 7

1缓存一致性问题

当数据时效性要求很高时,需要保证缓存中的数据与数据库中的保持一致,而且需要保证缓存节点和副本中的数据也保持一致,不能出现差异现象。这就比较依赖缓存的过期和更新策略。一般会在数据发生更改的时,主动更新缓存中的数据或者移除对应的缓存。

 澳门新葡8455最新网站 8

 2.缓存并发问题

缓存过期后将尝试从后端数据库获取数据,这是一个看似合理的流程。但是,在高并发场景下,有可能多个请求并发的去从数据库获取数据,对后端数据库造成极大的冲击,甚至导致
“雪崩”现象。此外,当某个缓存key在被更新时,同时也可能被大量请求在获取,这也会导致一致性的问题。那如何避免类似问题呢?我们会想到类似“锁”的机制,在缓存更新或者过期的情况下,先尝试获取到锁,当更新或者从数据库获取完成后再释放锁,其他的请求只需要牺牲一定的等待时间,即可直接从缓存中继续获取数据。

澳门新葡8455最新网站 9

3.缓存穿透问题

缓存穿透在有些地方也称为“击穿”。很多朋友对缓存穿透的理解是:由于缓存故障或者缓存过期导致大量请求穿透到后端数据库服务器,从而对数据库造成巨大冲击。

这其实是一种误解。真正的缓存穿透应该是这样的:

在高并发场景下,如果某一个key被高并发访问,没有被命中,出于对容错性考虑,会尝试去从后端数据库中获取,从而导致了大量请求达到数据库,而当该key对应的数据本身就是空的情况下,这就导致数据库中并发的去执行了很多不必要的查询操作,从而导致巨大冲击和压力。

澳门新葡8455最新网站 10

可以通过下面的几种常用方式来避免缓存传统问题:

缓存空对象

对查询结果为空的对象也进行缓存,如果是集合,可以缓存一个空的集合(非null),如果是缓存单个对象,可以通过字段标识来区分。这样避免请求穿透到后端数据库。同时,也需要保证缓存数据的时效性。这种方式实现起来成本较低,比较适合命中不高,但可能被频繁更新的数据。

单独过滤处理

对所有可能对应数据为空的key进行统一的存放,并在请求前做拦截,这样避免请求穿透到后端数据库。这种方式实现起来相对复杂,比较适合命中不高,但是更新不频繁的数据。

4.缓存颠簸问题

缓存的颠簸问题,有些地方可能被成为“缓存抖动”,可以看做是一种比“雪崩”更轻微的故障,但是也会在一段时间内对系统造成冲击和性能影响。一般是由于缓存节点故障导致。业内推荐的做法是通过一致性Hash算法来解决。这里不做过多阐述。

5.缓存的雪崩现象

缓存雪崩就是指由于缓存的原因,导致大量请求到达后端数据库,从而导致数据库崩溃,整个系统崩溃,发生灾难。导致这种现象的原因有很多种,上面提到的“缓存并发”,“缓存穿透”,“缓存颠簸”等问题,其实都可能会导致缓存雪崩现象发生。这些问题也可能会被恶意攻击者所利用。还有一种情况,例如某个时间点内,系统预加载的缓存周期性集中失效了,也可能会导致雪崩。为了避免这种周期性失效,可以通过设置不同的过期时间,来错开缓存过期,从而避免缓存集中失效。

从应用架构角度,我们可以通过限流、降级、熔断等手段来降低影响,也可以通过多级缓存来避免这种灾难。

此外,从整个研发体系流程的角度,应该加强压力测试,尽量模拟真实场景,尽早的暴露问题从而防范。

澳门新葡8455最新网站 11

 

缓存的应用和分类场景

目前的应用服务框架中 , 是根据缓存与应用的耦合度分为本地缓存和分布式缓存.

  • 本地缓存
    本地缓存是指缓存中的应用组件, 它最大的优点是应用和 cache ,
    是在同一个进程的内部,
    请求缓存非常的快速.没有过多的网络开销等,在单应用中,不需要集群支持 ,
    各节点不需要互相通知的情景下, 适合使用本地缓存.
    它的缺点也是显而易见的, 由于缓存和应用耦合度较高,
    多个应用无法共享缓存 ,各个应用都需要单独维护自己的缓存
    ,对内存也是一种浪费, 资源能节省就节省. 在实际实现中 ,
    都是同成员变量, 局部变量, 静态变量 来实现, 也还有一些框架 比如
    Guava Cache
  • 分布式缓存
    它是指应用分离的缓存组件或服务, 最大的优点是自身是一个独立的应用
    ,与本地应用是隔离的,多个应用可以直接共享缓存. 比如 常用的Redis

缓存命中率的介绍

缓存算法(页面置换算法)-FIFO、LFU、LRU

影响缓存命中率的因素:

1.业务场景和业务需求

缓存通常适合读多写少的业务场景,反之的使用意义并不多,命中率会很低。业务需求也决定了实时性的要求,直接影响到过期时间和更新策略,实时性要求越低越适合缓存。

2.缓存的设计(策略和粒度)

通常情况下缓存的粒度越小,命中率越高。比如说缓存一个用户信息的对象,只有当这个用户的信息发生变化的时候才更新缓存,而如果是缓存一个集合的话,集合中任何一个对象发生变化都要重新更新缓存。

当数据发生变化时,直接更新缓存的值比移除缓存或者让缓存过期它的命中率更高,不过这个时候系统的复杂度过高。

3.缓存的容量和基础设施

缓存的容量有限就会容易引起缓存的失效和被淘汰。目前多数的缓存框架和中间件都采用LRU这个算法。同时采用缓存的技术选型也是至关重要的,比如采用本地内置的应用缓存,就比较容易出现单机瓶颈。而采用分布式缓存就更加容易扩展。所以需要做好系统容量规划,系统是否可扩展。

 

缓存介质

虽然从硬件介质上来看,无非就是内存和硬盘两种,但从技术上,可以分成内存、硬盘文件、数据库。

  • 内存:将缓存存储于内存中是最快的选择,无需额外的I/O开销,但是内存的缺点是没有持久化落地物理磁盘,一旦应用异常break
    down而重新启动,数据很难或者无法复原。
  • 硬盘:一般来说,很多缓存框架会结合使用内存和硬盘,在内存分配空间满了或是在异常的情况下,可以被动或主动的将内存空间数据持久化到硬盘中,达到释放空间或备份数据的目的。
  • 数据库:前面有提到,增加缓存的策略的目的之一就是为了减少数据库的I/O压力。现在使用数据库做缓存介质是不是又回到了老问题上了?其实,数据库也有很多种类型,像那些不支持SQL,只是简单的key-value存储结构的特殊数据库(如BerkeleyDB和Redis),响应速度和吞吐量都远远高于我们常用的关系型数据库等。

 

根据缓存和应用的耦合度

澳门新葡8455最新网站 12

本地缓存最大的优点在于它在应用进程的内部,请求缓存非常的快速,没有过多的网络开销。在单应用中不需要集群支持,集群的情况下各节点不需要互相通知的情况下使用本地缓存比较合适。

缺点是因为本地缓存跟应用程序耦合,多个应用程序无法直接共享缓存,各应用节点都需要维护自己单独的缓存,有时也是对内存的一种浪费。

分布式缓存指的是应用分离的缓存服务,最大的优点就是自身就是一个独立的应用,与本地应用是隔离的,多个应用直接共享缓存。

Java并发编程与高并发解决方案
https://coding.imooc.com/class/195.html

有些朋友可能会有这样的理解误区:既然业务需求对数据时效性要求很高,而缓存时间又会影响到缓存命中率,那么系统就别使用缓存了。其实这忽略了一个重要因素–并发。通常来讲,在相同缓存时间和key的情况下,并发越高,缓存的收益会越高,即便缓存时间很短。

澳门新葡8455最新网站 13

命中:可以直接通过缓存获取到需要的数据。

应用需要支撑大量并发量,但数据库的性能有限,所以使用缓存来减少数据库压力与提高访问性能。

业务需求决定了对时效性的要求,直接影响到缓存的过期时间和更新策略。时效性要求越低,就越适合缓存。在相同key和相同请求数的情况下,缓存时间越长,命中率会越高。

还有另一种情况,假设其他地方也需要获取该对象对应的数据时,如果缓存的是单个对象,则可以直接命中缓存,反之,则无法直接命中。这样更加灵活,缓存命中率会更高。

相关文章

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图