100 votes

API légère de cache d'objets Java

Pregunta

Je suis à la recherche d'une API Java de mise en cache d'objets en mémoire. Des recommandations ? Quelles solutions avez-vous utilisées dans le passé ?

Actuel

Pour l'instant, je n'utilise qu'une carte :

Map cache = new HashMap<String, Object>();
cache.put("key", value);

Exigences

J'ai besoin d'étendre le cache pour inclure des fonctionnalités de base comme :

  • Taille maximale
  • Le temps de vivre

Cependant, je n'ai pas besoin de fonctionnalités plus sophistiquées comme :

  • Accès à partir de plusieurs processus (serveur cache)
  • Persistance (sur disque)

Suggestions

Mise en cache en mémoire :

  • Goyave CacheBuilder - développement actif. Voir ce site présentation .
  • LRUMap - Configuration via API. Pas de TTL. Pas conçu pour la mise en cache.
  • whirlycache - Configuration XML. Liste de diffusion. Dernière mise à jour : 2006.
  • cache4j - Configuration XML. Documentation en russe. Dernière mise à jour : 2006.

Mise en cache de l'entreprise :

  • JCS - Configuration des propriétés. Documentation complète.
  • Ehcache - Configuration XML. Documentation complète. De loin le plus populaire selon les résultats de Google.

3 votes

Pouvez-vous modifier la section Suggestions de mise en cache en mémoire pour y inclure Guava Cache ? Je cherchais un mécanisme de mise en cache léger, comme vous, et j'ai trouvé cette question, mais je n'ai pas trouvé Guava parce qu'il est très bas. Maintenant, j'utilise le paquet guava cache, et c'est INCROYABLE.

1 votes

Fait. :-) Très heureux que cela vous plaise !

0 votes

Peut-être voudrez-vous également envisager d'ajouter la relativement récente cache2k . Sur leur page des repères il est dit qu'il a de bien meilleures performances que ehcache et Guava.

58voto

Steve K Points 10475

EHCache est très agréable. Vous pouvez créer un cache en mémoire. Consultez leur échantillons de code pour un exemple de création d'un cache en mémoire. Vous pouvez spécifier une taille maximale, et un temps de vie.

EHCache offre quelques fonctionnalités avancées, mais si vous ne souhaitez pas les utiliser, ne le faites pas. Mais il est bon de savoir qu'elles sont là si vos besoins changent.

Voici un cache en mémoire. Créé en code, sans fichier de configuration.

CacheManager cacheManager = CacheManager.getInstance();
int oneDay = 24 * 60 * 60;
Cache memoryOnlyCache = new Cache("name", 200, false, false, oneDay, oneDay);
cacheManager.addCache(memoryOnlyCache);

Crée un cache qui contiendra 200 éléments et aura un ttl de 24 heures.

2 votes

EHCache se contente-t-il de faire référence à l'objet ou sérialise-t-il puis désérialise-t-il l'objet ?

2 votes

EHCache est-il une solution lourde ? Nous étudions les solutions de mise en cache existantes pour mettre en œuvre un cache d'API sur Android.

2 votes

C'est trop lourd pour Android. J'utilise Kitty cache et c'est tellement parfait !

47voto

Joachim Sauer Points 133411

J'aime beaucoup le MapMaker qui vient avec Google Guava ( API )

La JavaDoc contient un exemple très intéressant qui démontre à la fois sa facilité d'utilisation et sa puissance :

ConcurrentMap<Key, Graph> graphs = new MapMaker()
   .concurrencyLevel(32)
   .softKeys()
   .weakValues()
   .expiration(30, TimeUnit.MINUTES)
   .makeComputingMap(
       new Function<Key, Graph>() {
         public Graph apply(Key key) {
           return createExpensiveGraph(key);
         }
       });

De plus, la version 10.0 de Guava a introduit la fonction beaucoup plus étendue de com.google.common.cache paquet (il y a un une belle entrée wiki sur la façon de les utiliser ).

0 votes

0 votes

@mxttie : merci, j'ai ajouté le lien, n'hésitez pas à suggérer une édition pour des ajouts comme celui-ci.

10voto

Travis R Points 8935

Vous pouvez également consulter ma petite bibliothèque de cache appelée KittyCache à l'adresse suivante :

https://github.com/treeder/kitty-cache

Il y a quelques benchmarks de performance par rapport à ehcache.

Il est utilisé dans le SimpleJPA en tant que cache de deuxième niveau.

1 votes

Joli, mais si seulement il avait le TTL.

0 votes

Merci ! C'est juste le code que j'étais en train de taper avant de penser à vérifier si quelqu'un n'a pas déjà mis en place une source ouverte :)

0 votes

@RosdiKasim il y a effectivement un TTL sur l'appel put(), par exemple : cache.put("mykey", value, 500) ; 500 est le TTL.

9voto

JeeBee Points 11882

Vous pouvez consulter LinkedHashMap pour mettre en œuvre un cache simple sans bocal tiers :

    Map <String, Foo> cache = new LinkedHashMap<String, Foo>(MAX_ENTRIES + 1, .75F, true) {

        public boolean removeEldestEntry(Map.Entry<String, Foo> eldest) {
            return size() > MAX_ENTRIES;
        }
    };

alors vous pouvez obtenir du cache comme

    Foo foo = cache.get(key);
    if (foo == null && !cache.containsKey(key)) {
        try {
            FooDAO fooDAO = DAOFactory.getFooDAO(conn);
            foo = fooDAO.getFooByKey(key);
            cache.put(key, foo);
        } catch (SQLException sqle) {
            logger.error("[getFoo] SQL Exception when accessing Foo", sqle);
        }
    }

le reste est laissé comme exercice pour le lecteur :)

2 votes

Je ne pense pas que cette méthode ait une capacité TTL. Mais ce serait un bon début pour développer votre propre méthode.

0 votes

Ouais, je vais laisser le truc TTL comme faisant partie de l'exercice du lecteur :p - et bien sûr les librairies tierces auront été testées bien plus que de rouler votre propre librairie.

9voto

Bohemian Points 134107

Goyave MapMaker a été remplacé par son CacheBuilder classe.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X