1、redis核心原理
1.1、redis单线程为什么性能这么快?
redis所有的数据都在内存中,所有的运算都是内存级别的运算,而且采用单线程避免了多线程的cpu切换引起的性能消耗。
redis是单线程的,因此部分耗时命令需要谨慎使用,比如keys,这些命令的使用有可能导致redis卡顿。
1.2、redis单线程如何处理那么多的并发客户端链接?
redis的IO多路复用:redis利用epoll来实现多路复用,将连接信息和事件放到队列中,依次放到文件事件分派器中,事件分派器分发给事件处理器。
Nginx也是采用的IO多路复用原理解决C10K问题。
1.3、数据流图
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nDhDMoXt-1647786851380)(images/ac06e81f-789f-41a2-bfbf-b6f2ee977921.jpg)]
2、redis常用数据结构和命令
3、redis持久化
3.1、RDB快照(snapshot)
默认情况下,redis将内存中的数据库快照保存在名字诶dump.rdb的二进制文件中。
可以对redis进行设置,让它在“N秒内数据集至少有M个改动”时,自动保存一次数据集。
比如:# save 60 1000
当60秒内有1000个键被改动时,自动保存一次数据集。
关闭RDB只需要将所有的save保存策略注释掉即可。
还可以手动执行命令生成RDB快照,进入redis客户端执行命令save或bgsave可以生成dump.rdb文件,每次命令执行都会将所有redis内存快照到一个新的rdb文件里,并覆盖原有rdb快照文件。save是同步命令,bgsave是异步命令,bgsave会从redis主进程fork(fork()是linux函数)出一个子进程专门用来生成rdb快照文件。
3.2、save和bgsave对比
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-hzwU6KV0-1647786851381)(images/01eec37f-4c71-494c-9577-d0606a58b39c.png)]
4、AOF(append-only file)
快照功能并不是非常耐久(durable): 如果 Redis 因为某些原因而造成故障停机, 那么服务器将丢失最近写入、且仍未保存到快照中的那些数据。从 1.1 版本开始, Redis 增加了一种完全耐久的持久化方式: AOF 持久化,将修改的每一条指令记录进文件appendonly.aof中。
你可以通过修改配置文件来打开AOF 功能:
4.1、# appendonly yes
从现在开始, 每当 Redis 执行一个改变数据集的命令时(比如 SET), 这个命令就会被追加到 AOF 文件的末尾。这样的话, 当 Redis 重新启动时, 程序就可以通过重新执行 AOF 文件中的命令来达到重建数据集的目的。
你可以配置 Redis 多久才将数据 fsync 到磁盘一次。
- appendfsync always:每次有新命令追加到 AOF 文件时就执行一次 fsync ,非常慢,也非常安全。
- appendfsync everysec:每秒 fsync 一次,足够快(和使用 RDB 持久化差不多),并且在故障时只会丢失 1 秒钟的数据。
- appendfsync no:从不 fsync ,将数据交给操作系统来处理。更快,也更不安全的选择。推荐(并且也是默认)的措施为每秒 fsync 一次, 这种 fsync 策略可以兼顾速度和安全性。
4.2、AOP重写
AOF文件里可能有太多没用指令,所以AOF会定期根据内存的最新数据生成aof文件。
4.2.1、如下两个配置可以控制AOF自动重写频率
-
auto-aof-rewrite-min-size 64mb:aof文件至少要达到64M才会自动重写,文件太小恢复速度本来就很快,重写的意义不大。 -
auto-aof-rewrite-percentage 100:aof文件自上一次重写后文件大小增长了100%则再次触发重写。 当然AOF还可以手动重写,进入redis客户端执行命令bgrewriteaof重写AOF。 注意,AOF重写redis会fork出一个子进程去做,不会对redis正常命令处理有太多影响。
4.2.2、RDB 和 AOF ,我应该用哪一个?
redis启动时如果既有rdb文件又有aof文件则优先选择aof文件恢复数据,因为aof一般来说数据更全一点。
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Hf6Gm6f0-1647786851381)(images/870eef63-13df-4b0b-901c-37c8db4f2abc.png)]
5、Redis 4.0 混合持久化
重启 Redis 时,我们很少使用 RDB来恢复内存状态,因为会丢失大量数据。我们通常使用 AOF 日志重放,但是重放 AOF 日志性能相对 RDB来说要慢很多,这样在 Redis 实例很大的情况下,启动需要花费很长的时间。 Redis 4.0 为了解决这个问题,带来了一个新的持久化选项——混合持久化。通过如下配置可以开启混合持久化:\*\*# aof-use-rdb-preamble yes\*\*
如果开启了混合持久化,AOF在重写时,不再是单纯将内存数据转换为RESP命令写入AOF文件,而是将重写这一刻之前的内存做RDB快照处理,并且将RDB快照内容和增量的AOF修改内存数据的命令存在一起,都写入新的AOF文件,新的文件一开始不叫appendonly.aof,等到重写完新的AOF文件才会进行改名,原子的覆盖原有的AOF文件,完成新旧两个AOF文件的替换。于是在 Redis 重启的时候,可以先加载 RDB 的内容,然后再重放增量 AOF 日志就可以完全替代之前的AOF 全量文件重放,因此重启效率大幅得到提升。
混合持久化AOF文件结构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-YT6beVyX-1647786851382)(images/6d6443b9-15c7-4fe3-9a42-1e9446058aa0.jpg)]
6、Redis主从架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-dEd3ugCQ-1647786851382)(images/4eb5beba-c80a-44c2-a74a-01f1d38d9f6b.jpg)]
6.1、Redis 主从工作原理
如果你为master配置了一个slave,不管这个slave是否是第一次连接上Master,它都会发送一个SYNC命令(redis2.8版本之前的命令)给master请求复制数据。master收到SYNC命令后,会在后台进行数据持久化通过bgsave生成最新的rdb快照文件,持久化期间,master会继续接收客户端的请求,它会把这些可能修改数据集的请求缓存在内存中。当持久化进行完毕以后,master会把这份rdb文件数据集发送给slave,slave会把接收到的数据进行持久化生成rdb,然后再加载到内存中。然后,master再将之前缓存在内存中的命令发送给slave。
当master与slave之间的连接由于某些原因而断开时,slave能够自动重连Master,如果master收到了多个slave并发连接请求,它只会进行一次持久化,而不是一个连接一次,然后再把这一份持久化的数据发送给多个并发连接的slave。
当master和slave断开重连后,一般都会对整份数据进行复制。但从redis2.8版本开始,master和slave断开重连后支持部分复制。
6.2、数据部分复制
从2.8版本开始,slave与master能够在网络连接断开重连后只进行部分数据复制。master会在其内存中创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master和它所有的slave都维护了复制的数据下标offset和master的进程id,因此,当网络连接断开后,slave会请求master继续进行未完成的复制,从所记录的数据下标开始。如果master进程id变化了,或者从节点数据下标offset太旧,已经不在master的缓存队列里了,那么将会进行一次全量数据的复制。
从2.8版本开始,redis改用可以支持部分数据复制的命令PSYNC去master同步数据主从复制(全量复制)流程图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-cbu1jBkT-1647786851383)(images/a503c5f0-cca4-440e-88a8-07ae7a39ba85.jpg)]
主从复制(部分复制)流程图:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-omXFz2iE-1647786851383)(images/949ed913-c9c7-4fd8-b4f7-46181f51b5cd.jpg)]
6.3、redis主从架构搭建:
6.3.1、复制redis.conf 文件三分,分别为redis-6381.conf、redis-6382.conf 、redis-6383.conf
[root@localhost redis-5.0.5]
[root@localhost redis-5.0.5]
[root@localhost redis-5.0.5]
6.3.2、修改三分配置文件的端口信息
daemonize yes
protected-mode no
port 6381
pidfile /var/run/redis_6379.pid
6.3.3、分别启动三个redis进程,使用创建的配置文件
[root@localhost redis-5.0.5]
2259:C 07 Aug 2020 11:00:24.459
2259:C 07 Aug 2020 11:00:24.459
2259:C 07 Aug 2020 11:00:24.459
[root@localhost redis-5.0.5]
2264:C 07 Aug 2020 11:00:28.704
2264:C 07 Aug 2020 11:00:28.704
2264:C 07 Aug 2020 11:00:28.704
[root@localhost redis-5.0.5]
2269:C 07 Aug 2020 11:00:32.177
2269:C 07 Aug 2020 11:00:32.177
2269:C 07 Aug 2020 11:00:32.177
[root@localhost redis-5.0.5]
root 2260 1 0 11:00 ? 00:00:00 src/redis-server *:6381
root 2265 1 0 11:00 ? 00:00:00 src/redis-server *:6382
root 2270 1 0 11:00 ? 00:00:00 src/redis-server *:6383
root 2289 2219 0 11:02 pts/0 00:00:00 grep --color=auto redis
6.3.4、设置主从节点
\`\`\` 在Redis中设置主从有2种方式:
在redis.conf中设置replicaof:replicaof 使用redis-cli客户端连接到redis服务,执行slaveof命令:slaveof
```Shell
# 将6382 设置成master,分别将6381、6383链接到master上
[root@localhost redis-5.0.5]# src/redis-cli -p 6381
127.0.0.1:6381> slaveof localhost 6382
OK
127.0.0.1:6381> exit
[root@localhost redis-5.0.5]# src/redis-cli -p 6383
127.0.0.1:6383> slaveof localhost 6382
OK
6.3.5、查看主从信息
登录主节点6382上,使用info replication查看主从节点信息
[root@localhost redis-5.0.5]
127.0.0.1:6382> info replication
role:master
connected_slaves:2
slave0:ip=::1,port=6381,state=online,offset=112,lag=1
slave1:ip=::1,port=6383,state=online,offset=112,lag=1
master_replid:02fc1f89594b941b4dcffc10bf89ad1d4350212e
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:112
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1
repl_backlog_histlen:112
127.0.0.1:6382>
6.3.6、测试,主节点写,从节点读取数据
[root@localhost redis-5.0.5]
127.0.0.1:6382> set xuebin test
OK
127.0.0.1:6382> get xuebin
"test"
127.0.0.1:6382>
[root@localhost redis-5.0.5]
127.0.0.1:6381> get xuebin
"test"
127.0.0.1:6381>
[root@localhost redis-5.0.5]
127.0.0.1:6383> get xuebin
"test"
6.4、Jedis连接代码示例
6.4.1、引入maven
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.9.0</version>
</dependency>
6.4.2、编写Java测试类
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* desc:
* author: Administrator
* date: 2020/8/7
*/
public class JedisPoolTest {
public static void main(String[] args) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
String host = "192.168.1.101";
int port = 6381;
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, 30000, null);
Jedis jedis = jedisPool.getResource();
System.out.println(jedis.set("xb2222", "xuebin"));
System.out.println(jedis.get("xb2222"));
}
}
// 测试结果
OK
xuebin
6.5、下redis管道
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.Pipeline;
import java.util.List;
/**
* desc:
* author: Administrator
* date: 2020/8/7
*/
public class JedisPoolTest {
public static void main(String[] args) {
// 1、JedisPool示例
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
String host = "192.168.1.101";
int port = 6381;
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, 30000, null);
Jedis jedis = jedisPool.getResource();
System.out.println(jedis.set("xb2222", "xuebin"));
System.out.println(jedis.get("xb2222"));
// 2、管道示例
Pipeline pipeline = jedis.pipelined();
for (int i = 0; i < 10; i++){
pipeline.incr("xb:pl");
pipeline.set("xb:"+i, "xb:value"+i);
}
List<Object> result = pipeline.syncAndReturnAll();
System.out.println(result);
}
}
Connected to the target VM, address: '127.0.0.1:64020', transport: 'socket'
OK
xuebin
[11, OK, 12, OK, 13, OK, 14, OK, 15, OK, 16, OK, 17, OK, 18, OK, 19, OK, 20, OK]
Disconnected from the target VM, address: '127.0.0.1:64020', transport: 'socket'
6.6、调用lua脚本
// 3、调用lua脚本
// lua脚本模拟一个商品减库存的原子操作
// lua脚本命令执行方式:redis‐cli ‐‐eval /tmp/test.lua , 10
// jedis.set("product_count_10016", "15"); //初始化商品10016的库存
String script = " local count = redis.call('get', KEYS[1]) " +
" local a = tonumber(count) " +
" local b = tonumber(ARGV[1]) " +
" if a >= b then " +
" redis.call('set', KEYS[1], count‐b) " +
" return 1 " +
" end " +
" return 0 ";
Object obj = jedis.eval(script, Collections.singletonList("product_count_10016"), Collections.singletonList("10"));
System.out.println("lua result: "+obj);
7、Redis哨兵高可用架构
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-sXngtsVi-1647786851384)(images/f399ea19-3aea-47fb-87d1-086dd6ec2708.jpg)]
sentinel哨兵是特殊的redis服务,不提供读写服务,主要用来监控redis实例节点。哨兵架构下client端第一次从哨兵找出redis的主节点,后续就直接访问redis的主节点,不会每次都通过sentinel代理访问redis的主节点,当redis的主节点发生变化,哨兵会第一时间感知到,并且将新的redis主节点通知给client端(这里面redis的client端一般都实现了订阅功能,订阅sentinel发布的节点变动消息)。
7.1、redis哨兵架构搭建步骤
7.1.1、复制三分sentinel配置文件,并修改相关内容
[root@localhost redis-5.0.5]
[root@localhost redis-5.0.5]
[root@localhost redis-5.0.5]
port 26381
daemonize yes
pidfile "/var/run/redis‐sentinel‐26379.pid"
logfile "26379.log"
sentinel monitor mymaster 192.168.1.101 6381 2
注意:西东多个sentinel时,sentinel的myid不能相同,否则sentinel不能发现对方,查看信息时只有一个sentinel,没法实现高可用。可以手动修改sentinel的值或者删除,系统自动分配
7.1.2、启动sentinel
[root@localhost redis-5.0.5]
[root@localhost redis-5.0.5]
[root@localhost redis-5.0.5]
[root@localhost redis-5.0.5]
root 2872 1 0 22:23 ? 00:00:00 src/redis-sentinel *:26381 [sentinel]
root 2877 1 0 22:23 ? 00:00:00 src/redis-sentinel *:26382 [sentinel]
root 2882 1 0 22:23 ? 00:00:00 src/redis-sentinel *:26383 [sentinel]
root 2887 2219 0 22:23 pts/0 00:00:00 grep --color=auto sentinel
7.1.3、链接sentinel,查看相关信息
[root@localhost redis-5.0.5]
127.0.0.1:26381> info sentinel
sentinel_masters:1
sentinel_tilt:0
sentinel_running_scripts:0
sentinel_scripts_queue_length:0
sentinel_simulate_failure_flags:0
master0:name=mymaster,status=ok,address=192.168.1.101:6381,slaves=2,sentinels=3
7.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;
/**
* desc: redis哨兵模式 Java链接测试
* author: Administrator
* date: 2020/8/8
*/
public class JedisSentinelTest {
public static void main(String[] args) {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxTotal(20);
jedisPoolConfig.setMaxIdle(10);
jedisPoolConfig.setMinIdle(5);
String masterName = "mymaster";
Set<String> sentinels = new HashSet<>();
sentinels.add(new HostAndPort("192.168.1.101", 26381).toString());
sentinels.add(new HostAndPort("192.168.1.101", 26382).toString());
sentinels.add(new HostAndPort("192.168.1.101", 26383).toString());
JedisSentinelPool jedisSentinelPool = new JedisSentinelPool(masterName, sentinels, jedisPoolConfig, 3000, null);
Jedis jedis = null;
try {
jedis = jedisSentinelPool.getResource();
System.out.println(jedis.set("sentinel:xuebin", "xuebin"));
System.out.println(jedis.get("sentinel:xuebin"));
}catch (Exception e){
e.printStackTrace();
}finally {
if (jedis != null){
jedis.close();
}
}
}
}
八月 08, 2020 11:17:26 下午 redis.clients.jedis.JedisSentinelPool initSentinels
信息: Trying to find master from available Sentinels...
八月 08, 2020 11:17:26 下午 redis.clients.jedis.JedisSentinelPool initSentinels
信息: Redis master running at 192.168.1.101:6381, starting Sentinel listeners...
八月 08, 2020 11:17:26 下午 redis.clients.jedis.JedisSentinelPool initPool
信息: Created JedisPool to master at 192.168.1.101:6381
OK
xuebin
7.3、哨兵的Spring Boot整合Redis连接
7.3.1、引入maven依赖
<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>
7.3.2、YML 文件配置redis
server:
port: 8001
spring:
application:
name: redis-start
redis:
database: 0
timeout: 3000
lettuce:
pool:
max-idle: 50
max-active: 100
max-wait: 1000
sentinel:
master: mymaster
nodes: 192.168.1.101:26381,192.168.1.101:26382,192.168.1.101:26383
7.3.3、Spring Boot启动类,启动后操作redsi
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.data.redis.core.StringRedisTemplate;
import javax.annotation.PostConstruct;
/**
* desc:
* author: Administrator
* date: 2020/8/8
*/
@SpringBootApplication
public class RedisTempterApplication {
@Autowired
private StringRedisTemplate stringRedisTemplate;
public static void main(String[] args) {
SpringApplication.run(RedisTempterApplication.class, args);
}
/**
* 测试节点挂了哨兵重新选举新的master节点,客户端是否能动态感知到
* 新的master选举出来后,哨兵会把消息发布出去,客户端实际上是实现了一个消息监听机制,
* 当哨兵把新master的消息发布出去,客户端会立马感知到新master的信息,从而动态切换访问的maste rip
*/
@PostConstruct
public void testSentinel() {
int i = 1;
while (true){
try {
stringRedisTemplate.opsForValue().set("testSentinel:"+i, i+"");
System.out.println("设置key:"+ "testSentinel:" + i);
i++;
Thread.sleep(2000);
}catch (Exception e){
System.err.println("错误: "+e.getMessage());
}
}
}
}
7.3.4、测试结果
2020-08-09 00:04:50.128 INFO 17660 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2020-08-09 00:04:50.145 INFO 17660 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8ms. Found 0 Redis repository interfaces.
2020-08-09 00:04:50.351 INFO 17660 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8001 (http)
2020-08-09 00:04:50.356 INFO 17660 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-09 00:04:50.356 INFO 17660 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-08-09 00:04:50.405 INFO 17660 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-09 00:04:50.405 INFO 17660 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 741 ms
设置key:testSentinel:1
设置key:testSentinel:2
设置key:testSentinel:3
设置key:testSentinel:4
设置key:testSentinel:5
设置key:testSentinel:6
设置key:testSentinel:7
设置key:testSentinel:8
7.3.6、测试主节点被kill,系统是否自动选主
2020-08-09 00:04:49.628 INFO 17660 --- [ main] com.redis.start.RedisTempterApplication : Starting RedisTempterApplication on PC-201910131736 with PID 17660 (E:\workspace\java\SpringBootAll\redis-start\target\classes started by Administrator in E:\workspace\java\SpringBootAll)
2020-08-09 00:04:49.630 INFO 17660 --- [ main] com.redis.start.RedisTempterApplication : No active profile set, falling back to default profiles: default
2020-08-09 00:04:50.127 INFO 17660 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Multiple Spring Data modules found, entering strict repository configuration mode!
2020-08-09 00:04:50.128 INFO 17660 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data Redis repositories in DEFAULT mode.
2020-08-09 00:04:50.145 INFO 17660 --- [ main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 8ms. Found 0 Redis repository interfaces.
2020-08-09 00:04:50.351 INFO 17660 --- [ main] o.s.b.w.embedded.tomcat.TomcatWebServer : Tomcat initialized with port(s): 8001 (http)
2020-08-09 00:04:50.356 INFO 17660 --- [ main] o.apache.catalina.core.StandardService : Starting service [Tomcat]
2020-08-09 00:04:50.356 INFO 17660 --- [ main] org.apache.catalina.core.StandardEngine : Starting Servlet engine: [Apache Tomcat/9.0.37]
2020-08-09 00:04:50.405 INFO 17660 --- [ main] o.a.c.c.C.[Tomcat].[localhost].[/] : Initializing Spring embedded WebApplicationContext
2020-08-09 00:04:50.405 INFO 17660 --- [ main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 741 ms
设置key:testSentinel:1
设置key:testSentinel:2
。。。。。。。。。。。。
设置key:testSentinel:16
设置key:testSentinel:17
2020-08-09 00:05:23.980 INFO 17660 --- [xecutorLoop-1-1] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was /192.168.1.101:6383
2020-08-09 00:05:24.989 WARN 17660 --- [ioEventLoop-4-4] i.l.core.protocol.ConnectionWatchdog : Cannot reconnect to [192.168.1.101:6383]: Connection refused: no further information: /192.168.1.101:6383
错误: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 3 second(s)
错误: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 3 second(s)
错误: Redis command timed out; nested exception is io.lettuce.core.RedisCommandTimeoutException: Command timed out after 3 second(s)
2020-08-09 00:06:11.680 INFO 17660 --- [xecutorLoop-1-3] i.l.core.protocol.ConnectionWatchdog : Reconnecting, last destination was 192.168.1.101:6383
2020-08-09 00:06:11.689 INFO 17660 --- [ioEventLoop-4-2] i.l.core.protocol.ReconnectionHandler : Reconnected to 192.168.1.101:6382
设置key:testSentinel:18
设置key:testSentinel:19
设置key:testSentinel:20
。。。。。。。。。。。。。
设置key:testSentinel:43
设置key:testSentinel:44
7.3.7、重启主节点
重启主节点,sentinel会将原来主节点加都原有主从结构中,并将其设置为从节点。同事修改配置文件从新的主节点同步数据,该节点只读等信息。
配置信息会加导配置文件末尾。
redis-6383.conf
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-WWUToBgZ-1647786851384)(images/20b254c3-4c7d-4e61-8030-36820ced4807.png)]
sentinel-26383.conf
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-nZBuA2np-1647786851384)(images/9f014e04-ab93-4636-9570-cd2f29e1f4e2.png)]
|