API de cache de objeto Java leve [fechado]

99

Questão

Estou procurando uma API de cache de objeto Java na memória. Alguma recomendação? Que soluções você usou no passado?

Atual

No momento, estou apenas usando um mapa:

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

Requisitos

Preciso estender o cache para incluir recursos básicos como:

  • tamanho máximo
  • Tempo de Viver

No entanto, não preciso de recursos mais sofisticados, como:

  • Acesso de vários processos (servidor de cache)
  • Persistência (para o disco)

Sugestões

Cache na memória:

  • Guava CacheBuilder - desenvolvimento ativo. Veja esta apresentação .
  • LRUMap - Config via API. Sem TTL. Não foi criado especificamente para armazenamento em cache.
  • whirlycache - configuração XML. Lista de mala direta. Última atualização em 2006.
  • cache4j - configuração XML. Documentação em russo. Última atualização em 2006.

Cache empresarial:

  • JCS - configuração de propriedades. Documentação extensa.
  • Ehcache - configuração XML. Documentação extensa. De longe o mais popular de acordo com os acessos do Google.
Chase Seibert
fonte
3
Você pode editar a seção Sugestões de cache na memória para incluir o Guava Cache? Eu estava procurando por um mecanismo de cache leve como você e encontrei esta pergunta, mas não encontrei Guava porque está muito baixo. Agora eu uso o pacote de cache de goiaba, e é INCRÍVEL.
andras
1
Feito. :-) Que bom que gostou!
Kevin Bourrillion
Talvez você também queira adicionar o relativamente novo cache2k . Em sua página de benchmarks é dito que ele tem um desempenho muito melhor do que o ehcache e o Guava.
user3001
Experimente a @Cacheablepartir de aspectos jcabi
yegor256

Respostas:

57

EHCache é muito bom. Você pode criar um cache na memória. Confira seus exemplos de código para obter um exemplo de criação de um cache na memória. Você pode especificar um tamanho máximo e um tempo de vida.

O EHCache oferece alguns recursos avançados, mas se você não estiver interessado em usá-los, não faça isso. Mas é bom saber que eles estão lá se seus requisitos mudarem.

Aqui está um cache na memória. Criado em código, sem arquivos de configuração.

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

Cria um cache que comporta 200 elementos e tem um ttl de 24 horas.

Steve K
fonte
2
O EHCache apenas se refere ao objeto ou serializa e desserializa o objeto?
Phương Nguyễn
2
EHCache é uma solução pesada? Estamos pesquisando soluções de cache existentes para implementar um cache de API no Android.
Matthias
2
É muito pesado para o Android. Estou usando o cache do Kitty e é tão perfeito!
Felipe,
@Stevet K, estou atrasado para saber essa tecnologia de Cache, mas acho que getInstance () foi removido ou alterado.
Menai Ala Eddine - Aladdin
46

Eu realmente gosto do MapMakerque vem com o Google Guava ( API )

O JavaDoc tem um exemplo bastante interessante que demonstra sua facilidade de uso e seu 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);
         }
       });

Além disso, a versão 10.0 do Guava introduziu um com.google.common.cachepacote muito mais extenso (há uma boa entrada no wiki sobre como usá-los ).

Joachim Sauer
fonte
@mxttie: obrigado, adicionei o link, fique à vontade para sugerir uma edição para adições como essa.
Joachim Sauer
10

Você também pode verificar minha pequena biblioteca de cache chamada KittyCache em:

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

Existem alguns benchmarks de desempenho em relação ao ehcache.

É usado no projeto SimpleJPA como um cache de segundo nível.

Travis Reeder
fonte
1
Legal, mas se ao menos tivesse TTL.
Rosdi Kasim
Obrigado ! apenas o código que eu estava digitando antes de pensar em verificar se alguém já abriu o código-fonte :)
jpillora
@RosdiKasim ele realmente tem TTL na chamada put (), por exemplo: cache.put ("mykey", valor, 500); 500 é TTL.
Travis Reeder
1
@TravisR Bem ..., não tinha TTL naquela época ..: p
Rosdi Kasim
Ahh, não percebi há quanto tempo esse comentário foi.
Travis Reeder
9

Você pode verificar LinkedHashMap para implementar um cache simples sem jars de terceiros:

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

então você pode obter do cache 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 deixado como exercício para o leitor :)

JeeBee
fonte
2
Não acho que esse método tenha capacidade TTL. No entanto, seria um bom começo para rolar por conta própria.
Chase Seibert
Sim, vou deixar as coisas do TTL como parte do exercício do leitor: p - e é claro que as bibliotecas de terceiros terão sido testadas muito mais do que lançar as suas próprias.
JeeBee
5

JCS é testado e comprovado. Mesmo que seja leve no que diz respeito aos mecanismos de cache, você pode cavar no código real e imitar o que eles fazem com o HashMap nos bastidores para exatamente o que você precisa e nada mais. Você parece ter uma boa ideia do que está procurando.

Ichorus
fonte
Suponho que você queira dizer que não é leve no que diz respeito aos mecanismos de cache? No entanto, parece ser uma das soluções empresariais mais populares.
Chase Seibert