2015-09-30 19 views
12

Sto usando redis con Akka quindi non ho bisogno di chiamate di blocco. La lattuga ha incorporato una chiamata asincrona. Ma Jedis è il cliente consigliato da Redis. Qualcuno può dirmi se sto usando entrambi nel modo giusto. Se è così quale è meglio.Jedis e Lettuce async abilità

Jedi Sto usando un pool statico collegamento Jedi per avere condizionata e utilizzando Akka futuro callback per elaborare il risultato. La mia preoccupazione qui è quando uso un altro thread (callable) per ottenere il risultato che il thread sta per bloccare il risultato. Mentre Lettuce potrebbe avere un modo più efficiente di farlo.

private final class OnSuccessExtension extends OnSuccess<String> { 
      private final ActorRef senderActorRef; 
      private final Object message; 
      @Override 
      public void onSuccess(String valueRedis) throws Throwable { 
       log.info(getContext().dispatcher().toString()); 
       senderActorRef.tell((String) message, ActorRef.noSender()); 
      } 
      public OnSuccessExtension(ActorRef senderActorRef,Object message) { 
        this.senderActorRef = senderActorRef; 
        this.message=message; 
       } 
     } 
     ActorRef senderActorRef = getSender(); //never close over a future 
      if (message instanceof String) { 
     Future<String> f =akka.dispatch.Futures.future(new Callable<String>() { 
        public String call() { 
         String result; 
         try(Jedis jedis=JedisWrapper.redisPool.getResource()) { 
          result = jedis.get("name"); 
         } 
         return result; 
        } 
       }, ex); 
       f.onSuccess(new OnSuccessExtension(senderActorRef,message), ex); 
    } 

LATTUGA

ExecutorService executorService = Executors.newFixedThreadPool(10); 
public void onReceive(Object message) throws Exception { 
     ActorRef senderActorRef = getSender(); //never close over a future 
     if (message instanceof String) { 

      final RedisFuture<String> future = lettuce.connection.get("name"); 
      future.addListener(new Runnable() { 
       final ActorRef sender = senderActorRef; 
       final String msg =(String) message; 
       @Override 
       public void run() { 
        try { 
         String value = future.get(); 
         log.info(value); 
         sender.tell(message, ActorRef.noSender()); 
        } catch (Exception e) { 
        } 
       } 
      }, executorService); 

Se lattuga è una scelta migliore per le chiamate asincrone. Quindi che tipo di esecutore dovrei andare con in ambiente di produzione. Se possibile, posso utilizzare un dispatcher Akka come contesto di esecuzione per la chiamata futura Letture.

risposta

24

Non c'è una risposta alla tua domanda perché dipende.

Jedis e lattuga sono entrambi clienti maturi. Per completare l'elenco dei client Java, c'è anche Redisson, che aggiunge un altro livello di astrazione (interfacce Collection/Queue/Lock/... invece dei comandi Redis non elaborati).

Dipende molto da come si lavora con i clienti. In generale, Redis è single-threaded in termini di accesso ai dati, quindi l'unico vantaggio che si ottiene dalla concorrenza sta scaricando il protocollo e l'I/O funziona su thread diversi. Questo non è del tutto vero per lattuga e Redisson poiché usano netty sotto il cofano (netty lega un canale socket a un particolare thread del ciclo di eventi).

Con Jedis, è possibile utilizzare una sola connessione solo con un thread alla volta. Ciò si correla bene con il modello di attore di Akka perché un'istanza di attore è occupata solo da un thread alla volta.

Dall'altro lato, occorrono tanto connessioni Jedis quanto thread che si occupano di un particolare attore. Se inizi a condividere le connessioni Jedis tra diversi attori, puoi fare il pooling delle connessioni oppure devi disporre di una connessione Jedis dedicata per ogni istanza di attore. Si prega di tenere presente che è necessario occuparsi della riconnessione (una volta che una connessione Redis è interrotta) da soli.

Con Redisson e lattuga, si ottiene la riconnessione trasparente se si desidera farlo (questo è il valore predefinito di lattuga, non è sicuro di Redisson).

Utilizzando lattuga e Redisson è possibile condividere una connessione tra tutti gli attori perché sono thread-safe. Non è possibile condividere una connessione lattuga in due casi:

  1. operazioni (dal momento che sarebbe bloccare tutti gli altri utenti della connessione)
  2. transazioni (MULTI/EXEC, dal momento che sarebbe mescolare diverse operazioni con le transazioni e che il blocco è certamente una cosa che non si vuole fare)

Jedis non ha un'interfaccia asincrona, quindi è necessario farlo da soli. È fattibile, e ho fatto qualcosa di simile con MongoDB, scaricando/disaccoppiando la parte I/O verso altri attori.È possibile utilizzare l'approccio dal codice, ma non è necessario fornire un proprio servizio executor perché si eseguono operazioni non bloccanti nel listener eseguibile.

Con la lattuga 4.0 si ottiene il supporto per Java 8 (che è decisamente migliore in termini di API asincrona grazie all'interfaccia di CompletionStage) e si può persino utilizzare RxJava (programmazione reattiva) per avvicinarsi alla concorrenza.

La lattuga non è disponibile per il modello di concorrenza. Ti permette di usarlo secondo le tue necessità, eccetto la semplice API Future/ListenableFuture di Java 6/7 e Guava non è molto bello da usare.

HTH, Mark