java缓存技术,开源的分布式缓存

  java缓存技术,开源的分布式缓存

  00-1010缓存穿透缓存击穿缓存雪崩缓存相干分布式缓存系统是三高架构中不可或缺的一部分,大大提高了整个项目的并发性和响应速度,但也带来了新的问题需要解决,即:缓存穿透、缓存击穿、缓存雪崩和缓存相干。

  00-1010第一个大问题是缓存渗透。这个概念很好理解,和命中率有关系。如果命中率低,压力会集中在数据库持久层。

  如果我们能找到相关数据,我们可以缓存它。但是,问题是这个请求在缓存和持久层没有命中,这就是所谓的缓存穿透。

  例如,如上图所示,在一个登录系统中,有一个外部攻击一直试图用不存在的用户登录。这些用户是虚拟的,无法有效缓存。他们每次都会查询一次数据库,最终导致服务性能失效。

  这个问题有很多解决方法。下面简单介绍一下。

  第一种是缓存空对象。持久层不是无法检查数据吗?然后我们可以将这个请求的结果设置为null,并将其放入缓存中。通过设置合理的过期时间,可以保证后端数据库的安全性。

  空缓存对象会占用额外的缓存空间,并且会出现数据不一致的时间窗口。因此,第二种方法是使用Bloom filter来处理大量的常规键值。

  记录的存在与否是一个Bool值,只能用1位来存储。布隆过滤器可以将这种是和否操作压缩到数据结构中。比如手机号、用户性别等数据就非常适合使用Bloom filter。

  00-1010缓存崩溃也指用户请求落在数据库上的情况。在大多数情况下,这是由于缓存时间批量过期造成的。

  我们通常为缓存中的数据设置一个到期时间。如果在某个时间从数据库获取大量数据,并且设置了相同的失效时间,那么它们将同时失效,导致缓存崩溃。

  对于热数据,我们可以将其设置为过期;或者在访问时更新其到期时间;批处理缓存项也应该尽可能分配一个相对平均的过期时间,以避免同时失效。

  00-1010雪崩看起来很可怕,但实际情况真的很严重。缓存是用来提升系统速度的,后端数据库只是数据的备份,并不是高可用的替代品。

  当缓存系统出现故障时,流量会立即转移到后端数据库。用不了多久,数据库就会被繁重的流量压得喘不过气来,这种级联式的服务故障可以形象地称为雪崩。

  缓存的高可用性建设非常重要。Redis提供主从模式和集群模式,其中集群模式简单易用,每个切片可以独立主从,可以保证高可用性。

  此外,我们还对数据库的性能瓶颈进行了总体评估。如果缓存系统关闭,那么流向数据库的请求可以被限流组件拦截。

  00-1010引入缓存组件后,另一个持久的问题是缓存一致性。

  我们先来看看问题是怎么发生的。对于缓存项,有四种常见的操作:写、更新、读和删除。

  写:缓存和数据库是两个不同的组件。只要涉及两次写入,就有可能只有一次写入成功,从而导致数据不一致。更新:更新情况类似,需要更新两个不同的组件。读取:读取以确保从缓存中读取的信息是最新的,但与数据库中的信息一致。删除:删除数据库记录时,如何删除缓存中的数据?因为大多数情况下业务逻辑是复杂的。其中,更新操作是非常昂贵的。例如,用户的余额是通过计算一系列资产计算出来的数字。如果这些关联资产每次更改都刷新,代码结构会非常混乱,无法维护。

  我推荐使用触发式缓存一致性,延迟加载可以让缓存同步变得非常简单:

  读取缓存时,如果缓存中没有相关数据,则执行相关业务逻辑构造缓存数据并存储在缓存系统中;当缓存项相关的资源发生变化时,先删除对应的缓存项,然后更新数据库中的资源,最后删除对应的缓存项。这种操作,除了简单的编程模式,还有一个明显的优势。我只在使用这个缓存时才将其加载到缓存系统中。如果每次修改资源时都创建和更新资源,那么缓存系统中会有大量冷数据。实际上,它实现了Cache-side模式,即按需将数据从数据存储加载到缓存中,其最大的作用是提高性能,减少不必要的查询。

  但这还是有问题的。以下场景也是采访中经常提到的。

  上面提到的数据库更新动作和缓存删除动作显然不在同一个事务中。在更新过程中,这可能会导致数据库内容和缓存中的内容不一致。

  面试时,只要你指出这个问题,面试官就会竖起大拇指。

  您可以使用分布式锁来解决这个问题。您可以使用锁将数据库操作和缓存操作与其他缓存读取操作隔离开来。一般来说,读操作不需要被锁定。当遇到锁时,它将重试等待,直到超时。

  到此这篇关于详解Java分布式缓存系统中必须解决的四大问题的文章就介绍到这了,更多相关Java分布式缓存系统内容请搜索盛行IT以前的文章或继续浏览下面的相关文章希望大家以后多多支持盛行IT!

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: