1 В избранное 0 Ответвления 0

OSCHINA-MIRROR/mirrors-JetCache

Клонировать/Скачать
introduce_CN.md 10 КБ
Копировать Редактировать Web IDE Исходные данные Просмотреть построчно История
Отправлено 15.06.2025 22:45 7ea1239

Введение в универсальный кэш-доступный фреймворк JetCache, открытый Alibaba

JetCache — это универсальный кэш-доступный фреймворк, открытый компанией Alibaba. Если вы знакомы с Spring Cache, обязательно потратите немного времени, чтобы ознакомиться с JetCache, он более удобен в использовании.

Основные возможности, предоставляемые JetCache, включают:

  • Предоставление единого интерфейса для доступа к кэшу, аналогичного стилю JSR-107, и возможность создания и конфигурации кэш-экземпляров с помощью аннотаций
  • Реализация декларативного кэширования методов с помощью аннотаций, поддерживающая TTL и двухуровневое кэширование
  • Автоматическое обновление распределенного кэша и поддержка распределенных блокировок (2.2+)
  • Поддержка распределенного многоуровневого кэширования, при котором обновление кэша автоматически делает все локальные кэши недействительными (2.7+)
  • Поддержка асинхронного API кэша
  • Поддержка Spring Boot
  • Возможность настройки стратегий генерации ключей и сериализации значений
  • Автоматическая статистика для всех кэш-экземпляров и методов кэшированияДавайте рассмотрим код. Самый простой сценарий использования выглядит так:
public interface UserService {
    @Cached(expire = 3600, cacheType = CacheType.REMOTE)
    User getUserById(long userId);
}

Это похоже на Spring Cache, но аннотация @Cached нативно поддерживает TTL (время жизни), а параметр cacheType имеет три варианта: LOCAL, REMOTE и BOTH, которые соответственно означают локальный кэш в памяти, удаленный сервер кэша (например, Redis) и двухуровневое кэширование. Выбор зависит от конкретной ситуации, и правильное использование LOCAL или BOTH типов может снизить нагрузку на сервер кэша и ускорить время отклика предоставляемых вами услуг.Рассмотрим более сложный пример:

public interface UserService {
    @Cached(name="userCache-", key="#userId", expire = 3600)
    User getUserById(long userId);

    @CacheUpdate(name="userCache-", key="#user.userId", value="#user")
    void updateUser(User user);
}
```    @CacheInvalidate(name="userCache-", key="#userId")
     void deleteUser(long userId);
 }

В первом примере мы не указываем ключ, и JetCache генерирует его автоматически на основе параметров. В этом примере мы явно указываем ключ и демонстрируем обновление и удаление кэша. Автоматическая перезагрузка и защита от проникновения являются мощными инструментами JetCache, особенно для объектов с высокой стоимостью загрузки, чтобы предотвратить высокую конкуренцию при пропуске кэша и перегрузку базы данных:

public interface SummaryService{
    @Cached(expire = 3600, cacheType = CacheType.REMOTE)
    @CacheRefresh(refresh = 1800, stopRefreshAfterLastAccess = 3600, timeUnit = TimeUnit.SECONDS)
    @CachePenetrationProtect
    BigDecimal salesVolumeSummary(int timeId, long catagoryId);
}

Когда cacheType равен REMOTE или BOTH, поведение перезагрузки является глобально уникальным, то есть даже если сервер приложений является кластером, не будет ситуации, когда несколько серверов одновременно перезагружают один и тот же ключ. Аннотация CachePenetrationProtect гарантирует, что когда кэш пропускает запрос, в одном JVM только один поток будет выполнять метод, а остальные потоки будут ждать результат. Задача перезагрузки ключа инициализируется после первого доступа к ключу. Если ключ долго не используется, задача перезагрузки будет автоматически удалена через время, указанное в stopRefreshAfterLastAccess, что позволяет избежать траты ресурсов на бесполезную перезагрузку.Аннотации, добавленные к методам, в конечном итоге не могут обеспечить самую гибкую форму контроля, поэтому JetCache предоставляет API кэша, который используется аналогично Map:```java UserDO user = userCache.get(12345L); userCache.put(12345L, loadUserFromDataBase(12345L)); userCache.remove(12345L);

userCache.computeIfAbsent(1234567L, (key) -> loadUserFromDataBase(1234567L));


Инстансы кэша могут быть созданы через CacheManager (в версии 2.7 аннотация CreateCache была отменена), и в случае одинакового area и name, они используют один и тот же инстанс кэша, как и аннотация @Cached:

```java
@Autowired
private CacheManager cacheManager;
private Cache<String, UserDO> userCache;

@PostConstruct
public void init() {
    QuickConfig qc = QuickConfig.newBuilder("userCache")
        .expire(Duration.ofSeconds(100))
        .cacheType(CacheType.BOTH) // two level cache
        .syncLocal(true) // invalidate local cache in all jvm processes after update
        .build();
    userCache = cacheManager.getOrCreateCache(qc);
}

Также можно создать инстансы кэша с помощью билдера, аналогичного guava cache/caffeine (это низкоуровневый API):

GenericObjectPoolConfig pc = new GenericObjectPoolConfig();
pc.setMinIdle(2);
pc.setMaxIdle(10);
pc.setMaxTotal(10);
JedisPool pool = new JedisPool(pc, "127.0.0.1", 6379);
Cache<Long, UserDO> userCache = RedisCacheBuilder.createRedisCacheBuilder()
                .keyConvertor(FastjsonKeyConvertor.INSTANCE)
                .valueEncoder(JavaValueEncoder.INSTANCE)
                .valueDecoder(JavaValueDecoder.INSTANCE)
                .jedisPool(pool)
                .keyPrefix("userCache-")
                .expireAfterWrite(200, TimeUnit.SECONDS)
                .buildCache();

API кэша поддерживает асинхронные операции:

CacheGetResult r = cache.GET(userId);
CompletionStage<ResultData> future = r.future();
future.thenRun(() -> {
    if (r.isSuccess()) {
        System.out.println(r.getValue());
    }
});

Также можно реализовать нестрогую распределенную блокировку:

cache.tryLockAndRun("key", 60, TimeUnit.SECONDS, () -> heavyDatabaseOperation());
```Использование инстансов кэша также позволяет настроить автоматическое обновление:

```java
@PostConstruct
public void init() {
    QuickConfig qc = QuickConfig.newBuilder("userCache")
        .refreshPolicy(RefreshPolicy.newPolicy(60, TimeUnit.SECONDS))
        .build();
    userCache = cacheManager.getOrCreateCache(qc);
}

Низкоуровневый API также позволяет создать автоматическое обновление:

Cache<String, Long> orderSumCache = RedisCacheBuilder.createRedisCacheBuilder()
    ......省略
    .refreshPolicy(RefreshPolicy.newPolicy(60, TimeUnit.SECONDS))
    .loader(this::loadOrderSumFromDatabase)
    .buildCache();

Поддерживаемые системы кэширования включают следующие 4, и добавление новой системы кэширования также является простым процессом:

  • Caffeine (локальное кэширование)
  • LinkedHashMap (локальное кэширование, простая реализация LRU кэширования в JetCache)
  • Alibaba Tair (реализация не открыта в Github, доступна на внутреннем Gitlab в Alibaba)
  • Redis (с разными способами доступа: jedis, lettuce, spring-data, redisson)

Требования к системе для использования JetCache:

  • JDK: обязательно Java 8
  • Spring Framework (необязательно, если используется низкоуровневый API): jetcache2.5 требует 4.0.8 и выше, jetcache2.7 требует 5.2.4 и выше
  • Spring Boot (необязательно): jetcache2.5 требует 1.1.9 и выше, jetcache2.7 требует 2.2.5 и выше

Дополнительная документация доступна в разделе docs репозитория на Github.

С помощью JetCache нам становится легче использовать единый интерфейс для доступа к кэшу.

Опубликовать ( 0 )

Вы можете оставить комментарий после Вход в систему

1
https://api.gitlife.ru/oschina-mirror/mirrors-JetCache.git
git@api.gitlife.ru:oschina-mirror/mirrors-JetCache.git
oschina-mirror
mirrors-JetCache
mirrors-JetCache
master