Spring 通过 Kafka 失效的多个应用程序实例的本地缓存
Spring local cache for multiple app instances with invalidation through Kafka
我有一个常用的 Spring 启动应用程序,它执行大量的数据库调用,对于那些我想用普通 @Cacheable / @CacheEvict
和其他注释(默认情况下)实现一些 Spring 缓存我使用 CaffeineCache)。有几个 AKS 节点,在每个节点上我的应用程序的一个实例是 运行。我想收到什么:
- 本地(内存中) Spring 缓存。基于 Redis 的分布式解决方案不适合。
- 应用程序的所有 运行 个实例更新其中一个后,缓存应该失效。
- 我有一个全球 Kafka 服务,它会向我的 Cassandra DB
注册每个 write/update 请求
现在我的问题 - 是否有可能通过 Kafka 拥有一个本地的、通常的 Spring 缓存,当然会导致所有实例上的缓存版本同步?
原则上是可以的。您可以构建一个简单的解决方案,其中
- 读取操作使用
@Cacheable
- 写入操作将消息放入 Kafka 总线,每个节点都有一个侦听器使用
@CachePut
将其写入本地缓存。
但这种天真的解决方案不会有任何严格的同步保证,它只是最终一致。将更新传播到其他节点需要时间,并且在其他节点之间仍然可以读取旧值。此外,您还必须考虑更新可能丢失的错误情况。
如果你想有更严格的保证,你需要多阶段提交或共识协议。除非它是一个研究项目,否则我强烈建议你不要自己写一个。这些不是微不足道的,因为问题不是微不足道的。相反,您应该使用现有的实现。
总而言之:如果您不需要一致性,您可以按照您的建议进行。如果你需要任何级别的一致性保证,你应该使用现有的分布式缓存,它仍然可以与 @Cacheable
.
集成
我有一个常用的 Spring 启动应用程序,它执行大量的数据库调用,对于那些我想用普通 @Cacheable / @CacheEvict
和其他注释(默认情况下)实现一些 Spring 缓存我使用 CaffeineCache)。有几个 AKS 节点,在每个节点上我的应用程序的一个实例是 运行。我想收到什么:
- 本地(内存中) Spring 缓存。基于 Redis 的分布式解决方案不适合。
- 应用程序的所有 运行 个实例更新其中一个后,缓存应该失效。
- 我有一个全球 Kafka 服务,它会向我的 Cassandra DB 注册每个 write/update 请求
现在我的问题 - 是否有可能通过 Kafka 拥有一个本地的、通常的 Spring 缓存,当然会导致所有实例上的缓存版本同步?
原则上是可以的。您可以构建一个简单的解决方案,其中
- 读取操作使用
@Cacheable
- 写入操作将消息放入 Kafka 总线,每个节点都有一个侦听器使用
@CachePut
将其写入本地缓存。
但这种天真的解决方案不会有任何严格的同步保证,它只是最终一致。将更新传播到其他节点需要时间,并且在其他节点之间仍然可以读取旧值。此外,您还必须考虑更新可能丢失的错误情况。
如果你想有更严格的保证,你需要多阶段提交或共识协议。除非它是一个研究项目,否则我强烈建议你不要自己写一个。这些不是微不足道的,因为问题不是微不足道的。相反,您应该使用现有的实现。
总而言之:如果您不需要一致性,您可以按照您的建议进行。如果你需要任何级别的一致性保证,你应该使用现有的分布式缓存,它仍然可以与 @Cacheable
.