Comment rafraîchir automatiquement le Cache en utilisant Google Guava?

J'utilise la Bibliothèque Google Guava pour la mise en cache. Pour le rafraîchissement automatique du cache, Nous pouvons faire comme suit:

cache = CacheBuilder.newBuilder()               
                    .refreshAfterWrite(15, TimeUnit.MINUTES)
                    .maximumSize(100)
                    .build(....);

Cependant, les rafraîchissements automatiques sont effectués lorsque la première demande périmée pour une entrée se produit.

y a-t-il un moyen de le rafraîchir automatiquement même si aucune requête n'est venue pour les données de cache? comme pour toutes les 15 minutes les données de cache devraient être extraites de Db et les charger, peu importe si quelqu'un a appelé les données de cache ou pas.

de plus, le temps d'expiration du cache de Guava est pour tout le cache. est-il possible d'expirer les valeurs de cache basées sur la clé? comme les données de cache avec la touche " NOT_SO_FREQ_CHANGE_DATA "à expirer toutes les 1 heure et les données avec la touche" FREQ_CHANGING_DATA " devraient expirer toutes les 15 minutes?

20
demandé sur Sean Patrick Floyd 2012-07-13 07:21:08

4 réponses

Guava ne fournit aucun moyen de rafraîchir le cache en vrac, mais vous pouvez programmer un rafraîchissement périodique vous-même:

LoadingCache<K, V> cache = CacheBuilder.newBuilder()
        .refreshAfterWrite(15, TimeUnit.MINUTES)
        .maximumSize(100)
        .build(new MyCacheLoader());

for (K key : cache.asMap().keySet()) {
    cache.refresh(key);
}

mais dans ce cas, vous pouvez vouloir Outrepasser le CacheBuilder.reload(K, V) méthode MyCacheLoader donc il fonctionne de façon asynchrone.

pour ce qui est de la deuxième question, non, vous ne pouvez pas fixer une échéance par entrée en Goyave.

21
répondu Frank Pavageau 2012-07-13 08:30:16

première question. Utilisez un exécuteur pour lancer un rafraîchissement périodique.

2e question. Si vous pouvez déduire votre politique d'expiration à partir de votre clé de cache, ou de la valeur précédemment mise en cache, il est possible de vous rafraîchir les données à intervalles variables.

basé sur ceci: https://code.google.com/p/guava-libraries/wiki/CachesExplained#Refresh

LoadingCache<Key, Graph> graphs = CacheBuilder.newBuilder()
   .refreshAfterWrite(1, TimeUnit.MINUTES)
   .build(
       new CacheLoader<Key, Graph>() {
         public Graph load(Key key) { // no checked exception
           return getGraphFromDatabase(key);
         }

         public ListenableFuture<Graph> reload(final Key key, Graph prevGraph) {
           if (!needsRefresh(key,prevGraph)) {
             return Futures.immediateFuture(prevGraph);
           } else {
             // asynchronous!
             ListenableFutureTask<Graph> task = ListenableFutureTask.create(new Callable<Graph>() {
               public Graph call() {
                 return getGraphFromDatabase(key);
               }
             });
             executor.execute(task);
             return task;
           }
         }
       });

ScheduledExecutorService ses = Executors.newSingleThreadScheduledExecutor();
ses.scheduleWithFixedDelay(
    new Runnable() {
        public void run() {
            for (Key key : graphs.asMap().keySet()) {
                graphs.refresh(key);
            }
        }
    }, 0, UPDATE_INTERVAL, TimeUnit.MINUTES);
5
répondu McKidoubled 2013-10-16 17:41:37

version JAVA 8 avec flux parallèle:

Executors
        .newSingleThreadScheduledExecutor()
        .scheduleWithFixedDelay(() -> configurationCache
                .asMap()
                .keySet()
                .parallelStream()
                .forEach((key) -> configurationCache.refresh(key)),
            0,
            1, TimeUnit.SECONDS);
4
répondu Çağatay Gürtürk 2017-03-24 09:18:56

voici un exemple de code pour rafraîchir un cache. Guava cache est facile à mettre en œuvre et aussi il est rapide.

import java.util.concurrent.ExecutionException
import java.util.concurrent.TimeUnit;

import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

public class GuavaTest {
    private static GuavaTest INSTANCE = new GuavaTest();

    public static GuavaTest getInstance(){
        return INSTANCE;
    }   

    private LoadingCache<String,String> cache;

    private GuavaTest() {
        cache = CacheBuilder.newBuilder()
                .refreshAfterWrite(2,TimeUnit.SECONDS)
                .build(new CacheLoader<String, String>() {
                        @Override
                        public String load(String arg0) throws Exception {
                            return addCache(arg0);
                        }
                });
    }

    private String addCache(String arg0) {
        System.out.println("Adding Cache");
        return arg0.toUpperCase();
    }

    public String getEntry(String args) throws ExecutionException{
        System.out.println(cache.size());
        return cache.get(args);
    }

    public static void main(String[] args) {
        GuavaTest gt = GuavaTest.getInstance();
        try {
            System.out.println(gt.getEntry("java"));
            System.out.println(gt.getEntry("java"));
            Thread.sleep(2100);
            System.out.println(gt.getEntry("java"));
            System.out.println(gt.getEntry("java"));
        } catch (ExecutionException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

}

j'ai renvoyé cet article goyave cache exemple

-1
répondu Java Rocks 2015-11-18 18:26:29