简体   繁体   English

如何制作缓存取决于Spring应用程序启动时的其他缓存

[英]How to make cache depends on other caches on startup of spring application

In our multi module project, we have different cache present in different modules. 在我们的多模块项目中,不同模块中存在不同的缓存。 And we fill all these caches on server startup in @PostConstruct. 然后,我们在@PostConstruct的服务器启动时填充所有这些缓存。 Now some cache depends on some other cache which may present in different modules. 现在,某些缓存依赖于可能存在于不同模块中的某些其他缓存。 So it requires that some cache should be filled before the caches that depends on that cache. 因此,它要求在依赖于该缓存的缓存之前应填充一些缓存。 1. How we can do this in Spring? 1.我们如何在春季做到这一点? Any design pattern I can leverage? 我可以利用任何设计模式吗? 2. If a cache gets updated how we can propogate this updated change to those caches that depends on updated cache in real time? 2.如果更新了缓存,我们如何将更新后的更改推广到那些实时依赖更新缓存的缓存?

module 1---
    Cachce1

module 2--
    Cache2

module 3--
    Cache3

class Cache1 {
  private ConcurrentMap<> cache; 
  @PostConstruct() {
    cache = filleCache();
  }
}
class Cache2 {
  @Autowired
  private Cache1 cache1;
  private ConcurrentMap<> cache; 
  @PostConstruct() {
    cache = cache1;
  }
}
class Cache3 {
  @Autowired
  private Cache2 cache2;
  private ConcurrentMap<> cache; 
  @PostConstruct() {
    cache = cache2;
  }
}

Dependencies : The initialization order is usually done correctly by the DI framework. 依赖关系 :初始化顺序通常由DI框架正确完成。 So Cache2 post construct is run after Cache1 is completely initialized. 因此,在Cache1完全初始化之后,将运行Cache2后构造。 If you cache only a full set of data in a CuncurrentMap you could use memoization instead, see https://dzone.com/articles/need-micro-caching-memoization 如果仅在CuncurrentMap缓存完整的数据集,则可以改用CuncurrentMap ,请参阅https://dzone.com/articles/need-micro-caching-memoization

Avoid cache stacking . 避免缓存堆栈 Sometimes its simpler to avoid caching in intermediate layers. 有时,它更简单,可以避免在中间层进行缓存。 A simple approach is to cache where the data comes in, eg the persistence layer, and then cache where the data goes out, eg response snippets or complete responses. 一种简单的方法是缓存数据输入的位置(例如持久层),然后缓存数据输出的位置(例如响应片段或完整响应)。 Since the complete data is cached in the top-most cache anyways, the intermediate caches might not get any hits either. 由于无论如何,完整的数据都缓存在最顶层的缓存中,因此中间缓存也可能不会获得任何命中。

This heavily depends on the kind of data and how often its used on the next layer. 这在很大程度上取决于数据的种类以及在下一层使用的频率。

how we can propagate this updated change? 我们如何传播此更新的更改?

You have a range of options. 您有多种选择。 In case module1 knows about its dependencies you can call a reload of module2 and 3. If module1 code should not depend on its clients, then use a event listener pattern. 如果module1知道其依赖性,则可以调用module2和3的重载。如果module1代码不依赖于其客户端,则使用事件侦听器模式。 Depending where your data comes from, there are already existing mechanisms. 根据数据的来源,已经存在现有的机制。 Look for Spring Data events, Change Data Capture capabilities of your database, Triggers of your database or persistence layer. 查找Spring Data事件,数据库的Change Data Capture功能,数据库或持久层的触发器。

You can keep things simple by using an expiry on the cache entry and simply update/reload your data after a period of time. 您可以通过在缓存条目上使用有效期来简化事情,并在一段时间后简单地更新/重新加载数据。 However, expiry and cache stacking is a problem by itself. 但是,到期和缓存堆栈本身就是一个问题。 In case you use a fixed expiry of 5 minutes, the effective expiry adds up each layer. 如果您使用5分钟的固定期限,则有效期限将累加每一层。 So for three layers, data maybe refreshed after 5 or 15 minutes. 因此,对于三层,数据可能会在5或15分钟后刷新。 To avoid this, we propagate a point of time when expiry should happen together with the data through the caching layers. 为了避免这种情况,我们通过缓存层传播了一个到期时间和数据一起发生的时间点。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM