cache2k,read through和blocking

时间:2016-12-29 07:11:36

标签: cache2k

我在网络应用程序中使用 cache2k 通读来加载博客帖子 on demand 。但是,我担心读取功能的阻止。例如,如果多个线程(请求)要求缓存提供相同的密钥,是否可以多次调用 read through 方法来加载< / em>缓存中的相同键/值?

我从读取功能的文档中获取展示 阻止对同一密钥的并发请求,直到加载已经完成,但我可能误读了文档。我只是想检查一下这是行为。

初始化缓存的方法如下所示:

private void initializeURItoPostCache()
{
    final CacheLoader<String, PostImpl> postFileLoader = new CacheLoader<String, PostImpl>(){
        @Override public PostImpl load(String uri)
        {
            // Fetch the data and create the post object
            final PostImpl post = new PostImpl();
            //.. code omitted
            return post;
        }
    };

    // Initialize the cache with a read-through loader
    this.cacheUriToPost = new Cache2kBuilder<String, PostImpl>(){}
    .name("cacheBlogPosts")
    .eternal(true)
    .loader(postFileLoader)
    .build();
}

以下方法用于从缓存中请求帖子:

public Post getPostByURI(final String uri)
{
    // Check with the index service to ensure the URI is known (valid to the application)
    if(this.indexService.isValidPostURI(uri))
    {
        // We have a post associated with the given URI, so
        // request it from the cache
        return this.cacheUriToPost.get(uri);
    }
    return EMPTY_POST;
}

非常感谢,祝大家新年快乐和繁荣。

1 个答案:

答案 0 :(得分:2)

当对同一个键的多个请求将引发缓存加载器调用时,cache2k将仅调用一次加载器。其他线程一直等到负载完成。此行为称为阻止读取。引用Java Doc:

  

阻止:如果Cache.get(K)或其他允许透明访问的方法调用加载器,则同一个密钥上的并发请求将被阻塞,直到加载完成。对于过期值,可以通过启用Cache2kBuilder.refreshAhead(boolean)来避免阻塞。无法保证一次仅为一个密钥调用加载程序。例如,在调用Cache.clear()之后,一个键的加载操作可能会重叠。

此行为对缓存非常重要,因为它可以防御Cache stampede。例如:高流量网站每秒收到1000个请求。一个资源需要很长时间才能生成,大约100毫秒。当高速缓存未在高速缓存未命中时阻止多个请求时,将至少有100个请求命中加载器以获得相同的密钥。 “至少”是轻描淡写,因为你的机器可能无法以相同的速度处理100个请求。

请记住,缓存没有硬性保证。当同时调用相同的密钥时,加载程序仍必须能够正确执行。例如,阻止通读和Cache.clear()会导致竞争要求。 Cache.clear()应该很快,这意味着我们不想等待正在进行的加载操作完成。