ICode9

精准搜索请尝试: 精确搜索
首页 > 数据库> 文章详细

java – spring data redis master slave config

2019-07-28 07:19:46  阅读:227  来源: 互联网

标签:spring-data-redis jedis java spring redis


以下是我的jedis配置

@Bean
public JedisConnectionFactory getJedisConnectionFactory() {
    JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory();
    jedisConnectionFactory.setUsePool(true);
    return jedisConnectionFactory;
}

@Bean
public RedisTemplate<String, Object> getRedisTemplate() {
    RedisTemplate<String, Object> redisTemplate = new RedisTemplate<String, Object>();
    redisTemplate.setConnectionFactory(getJedisConnectionFactory());
    return redisTemplate;
}

当我有单个服务器时,此配置很有效.我想要做的是拥有1个redis master和多个redis slave.根据redis文档,读取应该从slave发生,写入应该从master发生.如何更改上述配置以使用master进行写入和slave进行读取?

可以说我的主人在192.168.10.10,奴隶在localhost.

谢谢!

解决方法:

目前,Spring Data Redis中没有可以实现所需行为的配置选项. Jedis也没有为这种情况提供支持(见jedis #458).
RedisConnection在执行操作时请求来自工厂的连接.此时,请求它的资源的使用目的不明确,因为命令可能是r,w或rw.

一个可能的解决方案是自定义RedisConnectionFactory,它能够提供连接 – 在您执行只读命令的情况下为您拥有的一个从属设备.

SlaveAwareJedisConnectionFactory factory = new SlaveAwareJedisConnectionFactory();
factory.afterPropertiesSet();

RedisConnection connection = factory.getConnection();

// writes to master
connection.set("foo".getBytes(), "bar".getBytes());

// reads from slave
connection.get("foo".getBytes());

/**
 * SlaveAwareJedisConnectionFactory wraps JedisConnection with a proy that delegates readonly commands to slaves.
 */
class SlaveAwareJedisConnectionFactory extends JedisConnectionFactory {

  /**
    * Get a proxied connection to Redis capable of sending
    * readonly commands to a slave node
    */
  public JedisConnection getConnection() {

    JedisConnection c = super.getConnection();

    ProxyFactory proxyFactory = new ProxyFactory(c);
    proxyFactory.addAdvice(new ConnectionSplittingInterceptor(this));
    proxyFactory.setProxyTargetClass(true);

    return JedisConnection.class.cast(proxyFactory.getProxy());
  };

  /**
   * This one will get the connection to one of the slaves to read from there
   * 
   * @return
   */
  public RedisConnection getSlaveConnection() {

    //TODO: find the an available slave serving the data
    return new JedisConnection(new Jedis("your slave host lookup here"));
  }

  static class ConnectionSplittingInterceptor implements MethodInterceptor,
      org.springframework.cglib.proxy.MethodInterceptor {

    private final SlaveAwareJedisConnectionFactory factory;

    public ConnectionSplittingInterceptor(SlaveAwareJedisConnectionFactory factory) {
      this.factory = factory;
    }

    @Override
    public Object intercept(Object obj, Method method, Object[] args, MethodProxy proxy) throws Throwable {

      RedisCommand commandToExecute = RedisCommand.failsafeCommandLookup(method.getName());

      if (!commandToExecute.isReadonly()) {
        return invoke(method, obj, args);
      }

      RedisConnection connection = factory.getSlaveConnection();

      try {
        return invoke(method, connection, args);
      } finally {
        // properly close the connection after executing command
        if (!connection.isClosed()) {
          connection.close();
        }
      }
    }

    private Object invoke(Method method, Object target, Object[] args) throws Throwable {

      try {
        return method.invoke(target, args);
      } catch (InvocationTargetException e) {
        throw e.getCause();
      }
    }

    @Override
    public Object invoke(MethodInvocation invocation) throws Throwable {
      return intercept(invocation.getThis(), invocation.getMethod(), invocation.getArguments(), null);
    }
  }
}

上面的解决方案存在几个问题.例如.您的应用程序中的多个EXEC块可能不再按预期工作,因为现在命令可能会在您不希望它们的某个地方发送.因此,将多个RedisTemplate用于专用读写目的也许是有意义的.

标签:spring-data-redis,jedis,java,spring,redis
来源: https://codeday.me/bug/20190728/1559147.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有