1.在分布式系统中,基本所有的系统都只能实现CAP中的两个选项,P是要必定实现的。
2.C:consitent,代表一致性,A:availablity,代表可用性,P:partition tolerance 分布式容忍性。
3.在redis中,redis其实就选择了CA这两个选项,假如网络断开了,主从连接失败,主从都可以继续使用,数据有可能不一致,但是redis会尽量保持数据一致,就是网络再次连接时,从机会尽量同步更新主机的数据。
1.前提:
本人这里只是在linux上开一个虚拟机,并不是启动三台虚拟机,所以,要有要启动三个redis服务器的话,就得有三个redis的配置文件,分别配置不同的端口号还有其他的一些信息
2.修改原来redis文件名为redis6379.conf
mv redis.conf redis6379.conf
3.修改redis6379.conf文件里面的内容
1)如果开启aof,则先关闭aof
2)修改log文件名,便于区分
3)修改dump的文件名,便于区分
4.拷贝多两个配置文件
cp redis6379.conf redis6380.conf
cp redis6379.conf redis6381.conf
5.vi redis6380.conf和redis6381.conf文件,修改它们的端口号,dump文件名再保存
redis6380文件执行
:%s/6379/6380/g
redis6381文件执行
:%s/6379/6381/g
6.同时启动三个redis服务
redis-server redis6379.conf
redis-server redis6380.conf
redis-server redis6381.conf
7.先前打开的终端连接到6379的redis,再打开两个终端,分别连接到6380和6381这两个端口号对应的redis服务器,三个终端都连接上redis服务器
redis-cli -a root123 -p 6379
redis-cli -a root123 -p 6380
redis-cli -a root123 -p 6381
8.我这里用6379的redis作为主机,其余两个作为从机
9.修改redis6380.conf和redis6381.conf文件,主要是修改连接到主机时需要的密码,我这里所有的配置文件中密码都为root123
10.在从机6380上设置6379作为其主机
slaveof 127.0.0.1 6379
11.查看连接信息
info replication
12.在主机6379set一个key,如果从机也可以get得到这个值,那么代表主从连接配置成功了,但是这种主从配置都只是暂时的,因为重启后,每一个redis服务器又全都是master身份了,要永久生效,得去修改redis的配置文件。
主机6379:
从机6380:
13.以上的slaveof 127.0.0.1 6379,可以指定主机,但是在重启服务器后会失效,如下可以在两个从机的redis配置文件配置连接到主机的地址永久生效
14.现在无论如何,每次重启6380的redis服务后,它都是一个从机,其主机是6379的redis服务器
15.redis2.6版本后,其设置了从机只能get,不能set。但是我们也可以去到redis的配置文件里将下面这个参数的值改为no,从机也可以进行set操作了
16.主从复制的流程简单来说可以分为如下几个步骤
1)从机启动,连接到主机后,会发送一个sync文件
2)主机在接收到命令后,启动后台的存盘进程,同时收集所有接收到的用于修改数据集命令
3)在后台进程执行完毕之后,主机将传送整个数据文件到各个从机,一次性完成同步
4)全量复制:从机在接收到主机发送过来的数据文件,将其保存到磁盘中并且加载到内存中
5)增量复制:主机将收集所有新的修改命令,依次传给从机,从机执行接收到的命令,完成数据同步
6)注意:从机只要是重新连接到主机,全量复制都会执行
1.现在我们的两个从机在配置文件那里都设置了同一个主机,这偶尔会给主机造成一点的压力
2.这里将6381从机的master改为6380
3.可以看到6381从机依然可以同步到6379主机的数据,类似于接力一样
1.情景
假设现在有一个主机,两个从机,从机均已连接到主机,能拿到数据,这时候,如果主机崩掉了,整个系统就蹦了,那么如何解决这种情况呢?redis提供了一种哨兵模式来解决这个问题
2.哨兵模式
简单理解就是有一个监控监控着主机,如果主机突然蹦了,没有主机了,那么其会从剩下的从机中,重新选举出一个来充当主机,避免系统崩掉的情况!
3.如何配置哨兵模式?
1)它的配置主要在sentinel.conf这个文件里
vi sentinel.conf
2)修改这行配置,最后的那个数改为1,1代表有多少个哨兵来监控6379主机
sentinel monitor mymaster 127.0.0.1 6379 1
3)添加这行配置,要监控的主机的连接密码
sentinel auth-pass mymaster root123
3)启动哨兵模式
redis-sentinel sentinel.conf
4)这时候,我们在6379端执行shutdown命令后,再查看是否重新选举了主机,这个要等一会时间
,如下可以看到,6381被选举成为了主机,注意,这个时候,如果6379重启服务后,它也是一个从机了,这个配置是永久生效的
6381成为了主机
1.准备工作
1)所有的redis实例都要配置一个参数,就是masterauth,还有从机指定主机为6379(在redis.conf中配置)
6379的配置文件
6380的配置文件
6381的配置文件
2)所有redis实例都需要绑定地址,地址为虚拟机ip地址
6379的配置文件
6380的配置文件
6381的配置文件
3)哨兵监控的master也要改成ip地址
2.启动三个redis服务器,并且启动哨兵模式
redis-server redis6379.conf
redis-server redis6380.conf
redis-server redis6381.conf
redis-sentinel sentinel.conf
3.打开三个终端,测试通过redis-cli命令测试是否能连接到redis服务器
redis-cli -p 6379 -a root123 -h 192.168.244.132
redis-cli -p 6380 -a root123 -h 192.168.244.132
redis-cli -p 6381 -a root123 -h 192.168.244.132
4.查看主机的相关信息,可以看到有两个从机
5.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>org.example</groupId>
<artifactId>distribute-lock</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<!--json依赖-->
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.12.3</version>
</dependency>
<!--jedis依赖-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>3.2.0</version>
<type>jar</type>
<scope>compile</scope>
</dependency>
<!--bloom依赖-->
<dependency>
<groupId>com.redislabs</groupId>
<artifactId>jrebloom</artifactId>
<version>1.2.0</version>
</dependency>
</dependencies>
</project>
6.sentinelTest
package com.yl;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.JedisSentinelPool;
import java.util.HashSet;
import java.util.Set;
public class SentinelTest {
public static void main(String[] args) {
//连接池信息
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(10);
config.setMaxWaitMillis(1000);
//主机名
String masterName = "mymaster";
//哨兵模式的配置
Set<String> set = new HashSet<>();
set.add("192.168.244.132:26379");
JedisSentinelPool sentinelPool = new JedisSentinelPool(masterName,set,config,"root123");
Jedis jedis = null;
while (true) {
try {
//获取jedis实例
jedis = sentinelPool.getResource();
System.out.println(jedis.get("k1"));
} catch (Exception e) {
e.printStackTrace();
} finally {
if (jedis != null) {
jedis.close();
}
try {
Thread.sleep(6000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
7.未作任何操作之前,都可以从redis服务器获取数据
8.那么现在,我们在6379主机执行shutdown
9.可以看到控制台报错了
10,但是过一段时间,又可以获取到数据了
11.在linux上也可以看到,6380被选举为了主机
1.pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.5.6</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.yl</groupId>
<artifactId>sentinel</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sentinel</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2.application.properties
# redis的配置
# 密码
spring.redis.password=root123
#超时时间
spring.redis.timeout=6000
# 要监控的主机名
spring.redis.sentinel.master=mymaster
# 哨兵的端口
spring.redis.sentinel.nodes=192.168.244.132:26379
3.test
package com.yl.sentinel;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.data.redis.core.StringRedisTemplate;
@SpringBootTest
class SentinelApplicationTests {
@Autowired
StringRedisTemplate redisTemplate;
@Test
void contextLoads() {
while (true) {
try {
String k1 = redisTemplate.opsForValue().get("k1");
System.out.println(k1);
} catch (Exception e) {
e.printStackTrace();
} finally {
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
}
4.未操作之前的结果
5.在主机6379执行shutdown后,发现报错了,并且过了一会,又正常了
报错
过一段时间,又正常了
linux上发现6381成为了主机
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://blog.csdn.net/weixin_41359273/article/details/120925259
内容来源于网络,如有侵权,请联系作者删除!