API de caché de objetos Java ligera [cerrada]

99

Pregunta

Estoy buscando una API de almacenamiento en caché de objetos en memoria de Java. ¿Alguna recomendación? ¿Qué soluciones ha utilizado en el pasado?

Actual

En este momento, solo estoy usando un mapa:

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

Requisitos

Necesito extender el caché para incluir características básicas como:

  • tamaño máximo
  • Tiempo para vivir

Sin embargo, no necesito funciones más sofisticadas como:

  • Acceso desde múltiples procesos (servidor de caché)
  • Persistencia (al disco)

Sugerencias

Almacenamiento en caché en memoria:

  • Guava CacheBuilder - desarrollo activo. Vea esta presentación .
  • LRUMap : configuración a través de API. Sin TTL. No está diseñado específicamente para el almacenamiento en caché.
  • whirlycache : configuración XML. Lista de correo. Última actualización 2006.
  • cache4j : configuración XML. Documentación en ruso. Última actualización 2006.

Almacenamiento en caché empresarial:

  • JCS : configuración de propiedades. Amplia documentación.
  • Ehcache : configuración XML. Amplia documentación. De lejos, el más popular según los hits de Google.
Chase Seibert
fuente
3
¿Puede editar la sección de caché en memoria de sugerencias para incluir Guava Cache? Estaba buscando un mecanismo de almacenamiento en caché ligero como usted y encontré esta pregunta, pero no encontré a Guava porque está muy abajo. Ahora uso el paquete guava cache, y es INCREÍBLE.
andras
1
Hecho. :-) ¡Me alegro de que te guste!
Kevin Bourrillion
Quizás también quieras considerar agregar el relativamente nuevo cache2k . En su página de puntos de referencia se dice que tiene un rendimiento mucho mejor que ehcache y Guava.
user3001

Respuestas:

57

EHCache es muy bueno. Puede crear un caché en memoria. Consulte sus ejemplos de código para ver un ejemplo de cómo crear un caché en memoria. Puede especificar un tamaño máximo y un tiempo de vida.

EHCache ofrece algunas funciones avanzadas, pero si no está interesado en usarlas, no lo haga. Pero es bueno saber que están ahí si sus requisitos cambian.

Aquí hay un caché en memoria. Creado en código, sin archivos de configuración.

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

Crea un caché que contendrá 200 elementos y tiene un ttl de 24 horas.

Steve K
fuente
2
¿EHCache simplemente se refiere al objeto o serializa y luego deserializa el objeto en su lugar?
Phương Nguyễn
2
¿EHCache es una solución de peso pesado? Estamos buscando soluciones de almacenamiento en caché existentes para implementar una caché de API en Android.
Matthias
2
Es demasiado pesado para Android. ¡Estoy usando el caché de Kitty y es tan perfecto!
Felipe
@Stevet K, llego tarde para conocer esta tecnología de caché, pero supongo que getInstance () se eliminó o cambió.
Menai Ala Eddine - Aladdin
46

Me gusta mucho el MapMakerque viene con Google Guava ( API )

JavaDoc tiene un ejemplo bastante bueno que demuestra tanto su facilidad de uso como su poder:

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);
         }
       });

Además, la versión 10.0 de Guava introdujo un com.google.common.cachepaquete mucho más extenso (hay una buena entrada en la wiki sobre cómo usarlos ).

Joachim Sauer
fuente
@mxttie: gracias, agregué el enlace, siéntase libre de sugerir una edición para adiciones como esta.
Joachim Sauer
10

También puede consultar mi pequeña biblioteca de caché llamada KittyCache en:

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

Hay algunos puntos de referencia de rendimiento frente a ehcache.

Se utiliza en el proyecto SimpleJPA como caché de segundo nivel.

Travis Reeder
fuente
1
Bonito, pero si solo tiene TTL.
Rosdi Kasim
Gracias ! solo el código que estaba escribiendo antes, pensé en verificar si alguien ya había abierto algo :)
jpillora
@RosdiKasim tiene TTL en realidad en la llamada put (), por ejemplo: cache.put ("mykey", value, 500); 500 es TTL.
Travis Reeder
1
@TravisR Bueno ..., no tenía TTL en ese entonces ...: p
Rosdi Kasim
Ahh, no me di cuenta de cuánto tiempo había pasado ese comentario.
Travis Reeder
9

Puede consultar LinkedHashMap para implementar un caché simple sin archivos jar de terceros:

    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;
        }
    };

entonces puedes obtener del caché como

    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);
        }
    }

resto a la izquierda como ejercicio para el lector :)

JeeBee
fuente
2
No creo que este método tenga capacidad TTL. Sin embargo, sería un buen comienzo para rodar el tuyo.
Chase Seibert
Sí, dejaré las cosas de TTL como parte del ejercicio del lector: p - y, por supuesto, las librerías de terceros se habrán probado mucho más que las tuyas propias.
JeeBee
5

JCS está probado y es cierto. A pesar de que es liviano en lo que respecta a los mecanismos de almacenamiento en caché, puede profundizar en el código real e imitar lo que hacen con HashMap debajo de las cubiertas para exactamente lo que necesita y nada más. Parece tener una idea bastante clara de lo que está buscando.

Icoro
fuente
Supongo que quiere decir que no es ligero en lo que respecta a los mecanismos de almacenamiento en caché. Sin embargo, parece ser una de las soluciones empresariales más populares.
Chase Seibert