cache2k, чтение и блокировка

Я использовал cache2k с возможностью чтения в веб-приложении для загрузки сообщений в блоге по требованию. Однако меня беспокоит блокировка функции чтения. Например, если несколько потоков (запросов) запрашивают в кеше один и тот же ключ, возможно ли, чтобы метод чтения вызывался несколько раз, чтобы загрузить один и тот же ключ / значение в кеш?

Из документации складывается впечатление, что функция считывания блокирует одновременные запросы на один и тот же ключ до тех пор, пока загрузка не будет завершена, но, возможно, я неправильно прочитал документацию. Я просто хочу проверить, что это за поведение.

Метод, который инициализирует кеш, выглядит так:

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 ответ

Когда несколько запросов к одному и тому же ключу вызовут вызов загрузчика кэша, cache2k вызовет загрузчик только один раз. Другие потоки ждут, пока загрузка не закончится. Такое поведение называется блокировкой чтения. Цитировать из Java Doc:

Блокировка: если загрузчик вызывается Cache.get(K) или другие методы, которые разрешают параллельные запросы прозрачного доступа к одному и тому же ключу, будут блокироваться до завершения загрузки. Для значений с истекшим сроком блокировки можно избежать, включив Cache2kBuilder.refreshAhead(boolean), Нет гарантии, что загрузчик вызывается только для одного ключа за раз. Например, после Cache.clear() Вызванные операции загрузки для одного ключа могут перекрываться.

Это поведение очень важно для кэшей, поскольку оно защищает от давки кэша. Пример: веб-сайт с высоким трафиком получает 1000 запросов в секунду. Один ресурс генерируется довольно долго, около 100 миллисекунд. Когда кеш не блокирует множественные запросы, когда происходит кеш-пропуск, было бы по меньшей мере 100 запросов, попадающих в загрузчик для того же ключа. "по крайней мере" - это занижение, поскольку ваш компьютер, вероятно, не будет обрабатывать 100 запросов с той же скоростью, что и один.

Имейте в виду, что нет никакой твердой гарантии кешем. Загрузчик должен по-прежнему иметь возможность правильно работать при вызове одного и того же ключа в одно и то же время. Например, блокировка чтения и Cache.clear() привести к конкурирующим требованиям. Cache.clear() должно быть быстрым, что означает, что мы не хотим ждать завершения текущих операций загрузки.

Другие вопросы по тегам