![](/img/trans.png)
[英]Configuring Spring Data Redis with Lettuce for Redis master/slave
[英]spring data redis master slave config
以下是我的 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 文檔,讀取應該從奴隸發生,寫入應該發生在主人身上。 如何更改上述配置以使用 master 進行寫入和使用 slave 進行讀取?
假設我的主人在 192.168.10.10 而奴隸在本地主機。
謝謝!
目前,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);
}
}
}
上面的解決方案包含幾個問題。 例如。 您的應用程序中的MULTI
EXEC
塊可能不再按預期工作,因為命令現在可能會被傳送到您不希望它們出現的地方。 所以也許有多個RedisTemplates
用於專用的讀、寫目的也是有意義的。
您應該使用Redis Sentinel來保持 redis 的主/從配置...您可以使用下面的連接到哨兵池-
@Bean
public RedisConnectionFactory jedisConnectionFactory() {
RedisSentinelConfiguration sentinelConfig = new RedisSentinelConfiguration() .master("mymaster")
.sentinel("127.0.0.1", 26379) .sentinel("127.0.0.1", 26380);
return new JedisConnectionFactory(sentinelConfig);
}
你想要寫到主從從
這是如何使用 sentinal 集群和 spring-boot 配置它
spring:
data:
redis:
sentinel:
master: mymaster
nodes: my.sentinel.hostname1:26379,my.sentinel.hostname2:26379
port: 6379
和彈簧配置
@Configuration
public class RedisDatasourceConfig {
@Bean
public LettuceClientConfigurationBuilderCustomizer lettuceClientConfigurationBuilderCustomizer() {
return p -> p.readFrom(SLAVE_PREFERRED);
}
}
主/從架構的復制與 Sentinel 不同。
設置redis只讀副本非常簡單。
我的 Spring Boot 應用程序 yaml。
redis:
master:
host: localhost
port: 6379
slaves:
- host: localhost
port: 16379
- host: localhost
port: 26379
對於上述實例,應更新 slaves 實例 redis 配置,如下所示。
################################# REPLICATION #################################
# Master-Replica replication. Use replicaof to make a Redis instance a copy of
# another Redis server. A few things to understand ASAP about Redis replication.
#
# +------------------+ +---------------+
# | Master | ---> | Replica |
# | (receive writes) | | (exact copy) |
# +------------------+ +---------------+
#
# 1) Redis replication is asynchronous, but you can configure a master to
# stop accepting writes if it appears to be not connected with at least
# a given number of replicas.
# 2) Redis replicas are able to perform a partial resynchronization with the
# master if the replication link is lost for a relatively small amount of
# time. You may want to configure the replication backlog size (see the next
# sections of this file) with a sensible value depending on your needs.
# 3) Replication is automatic and does not need user intervention. After a
# network partition replicas automatically try to reconnect to masters
# and resynchronize with them.
#
replicaof master 6379
在此處查看 docker 設置。
https://www.vinsguru.com/redis-master-slave-with-spring-boot/
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.