哪个Java客户端支持Redis的分片+ pubsub?

时间:2015-03-26 01:19:59

标签: redis

是否有支持Redis的分片和pubsub的Java客户端?我看着jedis,似乎缺乏支持。

3 个答案:

答案 0 :(得分:3)

<强> TLDR

  1. Jedis确实支持pub / sub,我实际上使用它。
  2. 群集是Redis的功能,Jedis有初始支持
  3. Jedis Pub / Sub

    请查看jedis pub/sub docs以获取扩展参考。举个简单的例子,你可以试试这个:

    class MyListener extends JedisPubSub {
            public void onMessage(String channel, String message) {
            }
    
            public void onSubscribe(String channel, int subscribedChannels) {
            }
    
            public void onUnsubscribe(String channel, int subscribedChannels) {
            }
    
            public void onPSubscribe(String pattern, int subscribedChannels) {
            }
    
            public void onPUnsubscribe(String pattern, int subscribedChannels) {
            }
    
            public void onPMessage(String pattern, String channel,
                String message) {
            }
    }
    
    MyListener l = new MyListener();
    
    jedis.subscribe(l, "foo");
    

    <强>聚类

    对于群集示例,首先阅读redis cluster tutorial以了解这是否符合您的需求是个好主意。

    Jedis为群集提供了初始API,但由于Redis功能本身正在进行中,因此可能会及时更改:

    Set<HostAndPort> jedisClusterNodes = new HashSet<HostAndPort>();
    //Jedis Cluster will attempt to discover cluster nodes automatically
    jedisClusterNodes.add(new HostAndPort("127.0.0.1", 7379));
    JedisCluster jc = new JedisCluster(jedisClusterNodes);
    jc.set("foo", "bar");
    String value = jc.get("foo");
    

    希望这有帮助。

答案 1 :(得分:2)

使用Jedis群集实现pubsub功能的两种棘手方法。

  1. 创建一个集群并从中随机获取两个节点。一个用于pub,一个用于sub。约束是我们不知道节点什么时候会关闭,我们必须定期检查pub / sub连接的可用性,并从集群节点获取新的连接。
  2.   //create cluster
      HashSet<HostAndPort> node = new HashSet<>();
      node.add(new HostAndPort("127.0.0.1", 7000));
      final JedisClusterPubSub cluster = new JedisClusterPubSub(node);
    
      //get all nodes
      Map<String, JedisPool> nodes = cluster.getClusterNodes();
    
      //pick two nodes from the cluster
      final JedisPool pool = nodes.values().iterator().next();
      final JedisPool pool2 = nodes.values().iterator().next();
    
      // publish 
      new Thread(new Runnable() {
        @Override
        public void run() {
    
          try {
            while (true) {
              Thread.sleep(3000);
              pool.getResource().publish("channel", "message");
            }
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }).start();
    
      //subscribe
      pool2.getResource().subscribe(new RequestListener(), "channel");
    
    1. 破解JedisClusterPubSub,扩展它并实现pub / sub选项。这是不安全的方式。
    2. public class JedisClusterPubSub extends JedisCluster{
        public JedisClusterPubSub(Set<HostAndPort> nodes) {
          super(nodes);
        }
      
        public void subscribe(final JedisPubSub pubSub, final String ... channels){
          try {
            Field fieldCH = JedisCluster.class.getDeclaredField("connectionHandler");
            fieldCH.setAccessible(true);
            JedisClusterConnectionHandler connectionHandler = (JedisClusterConnectionHandler)fieldCH.get(this);
      
            Field fieldMR = JedisCluster.class.getDeclaredField("maxRedirections");
            fieldMR.setAccessible(true);
      
            int maxRedirections = (int)fieldMR.get(this);
      
            new JedisClusterCommand<Void>(connectionHandler, maxRedirections) {
              @Override
              public Void execute(Jedis connection) {
                connection.subscribe(pubSub, channels);
                return null;
              }
            }.run("meaningless");
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      
        public void publish(final String channel, final String message){
          try {
            Field fieldCH = JedisCluster.class.getDeclaredField("connectionHandler");
            fieldCH.setAccessible(true);
            JedisClusterConnectionHandler connectionHandler = (JedisClusterConnectionHandler)fieldCH.get(this);
      
            Field fieldMR = JedisCluster.class.getDeclaredField("maxRedirections");
            fieldMR.setAccessible(true);
      
            int maxRedirections = (int)fieldMR.get(this);
      
            new JedisClusterCommand<Void>(connectionHandler, maxRedirections) {
              @Override
              public Void execute(Jedis connection) {
                connection.publish(channel, message);
                return null;
              }
            }.run("meaningless");
          } catch (Exception e) {
            e.printStackTrace();
          }
        }
      }
      

答案 2 :(得分:1)

你应该看看redisson:

https://github.com/mrniko/redisson

它不是使用redis的香草,更像是一个框架。它确实支持群集。 Jedis也支持Pub / Sub。