Кэширование в Java: Redis, Memcached и встроенные решения от А до Я

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Кэширование в Java: Redis, Memcached и встроенные решения: от А до Я

Кэширование — один из ключевых инструментов для повышения производительности Java-приложений. Оно позволяет сократить время ответа, снизить нагрузку на базы данных и внешние API, а также улучшить пользовательский опыт. В этой статье мы разберём три основных подхода к кэшированию в Java: встроенные решения (ConcurrentHashMap, Caffeine, Ehcache), распределённые системы (Redis) и лёгкие сетевые кэши (Memcached). Вы узнаете, когда и что выбирать, и получите готовые примеры кода.

Что такое кэширование и зачем оно нужно в Java?

Кэширование — это временное хранение часто запрашиваемых данных в быстром хранилище (обычно в оперативной памяти). В Java это особенно актуально для:

  • Снижения задержек — данные из кэша возвращаются за микросекунды, а не за миллисекунды (как из БД).
  • Уменьшения нагрузки на ресурсы — базы данных, внешние сервисы и диски работают меньше.
  • Экономии ресурсов — меньше CPU и I/O операций.

Основные метрики кэша: hit ratio (процент успешных обращений) и TTL (время жизни записи).

Встроенные решения: от простого к продвинутому

Для небольших проектов или однопоточных сценариев можно использовать простые структуры данных. Однако для промышленных приложений лучше подходят специализированные библиотеки.

1. ConcurrentHashMap — базовый кэш

Самый простой способ — использовать ConcurrentHashMap. Он потокобезопасен, но не имеет механизмов автоматической очистки (TTL, eviction).

import java.util.concurrent.ConcurrentHashMap;

public class SimpleCache {
    private final ConcurrentHashMap<String, Object> cache = new ConcurrentHashMap<>();

    public void put(String key, Object value) {
        cache.put(key, value);
    }

    public Object get(String key) {
        return cache.get(key);
    }

    public void evict(String key) {
        cache.remove(key);
    }

    public void clear() {
        cache.clear();
    }
}

Плюсы: простота, нулевая зависимость.
Минусы: нет автоматической инвалидации, ручное управление памятью.

2. Caffeine — современный высокопроизводительный кэш

Библиотека Caffeine — это стандарт де-факто для in-memory кэширования в Java. Она поддерживает:

  • Автоматическую вытеснение по времени (TTL) и размеру.
  • Асинхронную загрузку.
  • Статистику (hit rate, miss rate).
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import java.util.concurrent.TimeUnit;

public class CaffeineExample {
    public static void main(String[] args) {
        Cache<String, String> cache = Caffeine.newBuilder()
                .expireAfterWrite(10, TimeUnit.MINUTES)
                .maximumSize(1000)
                .recordStats() // для сбора статистики
                .build();

        // Добавление
        cache.put("user:1", "Alice");

        // Получение с автоматической загрузкой
        String value = cache.get("user:2", key -> loadFromDB(key));
        System.out.println(value);
    }

    private static String loadFromDB(String key) {
        // Имитация загрузки из БД
        return "Bob";
    }
}

Плюсы: высокая производительность, гибкость, малый размер (около 600 КБ).
Минусы: только локальный (не распределённый).

3. Ehcache — мощный in-process кэш

Ehcache — это зрелая библиотека (часть Hibernate). Поддерживает:

  • Дисковое хранение (persistence).
  • Кластеризацию (через Terracotta).
  • JSR-107 (JCache) стандарт.
import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;

public class EhcacheExample {
    public static void main(String[] args) {
        CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
                .withCache("users",
                        CacheConfigurationBuilder.newCacheConfigurationBuilder(
                                String.class, String.class,
                                ResourcePoolsBuilder.heap(100)))
                .build(true);

        Cache<String, String> cache = cacheManager.getCache("users", String.class, String.class);
        cache.put("user:1", "Alice");
        System.out.println(cache.get("user:1"));

        cacheManager.close();
    }
}

Плюсы: богатая функциональность, поддержка транзакций.
Минусы: тяжеловесность, сложность настройки.

Распределённое кэширование: Redis

Когда одного сервера недостаточно, на помощь приходит Redis — in-memory хранилище данных типа "ключ-значение". В Java для работы с Redis чаще всего используется библиотека Jedis или Lettuce.

Пример с Jedis

import redis.clients.jedis.Jedis;

public class RedisCache {
    private final Jedis jedis = new Jedis("localhost", 6379);

    public void set(String key, String value, int ttlSeconds) {
        jedis.setex(key, ttlSeconds, value);
    }

    public String get(String key) {
        return jedis.get(key);
    }

    public void delete(String key) {
        jedis.del(key);
    }

    public static void main(String[] args) {
        RedisCache cache = new RedisCache();
        cache.set("session:123", "user_data", 3600);
        System.out.println(cache.get("session:123"));
    }
}

Плюсы Redis:

  • Распределённость — данные доступны с любого узла.
  • Богатые структуры данных (списки, множества, геоданные).
  • Встроенные механизмы TTL и персистентности.

Минусы: требует отдельного сервера, чуть выше задержка по сети.

Memcached — лёгкий и быстрый

Memcached — это распределённый кэш, ориентированный на простоту. В Java используется кли

Блоги

Рекомендаций по книгам