Redis主从复制的功能非常强大,它有以下好处:
1、修改redis相关配置(rediss.conf)
port 6380 # redis端口
pidfile /var/run/redis_6380.pid # redis进程id文件路径
logfile "6380.log" # 日志文件名称
dir /usr/local/redis‐5.0.3/data/6380 redis数据存储目录
3、配置主从复制
replicaof xxx.xxx.xx.xx 6379 # 从主节点所在服务器的redis实例复制数据
replica‐read‐only yes # 设置从节点只读
4、启动从节点
redis‐server redis.conf # 启动节点,加载配置文件
5、连接从节点
redis‐cli ‐p 6380 (端口号)
6、测试在主节点实例上写数据,从节点实例是否能及时同步新修改数据
jedis访问和springboot访问redis主从的方式与访问单机方式一样
具体代码查看java客户端访问redis:https://blog.csdn.net/weixin_38414968/article/details/103246518
sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。
哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过 sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis 主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)
1、修改redis相关配置(sentinel.conf)
port 26379 # 端口号
daemonize yes # 后台运行
pidfile "/var/run/redis‐sentinel‐26379.pid" # 进程id文件
logfile "26379.log" # 日志文件
dir "/usr/local/redis‐5.0.3/data" # 数据存储路径
# sentinel monitor # quorum是一个数字,指明当有多少个sentinel认为一个master失效时(值一般为:sentinel总数/2 + 1),master才算真正失效
sentinel monitor mymaster(给主节点起个自定义名字) xxx.xxx.xx.xx(主节点服务器ip) 6379(主节点端口号) 2
2、启动sentinel哨兵实例
src/redis‐sentinel sentinel.conf(加载此哨兵对应的配置文件)
3、查看sentinel的info信息
src/redis‐cli ‐p 26379
127.0.0.1:26379>info
可以看到Sentinel的info里已经识别出了redis的主从
4、配置多个哨兵,按照此步骤即可
1、导入jedis的依赖包
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
2、jedis连接代码
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Set;
/**
* @auther jedis连接哨兵
* @create xxxx/xx/xx
*/
public class JedisSentine {
public static void main(String[] args) {
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(20); //最大连接数, 默认8个
config.setMaxIdle(10); //最大空闲连接数, 默认8个
config.setMinIdle(5); //最小空闲连接数, 默认0
// 哨兵配置文件中的主节点名称
String masterName = "mymaster";
// 哨兵的连接信息(如果有多个哨兵则可添加多个)
Set<String> sentinels = new HashSet<String>();
sentinels.add(new HostAndPort("xxx.xxx.xx.xx",26379).toString());
// 如果多个哨兵直接添加即可:
// sentinels.add(new HostAndPort("xxx.xxx.xx.xx",26380).toString());
// sentinels.add(new HostAndPort("xxx.xxx.xx.xx",26381).toString());
/**
* JedisSentinelPool其实本质跟JedisPool类似,都是与redis主节点建立的连接池
* JedisSentinelPool并不是说与sentinel建立的连接池,而是通过sentinel发现redis主节点并与其 建立连接
*
* masterName : redis哨兵中配置的主节点的名称
* sentinels : 哨兵的连接实例
* config : poolConfig配置
* timeout(3000) : 连接超时时间
* password(null) : 访问密码(如果redis没有设置访问密码则传null)
**/
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels,config, 3000, null);
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
jedis.set("sentine","ok");
jedis.get("sentine");
}catch (Exception e){
e.printStackTrace();
}finally {
//注意这里不是关闭连接,在JedisPool模式下,Jedis会被归还给资源池。
if (null != jedis){
jedis.close();
}
}
}
}
1、导入依赖包
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.apache.commons</groupId>
<artifactId>commons-pool2</artifactId>
</dependency>
2、application.yml配置
server:
port: 8080
spring:
redis:
database: 0
redis.timeout: 3000
lettuce:
pool:
max-idle: 50 #连接池中的最大空闲连接
min-idle: 10 #连接池中的最小空闲连接
max-active: 100 #连接池最大连接数(使用负值表示没有限制)
pool.max-wait: 1000 #连接池最大阻塞等待时间(使用负值表示没有限制)
sentinel:
master: mymaster # 哨兵配置的主节点名称
nodes: xxx.xxx.xx.xx:26379,xxx.xxx.xx.xx:26380,xxx.xxx.xx.xx:26381 # 哨兵的连接地址
3、StringRedisTemplate连接哨兵
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* @auther SentineConn
* @create xxxx/xx/xx
*/
@RestController
public class SentineConn {
@Autowired
StringRedisTemplate stringRedisTemplate;
/**
* 测试节点挂了哨兵重新选举新的master节点,客户端是否能动态感知到
* 新的master选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制,
* 当哨兵把新master的消息发布出去,客户端会立马感知到新master的信息,从而动态切换访问的maste
*/
@RequestMapping("sentine_conn")
public void mastConn(){
stringRedisTemplate.opsForValue().set("sentine","ok");
stringRedisTemplate.opsForValue().get("sentine");
}
}