Rest 何时以及如何更新缓存

Rest 何时以及如何更新缓存,rest,caching,architecture,Rest,Caching,Architecture,我有一个服务a和一个服务B 服务A是一个RESTAPI,它将服务B需要的一些相关信息存储在数据库中 服务B处理大量流量,并不断使用卡夫卡主题的消息。每条消息都需要来自服务A的一些信息。但是这些信息很少改变,最多每天改变一次 因此,为了避免经常访问RESTAPI以获取很少更改的信息,我将实现一个缓存。(不使用缓存也会带来一直查询数据库的问题)。服务B将首先命中缓存,如果没有所需数据,则只命中A一次 问题来了 如果服务A更新其信息,我需要立即更新缓存 这样做的最佳方式是什么 1) 我可以在RESTA

我有一个服务a和一个服务B

服务A是一个RESTAPI,它将服务B需要的一些相关信息存储在数据库中

服务B处理大量流量,并不断使用卡夫卡主题的消息。每条消息都需要来自服务A的一些信息。但是这些信息很少改变,最多每天改变一次

因此,为了避免经常访问RESTAPI以获取很少更改的信息,我将实现一个缓存。(不使用缓存也会带来一直查询数据库的问题)。服务B将首先命中缓存,如果没有所需数据,则只命中A一次

问题来了

如果服务A更新其信息,我需要立即更新缓存

这样做的最佳方式是什么

1) 我可以在RESTAPI中实现一些东西,让B注意到它需要更新他的缓存,但是在关注点分离和封装方面,A知道B处理内部缓存,这不坏吗?(我想是的)

2) 我可以在B中实现一个池(并让B检查信息是否每X次更改一次),或者让缓存每X次更新一次。但这样我就有可能无法立即更新信息

3) 是否可以在a中缓存此信息?至少我避免了查询数据库,但没有触及API:/

有没有更好的处理方法

谢谢

根据这句话:“如果服务A更新其信息,我需要立即更新缓存”,那么根据我的经验,您的两个选择将是某种形式的分布式缓存:

  • 让服务A提供服务B可以订阅的侦听器机制,以便在数据更改时使其自身的内部缓存失效
  • 实现服务a和B都知道的分布式缓存层,如ehcache或memcache;当服务A更新时,它会将新值写入缓存,所有订阅服务器都会自动更新

  • 希望有帮助

    在@CapnSchwenk的回答中添加第三个要点

  • 具有一个将所有更改提交到消息队列的权限,如Rabbit MQ。消息队列可以处理持久性(在B关闭的情况下)和发布者设计模型实现。队列还可以包含新数据,这样B就不必向A查询新数据

  • 这是一致性保证的问题,也是分布式系统中的核心问题

    您的场景包含三个服务:A、B和数据库。 如果B在任何情况下都不能使用过时数据,则有两种选择:

  • 所有读取都将命中数据库(在A或B处没有缓存)。数据库中的内置机制(如数据库的内部缓存、磁盘缓存和RAID镜像)可能会缓解一些磁盘I/O瓶颈
  • 将数据缓存在A(或B)处,并在缓存和数据库之间强制执行强一致性,这意味着每次写入都将在数据库和缓存之间的分布式事务中完成(或通过使用提供强一致性保证的其他一致协议)
  • 第一个选项不需要付出任何努力,在特定的工作负载下可以很好地工作,但是如果B的数据入口需要数据库可以保留的更多吞吐量,那么它将成为一个严重的瓶颈

    第二个选项的实现相当复杂,会减慢数据更改的速度,使系统变得复杂,并损害其整体可用性:如果A发生故障,则无法在数据库中更改数据;它在事务中下降,那么数据将无法从数据库中读取(!)

    好消息是,大多数系统不需要如此强大的一致性保证,它们可以在特定情况下偶尔使用过时的数据。

    如果您的系统是这样,那么有几种方法可以使缓存无效。就我个人而言,我同意Jose Martinez的建议,使用消息队列系统,并结合发布/订阅模式:服务B将向发布/订阅发布“数据更改”消息(消息将包括关于数据项确切更改的信息),服务a将是处理“数据更改”的订阅者消息,并在消息到达时使其缓存无效

    其他要点:

    B中的缓存乍一看似乎可以提供很强的一致性,但事实是,您可能需要扩展B,以便有多个B实例,每个实例都有自己的缓存,需要对其进行失效和同步

    您可以使用一个完整的其他服务来保存缓存数据(Redis、Memcached等),这将允许您分担缓存数据的责任(B可以使其失效,a可以直接从中读取),但这不会改变一致性困境的本质