2015-09-30 17 views
12

Używam redis z Akka, więc nie potrzebuję żadnych blokujących połączeń. Sałata ma wbudowane w nią połączenie asynchroniczne. Ale Jedis jest rekomendowanym klientem Redisa. Czy ktoś może mi powiedzieć, czy używam obu w odpowiedni sposób. Jeśli tak, który z nich jest lepszy.Jedi i asynch sałata

JEDIS Używam statycznej puli połączeń Jedis do uzyskania potwierdzenia połączenia i korzystania z przyszłego oddzwaniania Akka w celu przetworzenia wyniku. Moją obawą jest tutaj, kiedy używam innego wątku (wywoływanego), aby uzyskać wynik, który wątek ostatecznie zablokuje dla wyniku. Podczas gdy sałata może mieć bardziej efektywny sposób robienia tego.

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

SAŁATA

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

Jeśli sałata jest lepszym rozwiązaniem dla połączeń transmisji asynchronicznej. Następnie, jakiego typu executor powinienem używać w środowisku produkcyjnym. Jeśli to możliwe, mogę użyć dyspozytora Akka jako kontekstu wykonawczego dla przyszłego połączenia Letture.

Odpowiedz

24

Nie ma jednej odpowiedzi na twoje pytanie, ponieważ to zależy.

Jedi i sałata są dojrzałymi klientami. Aby uzupełnić listę klientów Java, istnieje również Redisson, który dodaje kolejną warstwę abstrakcji (interfejsy Collection/Queue/Lock/... zamiast surowych poleceń Redis).

To zależy od tego, jak pracujesz z klientami. Ogólnie rzecz biorąc, Redis jest jednowątkowy pod względem dostępu do danych, więc jedyną korzyścią uzyskaną dzięki współbieżności jest odciążenie protokołu i operacji we/wy na różne wątki. Nie jest to w pełni zgodne z sałatą i Redisson, ponieważ używają one netty pod maską (netty wiąże jeden kanał gniazda z określonym wątkiem pętli zdarzeń).

W przypadku Jedis można używać tylko jednego połączenia tylko z jednym wątkiem naraz. To ładnie kojarzy się z modelem aktora Akka, ponieważ jedna instancja aktora jest zajęta tylko przez jeden wątek na raz.

Po drugiej stronie, potrzebujesz tak wielu połączeń Jedi jak nici, które dotyczą konkretnego aktora. Jeśli zaczniesz udostępniać połączenia Jedi między różnymi aktorami, albo wybierzesz połączenie, albo musisz mieć dedykowane połączenie Jedis na instancję aktora. Pamiętaj, że musisz sam się zająć ponownym połączeniem (po zerwaniu połączenia Redis).

Z Redisson i sałatą otrzymujesz przejrzyste ponowne połączenie, jeśli chcesz to zrobić (to jest domyślna wartość sałaty, nie wiesz o Redisson).

Za pomocą sałaty i Redisson można dzielić jedno połączenie między wszystkimi aktorami, ponieważ są one wątkowo bezpieczne. Nie można dzielić jedno połączenie sałaty w dwóch przypadkach:

  1. operacji (ponieważ chcesz zablokować wszystkie inne użytkownikom połączenia)
  2. transakcji (MULTI/EXEC, ponieważ będzie mieszać różne operacje z transakcji i że blokowanie to na pewno coś, czego nie chcesz)

Jedis nie ma interfejsu asynchronicznego, więc musisz to zrobić sam. To jest wykonalne i zrobiłem coś podobnego z MongoDB, odciążając/oddzielając część I/O od innych aktorów.Możesz użyć podejścia z kodu, ale nie musisz dostarczać własnej usługi executora, ponieważ wykonujesz operacje bez blokowania w działającym programie nasłuchującym.

Z sałatą 4.0 otrzymasz wsparcie dla Java 8 (co jest o wiele lepsze pod względem asynchronicznego API z powodu interfejsu CompletionStage), a możesz nawet użyć RxJava (programowanie reaktywne), aby zbliżyć się do współbieżności.

Sałata nie jest opiniowana na twoim modelu współbieżności. Pozwala na użycie go zgodnie z twoimi potrzebami, z wyjątkiem zwykłego interfejsu API Java 6/7 i Guava, który nie jest zbyt przyjemny w użyciu.

HTH, Mark

Powiązane problemy