2015-09-30 15 views
12

Tôi đang sử dụng redis với Akka nên tôi không cần chặn cuộc gọi. Rau diếp có cuộc gọi không đồng bộ trong tương lai được tích hợp vào nó. Nhưng Jedis là khách hàng được đề nghị bởi Redis. Ai đó có thể cho tôi biết nếu tôi đang sử dụng cả hai cách đúng đắn. Nếu vậy thì cái nào tốt hơn.Jedis và Rau diếp khả năng không đồng bộ

JEDIS Tôi đang sử dụng hồ bơi kết nối Jedis tĩnh để nhận con và sử dụng gọi lại trong tương lai của Akka để xử lý kết quả. Mối quan tâm của tôi ở đây là khi tôi sử dụng một luồng khác (có thể gọi) để nhận được kết quả mà luồng cuối cùng sẽ chặn cho kết quả. Trong khi rau diếp có thể có một số cách hiệu quả hơn để làm điều này.

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

rau diếp

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

Nếu rau diếp là một lựa chọn tốt hơn cho các cuộc gọi async. Sau đó, loại người thực hiện tôi nên đi với trong môi trường sản xuất. Nếu có thể, tôi có thể sử dụng một điều phối viên Akka như một bối cảnh thực hiện cho cuộc gọi tương lai Letture.

Trả lời

24

Không có câu trả lời cho câu hỏi của bạn bởi vì nó phụ thuộc.

Rau diếp và rau diếp là cả hai khách hàng trưởng thành. Để hoàn thành danh sách các máy khách Java, cũng có Redisson, nó thêm một lớp trừu tượng khác (các giao diện Collection/Queue/Lock/... thay vì các lệnh Redis thô).

Nó phụ thuộc khá nhiều vào cách bạn làm việc với khách hàng. Nói chung, Redis là đơn luồng trong điều khoản của truy cập dữ liệu, vì vậy lợi ích duy nhất bạn đạt được bằng cách đồng thời là offloading giao thức và I/O làm việc với các chủ đề khác nhau. Điều đó không hoàn toàn đúng với rau diếp và Redisson vì chúng sử dụng netty dưới mui xe (netty liên kết một kênh socket với một chuỗi vòng lặp sự kiện cụ thể).

Với Jedis, bạn chỉ có thể sử dụng một kết nối chỉ với một chuỗi tại một thời điểm. Điều đó tương quan độc đáo với mô hình diễn viên Akka bởi vì một cá thể diễn viên chỉ bị chiếm bởi một luồng tại một thời điểm.

Mặt khác, bạn cần có nhiều kết nối Jedis làm chủ đề xử lý một diễn viên cụ thể. Nếu bạn bắt đầu chia sẻ các kết nối Jedis trên các diễn viên khác nhau, bạn hoặc là đi để kết nối tổng hợp, hoặc bạn cần phải có một kết nối Jedis chuyên dụng cho mỗi cá thể diễn viên. Hãy ghi nhớ rằng bạn cần phải chăm sóc việc kết nối lại (một khi kết nối Redis bị hỏng) của chính bạn.

Với Redisson và rau diếp, bạn sẽ nhận được kết nối lại trong suốt nếu bạn muốn làm như vậy (Đó là giá trị mặc định cho rau diếp, không chắc chắn về Redisson).

Bằng cách sử dụng rau diếp và Redisson, bạn có thể chia sẻ một kết nối giữa tất cả các tác nhân vì chúng an toàn chỉ. Bạn không thể chia sẻ một kết nối rau diếp trong hai trường hợp:

  1. Chặn hoạt động (vì bạn sẽ chặn tất cả các người dùng khác của kết nối)
  2. giao dịch (MULTI/EXEC, vì bạn sẽ trộn các hoạt động khác nhau với các giao dịch và chắc chắn là một điều bạn không muốn làm như vậy)

Jedis không có giao diện không đồng bộ, do đó bạn được yêu cầu tự làm điều này. Đó là khả thi, và tôi đã làm một cái gì đó tương tự với MongoDB, offloading/tách phần I/O cho các diễn viên khác.Bạn có thể sử dụng cách tiếp cận từ mã của bạn, nhưng bạn không bắt buộc phải cung cấp một dịch vụ thực thi riêng bởi vì bạn thực hiện các thao tác không chặn trong trình nghe runnable.

Với rau diếp 4.0, bạn sẽ nhận được hỗ trợ Java 8 (cách tốt hơn về API async vì giao diện CompletionStage) và thậm chí bạn có thể sử dụng RxJava (lập trình phản ứng) để tiếp cận đồng thời.

Rau diếp không được đưa ra ý kiến ​​về mô hình đồng thời của bạn. Nó cho phép bạn sử dụng nó theo nhu cầu của bạn, ngoại trừ đồng bằng Future/ListenableFuture API của Java 6/7 và Ổi không phải là rất tốt đẹp để sử dụng.

HTH, Mark

Các vấn đề liên quan