Когда дело касается кэширования, Java-разработчику первое, что приходит на ум, — это Redis. Использование этого типа кеша достаточно для решения большинства проблем с производительностью. Нам также необходимо знать, что этот тип кеша является удаленным кешем (распределенным кешем). Процессы приложений и процессы кеша обычно распределены по разным серверам, и разные процессы взаимодействуют через RPC. Или общаться через HTTP. Преимущество такого типа кеша заключается в том, что кеш отделен от службы приложений и поддерживает хранение больших объемов данных. Недостаток заключается в том, что данные приходится передавать по сети, что приведет к определенной потере производительности.
Распределенному кешу соответствует локальный кеш. Процесс кэширования и процесс приложения одинаковы, а чтение и запись данных выполняются в одном процессе. Преимущество этого метода заключается в отсутствии сетевых затрат и скорости доступа. это очень быстро. Недостаток — он ограничен памятью JVM и не подходит для хранения больших данных.
Локальный кэш и приложение принадлежат одному и тому же процессу. Неправильное использование повлияет на стабильность службы, поэтому обычно необходимо учитывать больше факторов, таких как ограничения емкости, стратегии истечения срока действия, стратегии удаления, автоматическое обновление и т. д. Обычно используемые решения для локального кэширования включают в себя:
Guava — это библиотека расширения ядра Java с открытым исходным кодом, созданная командой Google. Она включает в себя такие наборы инструментов, как коллекции, примитивы параллелизма, кэш, ввод-вывод и отражение. Она имеет гарантированную производительность и стабильность и широко используется. Guava Cache поддерживает множество функций:
Введение зависимостей
<dependency>
<groupId>com.google.guava</groupId>
<artifactId>guava</artifactId>
<version>18.0</version>
</dependency>
Простой пример:
public class GuavaCacheTest {
public static void main(String[] args) throws Exception {
//Создаем гуаву cache
Cache<String, String> loadingCache = CacheBuilder.newBuilder()
//Начальная емкость кэша
.initialCapacity(5)
//кэшируем максимальное количество кэшей
.maximumSize(10)
//Установим срок действия кэша записи на n секунд позже
.expireAfterWrite(17, TimeUnit.SECONDS)
//Устанавливаем срок действия кэша чтения и записи через n секунд, редко используется на практике, аналогично expireAfterWrite
//.expireAfterAccess(17, TimeUnit.SECONDS)
.build();
String key = "key";
// Запись данных в кэш
loadingCache.put(key, "v");
// Получите значение value. Если ключ не существует, вызовите метод collable, чтобы получить значение, загрузить его в ключ и выполнить возврат.
String value = loadingCache.get(key, new Callable<String>() {
@Override
public String call() throws Exception {
return getValueFromDB(key);
}
});
// Удалить ключ
loadingCache.invalidate(key);
}
private static String getValueFromDB(String key) {
return "v";
}
}
Caffeine — это высокопроизводительная библиотека кэширования, основанная на JAVA 8. А после Spring 5 (Springboot 2.x) Spring официально отказался от Guava и использовал Caffeine с большей производительностью в качестве компонента кэша по умолчанию.
<dependency>
<groupId>com.github.ben-manes.caffeine</groupId>
<artifactId>caffeine</artifactId>
<version>2.5.5</version>
</dependency>
Использование кофеина:
public class CaffeineCacheTest {
public static void main(String[] args) throws Exception {
//Создаем гуаву cache
Cache<String, String> loadingCache = Caffeine.newBuilder()
//Начальная емкость кэша
.initialCapacity(5)
//кэшируем максимальное количество кэшей
.maximumSize(10)
//Установим срок действия кэша записи на n секунд позже
.expireAfterWrite(17, TimeUnit.SECONDS)
//Устанавливаем срок действия кэша чтения и записи через n секунд, редко используется на практике, аналогично expireAfterWrite
//.expireAfterAccess(17, TimeUnit.SECONDS)
.build();
String key = "key";
// Запись данных в кэш
loadingCache.put(key, "v");
// Получите значение value. Если ключ не существует, получите значение и затем вернитесь.
String value = loadingCache.get(key, CaffeineCacheTest::getValueFromDB);
// Удалить ключ
loadingCache.invalidate(key);
}
private static String getValueFromDB(String key) {
return "v";
}
}
По сравнению с Guava Cache Caffeine имеет очевидные преимущества с точки зрения функциональности и производительности. В то же время API этих двух приложений схожи. Код, использующий Guava Cache, можно легко переключить на Caffeine, что позволяет сэкономить на миграции.
EhCache — это чистая среда внутрипроцессного кэширования Java, быстрая и экономичная. Обратите внимание на ключевое слово процесс. Интуиция кэширования на основе процессов подсказывает нам, что эффективность должна быть выше, поскольку оно работает непосредственно внутри процесса, но могут возникнуть проблемы с разделением кэшей между различными приложениями.
EhCache является CacheProvider по умолчанию в Hibernate, и Spring Boot также поддерживает его. Абстракция кэша, предоставляемая Spring, также поддерживает привязку к платформе кэша EhCache и поддерживает использование на основе аннотаций. Таким образом, EhCache — это широко используемая среда кэширования на основе Java, которая также очень удобна в использовании.
EhCache предоставляет различные стратегии кэширования, в основном разделенные на уровни памяти и диска. Это среда кэширования для общего кэша, Java EE и облегченных контейнеров.
<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.8.0</version>
</dependency>
Использование EhCache
public class EncacheTest {
public static void main(String[] args) throws Exception {
// Объявить кэшбилдер
CacheManager cacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.withCache("encacheInstance", CacheConfigurationBuilder
//Объявляем кэш в куче емкостью 20
.newCacheConfigurationBuilder(String.class,String.class, ResourcePoolsBuilder.heap(20)))
.build(true);
// Получить экземпляр кэша
Cache<String,String> myCache = cacheManager.getCache("encacheInstance", String.class, String.class);
// записать кеш
myCache.put("key","v");
// читать кеш
String value = myCache.get("key");
// Удалить и изменить на грубый
cacheManager.removeCache("myCache");
cacheManager.close();
}
}
Вообще, среди решений для локального кэширования лично я рекомендую Caffeine, который по производительности далеко впереди. В реальных бизнес-проектах рекомендуется использовать Caffeine в качестве локального кеша и использовать Redis или Memcache в качестве распределенного кеша для создания многоуровневой системы кеширования для обеспечения производительности и надежности.