-
配置
- 主redis:无须额外配置。一般会把protected-mode 设为 no, 假设ip为
192.168.0.2
- 从redis:增加如下配置。假设 ip为
192.168.0.3
- 目前我们不需要其它的功能(如哨兵,cluster等),只是需要从redis减轻主redis的流量,因此配置基本上就这样
- 主redis:无须额外配置。一般会把protected-mode 设为 no, 假设ip为
slaveof 192.168.0.2 6379 # 主redis的地址
#masterauth xxxxxx # 主redis的密码,如果有设置的话
#requirepass xxxxxx # 从redis的密码,如果需要的话
p.s : redis没有密码暴露在外网环境极其容易遭到攻击,因此要谨慎
-
代码
-
要实现redis读写分离,主要是在代码上实现。幸好我们系统使用Redis的地方都在 RedisUtil类上
-
把 read 相关方法定位到从redis,把 write相关定位主redis即可。
-
做法:原get pool的方式为 manager.getJedisPool(). 如下getString
public String getString(final String key) {
JedisPool jedisPool = manager.getJedisPool();
return new CommExecutor<String>(jedisPool) {
@Override
public String execute() {
String result = null;
result = getJedis().get(key);
return result;
}
}.getResult();
}
- 现在manager增加,getReadJedisPool,在RedisUtil相关的read方法,都换成这一个。例如getString:
public String getString(final String key) {
JedisPool jedisPool = manager.getJedisPool();
return new CommExecutor<String>(jedisPool) {
@Override
public String execute() {
String result = null;
result = getJedis().get(key);
return result;
}
}.getResult();
}
- 其它方面1: 由于从redis可以有多个,因此需要一种策略来获取使用哪一个从redis。可选的有:
- 1)[加权]平均
- 2)[加权]随机。
- 这里使用的是随机方法,getReadJedisPool 如下。
//在从redis列表中,随机取一个从redis,如果没有从redis,则使用主redis
public JedisPool getReadJedisPool() {
JedisPool readJedisPool;
if(CollectionUtils.isNotEmpty(slaveJedisPoolList)) {
Random random = new Random();
int randomIndex = random.nextInt(slaveJedisPoolList.size());
readJedisPool = slaveJedisPoolList.get(randomIndex);
}else {
readJedisPool = jedisPool;
}
return readJedisPool;
}
- 其它方面2:,还在初始化的时候简单加了可用性判断,不可用的从redis配置直接丢弃。如下代码
List<JedisPool> invalidList = new ArrayList<>();
for (JedisPool jedisPool : slaveJedisPoolList) {
try {
boolean isConnnected = jedisPool.getResource().isConnected();
if(!isConnnected) {
invalidList.add(jedisPool);
}
} catch (Exception e) {
invalidList.add(jedisPool);
}
}
slaveJedisPoolList.removeAll(invalidList);