java – spring data redis master slave config
发布时间:2020-12-15 04:26:37 所属栏目:Java 来源:网络整理
导读:以下是我的jedis配置 @Beanpublic JedisConnectionFactory getJedisConnectionFactory() { JedisConnectionFactory jedisConnectionFactory = new JedisConnectionFactory(); jedisConnectionFactory.setUsePool(true); return jedisConnectionFactory;}@Bea
以下是我的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用于专用读写目的也许是有意义的. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |