gpt4 book ai didi

java - spring data redis主从配置

转载 作者:IT王子 更新时间:2023-10-29 06:00:40 27 4
gpt4 key购买 nike

以下是我的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,奴隶在本地主机。

谢谢!

最佳答案

此时 Spring Data Redis 中没有配置选项可以启用所需的行为。 Jedis 本身也不提供对这种情况的支持(参见 jedis #458)。RedisConnection 在执行操作时从工厂请求连接。此时所请求资源的使用目的尚不清楚,因为命令可能是 rwrw

一个潜在的解决方案是自定义 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);
}
}
}

上面的解决方案存在几个问题。例如。 MULTI EXEC 您应用程序中的 block 可能不再按预期工作,因为命令现在可能会通过管道传输到您不希望它们到达的位置。因此,为了专用的读取写入 目的,拥有多个 RedisTemplates 可能也是有意义的。

关于java - spring data redis主从配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29527738/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com