Detailed Explanation of Redis's Master-Slave Replication and Sentinel Mechanism

Note: Some of the knowledge points in this article come from the book [Redis Deep Adventure - Core Principles and Application Practice]!

Before understanding Redis's master-slave replication, let us first understand the theoretical cornerstone of modern distributed systems-the CAP principle.

1. The principle of CAP

The CAP principle is like Newton's law in the distributed field, and it is the theoretical cornerstone of distributed storage. Since the publication of the CAP paper, distributed storage middleware has sprung up one by one like mushrooms after rain. Understanding this principle is actually very simple. In this section, we first give some simple explanations of this principle.

  • C - Consistent, Consistency: Whether all data backups in a distributed system have the same value at the same time. (equivalent to all nodes accessing the same latest data copy)
  • A - Availability, availability: ensure that each request has a response regardless of success or failure.
  • P - Partition tolerance, partition tolerance: the loss or failure of any information in the system will not affect the continued operation of the system.

Network partition:分布式系统的节点往往都是分布在不同的机器上进行网络隔离开的,这意味着必然会有网络断开的风险,这个网络断开的场景的专业词汇叫着「网络分区」 .

Problems caused by network partition: When a network partition occurs, two distributed nodes cannot communicate, and the modification operation we make on one node will not be synchronized to the other node, so the "consistency" of data will not be satisfied. Because the data of the two distributed nodes is no longer consistent. Unless we sacrifice "availability", that is, suspend distributed node services, when a network partition occurs, we will no longer provide the function of modifying data, and continue to provide external services until the network condition is completely restored to normal.

一句话概括 CAP 原理就是——网络分区发生时,一致性和可用性两难全。

2. Redis master-slave synchronization

1. What can master-slave synchronization do?

Master-slave: Many enterprises have not used Redis clusters, but at least they have done master-slave. With the master-slave, when the master hangs up, the operation and maintenance will let the slave library take over, and the service can continue. Otherwise, the master needs to go through the process of data recovery and restart, which may take a long time and affect the online business continuous service.

Data synchronization: Master-slave replication is also called master-slave synchronization by some people. In fact, the two are talking about the same thing. The main purpose is to avoid the failure of a single node Redis and cause the service to be unavailable. Therefore, multiple nodes are deployed. Although multiple Node, 但是节点之间的数据是始终是保持同步(一样)的数据, if you want to add key/value, add kev/value, if you want to delete, delete it, which can be understood as cloning!

The master-slave synchronization function is not necessary, but as long as you use the persistence function of Redis, you must take master-slave replication seriously, which is the basic guarantee of system data security.

Master-slave synchronization has two main features:

  • Read-write separation, performance expansion, reduce the pressure on the main server
  • Disaster recovery, fast recovery, when the master hangs up, the slave becomes the master

Redis satisfies AP in CAP theory

The master-slave data of Redis is 异步同步yes, so the distributed Redis system 并不满足「一致性」requires it. When the client modifies the data on the master node of Redis, it returns immediately. Even if the master-slave network is disconnected, the master node can still provide modification services to the outside world normally, so Redis satisfies "availability".

Redis can guarantee eventual consistency

The slave node will try to catch up with the master node, and eventually the state of the slave node will be consistent with the state of the master node. If the network is disconnected, there will be a lot of inconsistencies in the data of the master and slave nodes. Once the network is restored, the slave nodes will use various strategies to catch up with the lagging data and continue to try their best to maintain consistency with the master node.

Redis synchronization support 主从同步and 从从同步slave-slave synchronization function are functions added in subsequent versions of Redis, in order to reduce the synchronization burden of the main library. In the following, for the convenience of description, the unified understanding is master-slave synchronization.

What happens after the main redis hangs up? Is the slave machine in the upper position or standing still?

After the main machine hangs up, it will wait for the opportunity to wait for the younger brother to recover, and will not usurp the throne.

After the slave hangs up and resumes, will it continue to synchronize data from the master?

Yes, after restarting, the missing data will continue to be synchronized.

You can use info Replicationthe command to view master-slave replication information

2. How does Redis realize data synchronization?

  1. After the slave starts and successfully connects to the master, it will send a data synchronization message to the master (send sync command)
  2. After the master receives the data synchronization message sent by the slave, it persists the data of the master server to the rdb file, and at the same time collects the commands received for modifying the data, and the master sends the rdb file to your slave to complete a complete Synchronize
  3. Full copy: after the slave service receives the rdb file sent by the master, it saves it and loads it into the memory
  4. Incremental replication: the master continues to pass the collected modification commands to the slave in turn to complete the synchronization,
    but as long as the master is reconnected, a full synchronization (full copy) will be automatically executed

The above is just an overall general process. Below we will introduce the incremental synchronization and full synchronization in detail!

2.1. Incremental synchronization

What Redis synchronizes is 指令流:

  1. The master node will record those instructions that modify its own state in the local memory buffer
  2. Then 异步synchronize the instructions in the buffer to the slave node
  3. The slave node executes the synchronous instruction flow to achieve the same state as the master node, and feeds back to the master node where it is synchronized (offset).

Note: Because the memory buffer is limited, the Redis main library cannot record all instructions in the memory buffer.Redis 的复制内存 buffer 是一个定长的环形数组,如果数组内容满了,就会从头开始覆盖前面的内容。

If the slave node cannot synchronize with the master node in a short period of time due to poor network conditions, then when the network condition recovers, those unsynchronized instructions in the master node of Redis may have been overwritten by subsequent instructions in the buffer , the slave nodes will not be able to synchronize directly through the instruction stream. At this time, a more complex synchronization mechanism-snapshot synchronization is required.

2.2. Snapshot synchronization

Snapshot synchronization is a very resource-intensive operation:

  1. It first needs to be performed on the main library bgsaveto snapshot all the data in the current memory to the disk file
  2. Then transfer all the contents of the snapshot file to the slave node.
  3. After the slave node accepts the snapshot file, it immediately executes a full load. Before loading, the data in the current memory must be cleared.
  4. After the loading is complete, notify the master node to continue incremental synchronization.

During the entire snapshot synchronization process, the replication buffer of the primary node is still moving forward. If the snapshot synchronization time is too long or the replication buffer is too small, the incremental instructions during the synchronization will be overwritten in the replication buffer , which will result in the inability to perform incremental replication after the snapshot synchronization is completed, and then initiate the snapshot synchronization again, which is very likely to fall into an infinite loop of snapshot synchronization.

所以务必配置一个合适的复制 buffer 大小参数,避免快照复制的死循环。

When a slave node has just joined the cluster, it must first perform a snapshot synchronization, and then proceed to incremental synchronization after the synchronization is completed.

2.3. Diskless Copy

When the master node performs snapshot synchronization, it will perform heavy file IO operations, especially for non-SSD disk storage, snapshots will have a greater impact on the system load. Especially when the system is performing AOF fsync operation, if a snapshot occurs, fsync will be delayed, which will seriously affect the service efficiency of the master node.

So starting from Redis version 2.8.18, diskless replication is supported. 所谓无盘复制是指主服务器直接通过套接字将快照内容发送到从节点,生成快照是一个遍历的过程,主节点会一边遍历内存,一边将序列化的内容发送到从节点, the slave node is still the same as before, first storing the received content in a disk file, and then loading it at one time.

2.4. Ensure strong consistency through the Wait instruction

The replication of Redis is performed asynchronously wait 指令可以让异步复制变身同步复制to ensure the strong consistency of the system (not strict). The wait command only appeared after Redis3.0 version.

> set key value
OK
> wait 1 0
(integer) 1

wait takes two arguments, 第一个参数是从库的数量 N,第二个参数是时间 t,以毫秒为单位. It means waiting for all write operations before the wait instruction to be synchronized to N slave libraries (that is, to ensure that the synchronization of N slave libraries does not lag behind), and the maximum waiting time is t. If the time t=0, it means waiting indefinitely until the synchronization of N slave libraries is completed and an agreement is reached.

Assuming that a network partition occurs at this time, the second parameter time of the wait command is t=0, the master-slave synchronization cannot continue, the wait command will be blocked forever, and the Redis server will lose availability.

3. Build Redis 1 master and 2 slaves

3.1. Install Redis

Next, let's configure the effect of 1 master and 2 slaves. In reality, 3 machines are needed. For convenience, we will demonstrate on a Linux machine, and distinguish the machines through different ports. The configuration of 3 machines

(1) stop redis

If redis is installed in linux, you can stop all of them first and stop all redis commands:

ps -ef | grep redis | awk -F" " '{print $2;}' | xargs kill -9

(2) Download redis, then upload redis to the opt directory

If wget is not installed, install it first:

cd /opt
yum -y install wget
wget https://download.redis.io/redis-stable.tar.gz

(3) install redis

To compile Redis, first unpack the tar, switch to the root directory, and run make:

tar -xzvf redis-stable.tar.gz
cd redis-stable
yum install gcc-c++
make install

If make install reports the following exception, use it directlymake install MALLOC=libc

After installation you'll find several Redis binaries in the src directory, including:

  • redis-server: Redis server itself
  • redis-cli: It is a command-line interface utility for talking to Redis, commonly known as a client.

3.2. Create 1 master 2 slave configuration file

(1) Create a configuration file

We put the configuration files of the three machines in /opt/redis-stable/config

mkdir /opt/redis-stable/config
cd /opt/redis-stable/config
cp /opt/redis-stable/redis.conf /opt/redis-stable/config/

(2) Create a master configuration file: redis-6379.conf

touch redis-6379.conf
vi redis-6379.conf

Edit as follows:

bind 0.0.0.0: Indicates that all ip addresses are allowed to access. The default is 127.0.0.1, and only the current host is allowed to connect. If the ip of the current machine or 127.0.0.1 is configured here, it may result in the inability to connect to Redis in windows.

#redis.conf是redis原配置文件,内部包含了很多默认的配置,这里使用include将其引用,相当于把redis.conf内容直接贴进来了
include /opt/redis-stable/config/redis.conf
daemonize yes
bind 0.0.0.0
#配置密码
requirepass 123456
dir /opt/redis-stable/config/
logfile /opt/redis-stable/config/6379.log
#端口
port 6379
#rdb文件
dbfilename dump_6379.rdb
#pid文件
pidfile /var/run/redis_6379.pid

(3) Create a configuration file for slave1: redis-6380.conf

The content is as follows, similar to the master above, with the addition of the next 2 lines of configuration, mainly to specify the ip and port of the master and the authentication password.

192.168.0.108 is my linux ip, please remember to switch to your own here!

include /opt/redis-stable/config/redis.conf
daemonize yes
bind 0.0.0.0
requirepass 123456
dir /opt/redis-stable/config/
port 6380
dbfilename dump_6380.rdb
pidfile /var/run/redis_6380.pid
logfile /opt/redis-stable/config/6380.log
#用来指定主机:slaveof 主机ip 端口
slaveof 192.168.0.108 6379
#主机的密码
masterauth 123456

(4) Create a configuration file for slave2: redis-6381.conf

include /opt/redis-stable/config/redis.conf
daemonize yes
bind 0.0.0.0
requirepass 123456
dir /opt/redis-stable/config/
port 6381
dbfilename dump_6381.rdb
pidfile /var/run/redis_6381.pid
logfile /opt/redis-stable/config/6381.log
#用来指定主机:slaveof 主机ip 端口
slaveof 192.168.0.108 6379
#主机的密码
masterauth 123456

3.3. Start Redis

(1) Turn off the firewall

If the firewall is not closed, windows may not be able to connect to the redis we just installed on the virtual machine

  • Set the boot to enable the firewall:systemctl enable firewalld.service
  • Set the boot to disable the firewall:systemctl disable firewalld.service
  • Start the firewall:systemctl start firewalld
  • Turn off the firewall:systemctl stop firewalld
  • Check firewall status:systemctl status firewalld

(2) start redis

start master

/opt/redis-stable/src/redis-server /opt/redis-stable/config/redis-6379.conf

start slave1

/opt/redis-stable/src/redis-server /opt/redis-stable/config/redis-6380.conf

start slave2

/opt/redis-stable/src/redis-server /opt/redis-stable/config/redis-6381.conf

If there is an error in the startup, please check the configuration carefully, and you can also read the logs. The logs will be generated in the /opt/redis-stable/config directory when the three machines are started, as follows

ps -ef|grep redisYou can view the started redis by

(3) connect redis

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6379 -a 123456

View host information:info Replication

Query the information of the slave slave1

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6380 -a 123456

3.4. Verify the effect of master-slave synchronization

Execute the following 2 commands on the master

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6379 -a 123456
127.0.0.1:6379> flushdb
OK
127.0.0.1:6379>  set name ready
OK
127.0.0.1:6379> set age 30
OK

Execute the following command on slave1, it can be seen that the data has been synchronized

[root@bogon config]# /opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6380 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6380>  mget name age
1) "ready"
2) "30"

Also execute it on slave2, the effect is as follows, note that it is not allowed to execute new and modified commands in the slave machine!

[root@bogon config]# /opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6381 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6381> mget name age
1) "ready"
2) "30"
127.0.0.1:6381> set aa aa
(error) READONLY You can't write against a read only replica.

3.5. Configure the master-slave relationship through commands

The above demonstration is one master and two slaves, but the configuration files are used. In fact, the slaves can be configured by commands. Let’s demonstrate it again, and everyone is optimistic.

(1) Delete the two lines of redis-6380.conf and redis-6381.conf

#用来指定主机:slaveof 主机ip 端口
slaveof 192.168.0.108 6379
#主机的密码
masterauth 123456

(2) Start three redis

start master

/opt/redis-stable/src/redis-server /opt/redis-stable/config/redis-6379.conf

start slave1

/opt/redis-stable/src/redis-server /opt/redis-stable/config/redis-6380.conf

start slave2

/opt/redis-stable/src/redis-server /opt/redis-stable/config/redis-6381.conf

(3) Log in to 3 machines respectively to view the master-slave information

Log in to the three redis respectively, and then use the info replication command to view the master-slave information of the next three, as follows:

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6380 -a 123456
info Replication

At this time, we have lifted the master-slave relationship of the 3 nodes!

(4) Configure slave1 as the slave library of the master

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6380 -a 123456
config set masterauth 123456
slaveof 127.0.0.1 6379
info replication

(5) Configure slave2 as the slave library of the master

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6381 -a 123456
config set masterauth 123456
slaveof 127.0.0.1 6379
info replication

(6) Look at the master-slave information of the master again

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6379 -a 123456
info replication

注意:通过 slaveof 命令指定主从的方式,slave重启之后主从配置会失效,所以,重启后需要在slave上重新通过 slaveof 命令进行设置,这个不要忘记了。中途通过 slaveof 变更转向,本地的数据会被清除,会从新的master重新同步数据。

3.6. Anti-customer-oriented

When the master hangs up, we can choose one of the slaves as the master. For example, if we want slave1 to be the master, then we can execute the following command on slave1.

slaveof no one

Here I ps-ef|grep redisfound out the process of 6379 master nodes by querying, and then directly killclosed it forcibly

At this point, slave1 becomes the host, and then go to other slaves to execute the slaveof command to hang it on slave1.

Configure slave2 as the slave library of slave1

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6381 -a 123456
config set masterauth 123456
slaveof 127.0.0.1 6380
info replication

If the master recovers after a period of time, if you still want him to be the master, you have to restart all redis to let him continue to be the master.

4. Message lost

Redis master-slave uses asynchronous replication, which means that when the master node hangs up, the slave node may not receive all the synchronization messages, and this part of the unsynchronized messages will be lost. If the master-slave delay is particularly large, the lost data may be particularly large. Sentinel cannot guarantee that the message will not be lost at all, but it will try to ensure that the message will be lost as little as possible. It has two options to limit excessive master-slave latency.

min-slaves-to-write 1
min-slaves-max-lag 10

The first parameter indicates that the master node must have at least one slave node performing normal replication, otherwise the external write service will be stopped and availability will be lost.

What is normal replication and what is abnormal replication? This is controlled by the second parameter, and its unit is seconds, which means that if the feedback from the slave node is not received within 10s, it means that the slave node is not synchronizing normally, or the network is disconnected, or no feedback has been given.

5. Insufficient master-slave mode

The master-slave mode is not perfect, and it also has many shortcomings. Here is a brief summary:

  1. The Redis master-slave mode does not have automatic fault tolerance and recovery functions. If the master node goes down, the Redis cluster will not work. At this time, human intervention is required to promote the slave node to the master node.
  2. If part of the data is not synchronized to the slave machine in time before the master machine goes down, data inconsistency will occur even after the master machine is switched, thereby reducing the availability of the system.
  3. Because there is only one master node, its writing and storage capabilities are limited to a certain extent.
  4. When performing full data synchronization, if the amount of data to be synchronized is large, it may cause lag.

Let’s introduce another method: sentinel mode, after the master hangs up, one of the slaves is automatically elected as the master, and the failover is automatically realized.

4. Sentinel mode

1. What can do what?

The anti-customer-based automatic version can automatically monitor whether the master fails. If there is a failure, one of the slaves will be selected as the master according to the number of votes, and the other slaves will automatically switch to the new master for synchronization to realize the automatic escape of the failure.

2. Sentinel mode principle

  • First: The sentinel node will send a PING command to each Redis node once per second, and judge its running status through the reply of the Redis node.
  • Second: When the sentinel detects that the master server fails, it will automatically select a machine from the slave nodes and promote it to the master server, and then use the PubSub publish-subscribe mode 通知其他的从节点,修改配置文件,跟随新的主服务器. When the client tries to connect to the failed master server, the cluster will also return the address of the new master server to the client, so that the cluster can use the new master server to replace the failed server.

However, there is a possibility of misjudgment in this situation. For example, the master may not be down, but the network between sentinel and the master is not connected, resulting in ping failure. 为了避免误判,通常会启动多个sentinel, generally an odd number, such as 3, then it can be specified. 当有多个sentinel都觉得master挂掉了,此时才断定master真的挂掉了Usually, this value is set to half of the sentinel. For example, if the number of sentinels is 3, then this amount can be set to 2.

There is also mutual monitoring among multiple sentinels, which forms the multi-sentinel mode. Now the working process of this mode is explained as follows:

  1. Subjective offline: Subjective offline, 适用于主服务器和从服务器. If the Sentinel node does not receive a valid reply from the target server within the specified time (configuration parameter: down-after-milliseconds), then it is determined that the server is "subjectively offline". For example, Sentinel1 sends a PING command to the main server, but does not receive a PONG reply from the main server within the specified time, then Sentinel1 determines that the main server is "subjectively offline".
  2. Objective offline: objective (passive) offline, 只适用于主服务器. Sentinel1 finds that the main server has failed, and it will ask other Sentinel nodes to judge the status of the main server through corresponding commands. If more than half of the Sentinel nodes think that the main server is down, then the Sentinel1 node judges that the main service is "objectively offline".
  3. Voting: Voting, all Sentinel nodes will use the voting mechanism to 谁发现谁去处理elect Sentinel1 as the leading node to perform Failover (failover) operation according to the principle. The Sentinel1 node selects one of the best slave nodes as the master server according to certain rules, and then notifies the rest of the slave nodes (slave) to change the configuration file through the publish and subscribe function, and follow the newly appointed master server (master). At this point, the operation of master-slave switching is completed.

A brief summary of the above process:

Sentinel is responsible for monitoring the "health" status of the master and slave nodes. When the master node hangs up, an optimal slave node is automatically selected to switch to the master node. 客户端来连接 Redis 集群时,会首先连接 Sentinel,通过 Sentinel 来查询主节点的地址,然后再去连接主节点进行数据交互。When the master node fails, the client will ask Sentinel for the address again, and Sentinel will tell the client the latest master node address. Therefore, the application can automatically complete the master-slave node switch without restarting.

3. Build 1 master, 2 slaves and 3 sentinels

Next, let's implement the configuration of 1 master, 2 slaves and 3 sentinels. When the slaves hang up, at least 2 sentinels are required to think that the master is down before failover.

For convenience, we simulate on one machine and distinguish 6 different nodes (1 master, 2 slaves, and 3 sentinels) through ports. The node configuration information is as follows

3.1. Create 3 sentinel configuration files

We are directly based on the above master-slave replication configuration of 1 master and 2 slaves, and then configure 3 sentinel sentinels for him.

(1) Create a configuration file for sentinel1: sentinel-26379.conf

Create a sentinel-26379.conf file in the /opt/redis-stable/config directory with the following content

Note: 127.0.0.1 needs to be replaced with the ip of the master host, otherwise there will be problems connecting to the sentinel in windows!

cd /opt/redis-stable/config/
touch sentinel-26379.conf
vi sentinel-26379.conf
bind 0.0.0.0
# 配置文件目录
dir /opt/redis-stable/config/
# 日志文件位置
logfile "./sentinel-26379.log"
# pid文件
pidfile /var/run/sentinel_26379.pid
# 是否后台运行
daemonize yes
# 端口
port 26379
# 监控主服务器master的名字:mymaster,IP:127.0.0.1,port:6379,最后的数字2表示当Sentinel集群中有2个Sentinel认为master存在故障不可用,则进行自动故障转移
sentinel monitor mymaster 127.0.0.1 6379 2
# master响应超时时间(毫秒),Sentinel会向master发送ping来确认master,如果在20秒内,ping不通master,则主观认为master不可用
sentinel down-after-milliseconds mymaster 20000
# 故障转移超时时间(毫秒),如果3分钟内没有完成故障转移操作,则视为转移失败
sentinel failover-timeout mymaster 180000
# 故障转移之后,进行新的主从复制,配置项指定了最多有多少个slave对新的master进行同步,那可以理解为1是串行复制,大于1是并行复制
sentinel parallel-syncs mymaster 1
# 指定mymaster主的密码(没有就不指定)
sentinel auth-pass mymaster 123456

(2) Create a configuration file for sentinel2: sentinel-26380.conf

touch sentinel-26380.conf
vi sentinel-26380.conf
bind 0.0.0.0
# 配置文件目录
dir /opt/redis-stable/config/
# 日志文件位置
logfile "./sentinel-26380.log"
# pid文件
pidfile /var/run/sentinel_26380.pid
# 是否后台运行
daemonize yes
# 端口
port 26380
# 监控主服务器master的名字:mymaster,IP:127.0.0.1,port:6379,最后的数字2表示当Sentinel集群中有2个Sentinel认为master存在故障不可用,则进行自动故障转移
sentinel monitor mymaster 127.0.0.1 6379 2
# master响应超时时间(毫秒),Sentinel会向master发送ping来确认master,如果在20秒内,ping不通master,则主观认为master不可用
sentinel down-after-milliseconds mymaster 20000
# 故障转移超时时间(毫秒),如果3分钟内没有完成故障转移操作,则视为转移失败
sentinel failover-timeout mymaster 180000
# 故障转移之后,进行新的主从复制,配置项指定了最多有多少个slave对新的master进行同步,那可以理解为1是串行复制,大于1是并行复制
sentinel parallel-syncs mymaster 1
# 指定mymaster主的密码(没有就不指定)
sentinel auth-pass mymaster 123456

(3) Create a configuration file for sentinel3: sentinel-26381.conf

touch sentinel-26381.conf
vi sentinel-26381.conf
bind 0.0.0.0
# 配置文件目录
dir /opt/redis-stable/config/
# 日志文件位置
logfile "./sentinel-26381.log"
# pid文件
pidfile /var/run/sentinel_26381.pid
# 是否后台运行
daemonize yes
# 端口
port 26381
# 监控主服务器master的名字:mymaster,IP:127.0.0.1,port:6379,最后的数字2表示当Sentinel集群中有2个Sentinel认为master存在故障不可用,则进行自动故障转移
sentinel monitor mymaster 127.0.0.1 6379 2
# master响应超时时间(毫秒),Sentinel会向master发送ping来确认master,如果在20秒内,ping不通master,则主观认为master不可用
sentinel down-after-milliseconds mymaster 20000
# 故障转移超时时间(毫秒),如果3分钟内没有完成故障转移操作,则视为转移失败
sentinel failover-timeout mymaster 180000
# 故障转移之后,进行新的主从复制,配置项指定了最多有多少个slave对新的master进行同步,那可以理解为1是串行复制,大于1是并行复制
sentinel parallel-syncs mymaster 1
# 指定mymaster主的密码(没有就不指定)
sentinel auth-pass mymaster 123456

3.2, start 3 sentinels

There are 2 ways to start sentinel

  • Method 1:redis-server sentinel.conf --sentinel
  • Method 2:redis-sentinel sentinel.conf

Below we use method 2 to start 3 sentinels

/opt/redis-stable/src/redis-sentinel /opt/redis-stable/config/sentinel-26379.conf
/opt/redis-stable/src/redis-sentinel /opt/redis-stable/config/sentinel-26380.conf
/opt/redis-stable/src/redis-sentinel /opt/redis-stable/config/sentinel-26381.conf

Execute the following commands on the three sentinels respectively to view the information of each sentinel

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 26379
info sentinel

The information of sentinel1 is as follows, and the information of the other two sentinels will not be listed here. Please check it out yourself

Note: Connecting to Sentinel is not equal to connecting to Redis, we will find that the relevant commands entered into Redis will be directly abnormal. The commands supported by Sentinel are documented below the article!

3.3. Use Redis DeskTop to connect sentinel

Using the Redis DeskTop client in windows, you can operate redis by connecting to Sentry.

In essence, he is the Redis host obtained through Sentry, and then it is equivalent to a directly connected Redis host!

The ip of the Redis master configured in sentinel must not be 127.0.0.1, otherwise it may not be able to connect!

3.4. Verify whether the automatic failover is successful

(1) Execute the following command in the master to stop the master

[root@localhost config]# /opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6379 -a 123456
Warning: Using a password with '-a' or '-u' option on the command line interface may not be safe.
127.0.0.1:6379> shutdown
(0.76s)

(2) Wait 2 minutes for the failover to complete

In sentinel, we configure the value of down-after-milliseconds to be 20 seconds, which means that the time for judging that the host is offline is 20 seconds, so we wait for 2 minutes to let the system automatically complete the failover first.

(3) View the master-slave information of slave1, as follows

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6380 -a 123456
info replication

(4) View the master-slave information of slave2, as follows

slave2 becomes the master, and slave2 becomes the slave library of slave1, and the failover is completed.

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6381 -a 123456
info replication

(5) The redis configuration file and the sentinel configuration file have changed:

(6) Next, verify whether slave1 and slave2 are synchronized

Execute the following command in slave2

127.0.0.1:6381>set address china
OK

Execute the following command in slave1 to query the value of address, the effect is as follows, indicating that slave2 and slave1 are synchronously normal

127.0.0.1:6381> get address
"china"

3.4. Restoring the old master to bow down automatically

When the old master is restored, it will automatically hang under the new master. Let's verify whether this is the case.

(1) Execute the following command to start the old master

/opt/redis-stable/src/redis-server /opt/redis-stable/config/redis-6379.conf

(2) Execute the following command to connect to the old master

/opt/redis-stable/src/redis-cli -h 127.0.0.1 -p 6379 -a 123456

(3) Execute the following command to view its master-slave information: info replication

The effect is as follows, indeed consistent with expectations.

4. Commands supported by Sentinel

As a redis node running in a special mode, the sentinel node supports different commands from ordinary redis nodes. In operation and maintenance, we can use these commands to query or modify the sentinel system; but more importantly, the sentinel system cannot achieve various functions such as fault discovery and failover without the communication between sentinel nodes, and the communication is very Much of this is done through commands supported by Sentinel nodes. The main commands supported by Sentinel nodes are introduced below.

(1) Basic query: Through these commands, you can query the topology, node information, configuration information, etc. of the sentinel system.

  • info sentinel: Get the basic information of all the master nodes monitored
  • sentinel masters: Get details of all master nodes monitored
  • sentinel master mymaster: Get detailed information about the monitored master node mymaster
  • sentinel slaves mymaster: Get the details of the slave nodes of the monitored master node mymaster
  • sentinel sentinels mymaster: Get the details of the sentinel node of the monitored master node mymaster
  • sentinel get-master-addr-by-name mymaster: Get the address information of the monitored master node mymaster, which has been introduced in the previous article
  • sentinel is-master-down-by-addr: Sentinel nodes can use this command to ask whether the master node is offline, so as to judge whether it is offline objectively

(2) Add/remove monitoring of the master node

  • sentinel monitor mymaster2 192.168.92.128 16379 2: It is exactly the same as the sentinel monitor function in the configuration file when deploying the sentinel node, no more details

  • sentinel remove mymaster2: cancel the monitoring of the current sentinel node to the master node mymaster2

(3) Forced failover

  • sentinel failover mymaster: This command can force a failover of mymaster, even if the current master node is running well; for example, if the machine where the current master node is located is about to be scrapped, you can use the failover command to perform failover in advance.

Five, Jedis connection Sentinel mode

<dependency>
    <groupId>redis.clients</groupId>
    <artifactId>jedis</artifactId>
    <version>4.4.2</version>
</dependency>
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;

public class SentinelDemo {
    
    
    private static JedisSentinelPool jedisSentinelPool;

    static {
    
    
        try {
    
    
            JedisPoolConfig config = new JedisPoolConfig();
            //最大空闲连接数, 默认8个
            config.setMaxIdle(8);
            //最大连接数, 默认8个
            config.setMaxTotal(8);
            //最小空闲连接数, 默认0
            config.setMinIdle(0);
            //获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,  默认-1
            config.setMaxWaitMillis(3000);
            //在获取连接的时候检查有效性,表示取出的redis对象可用, 默认false
            config.setTestOnBorrow(true);


            //redis服务器列表
            Set<String> sentinels = new HashSet<>();
            sentinels.add(new HostAndPort("192.168.115.78", 26379).toString());
            sentinels.add(new HostAndPort("192.168.115.78", 26380).toString());
            sentinels.add(new HostAndPort("192.168.115.78", 26381).toString());

            //初始化连接池
            jedisSentinelPool = new JedisSentinelPool("mymaster", sentinels, config, "123456");
        } catch (Exception e) {
    
    
            e.printStackTrace();
        }
    }

    public static void main(String[] args) {
    
    
        // 从池中获取一个Jedis对象
        Jedis jedis = jedisSentinelPool.getResource();
        String aaa = jedis.get("aaa");
        System.out.println(aaa);
        jedis.close();
    }
}

6. SpringBoot integrates Sentinel mode

(1) Introduce the maven configuration of redis

<dependency>
	<groupId>org.springframework.boot</groupId>
	<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>

(2) Configure redis sentinel information in application.properties

spring:
  redis:
    sentinel:
      master: mymaster
      nodes: 192.168.115.78:26379,192.168.115.78:26380,192.168.115.78:26381
    # 连接超时时间(毫秒)
    timeout: 60000
    # Redis默认情况下有16个分片,这里配置具体使用的分片,默认是0
    database: 0
    # redis的密码
    password: 123456

(3) Use the RedisTemplate tool class to operate redis

RedisTemplate is used in springboot to operate redis, and this object needs to be injected into our bean. The code is as follows:

@Autowired
private RedisTemplate<String, String> redisTemplate;

// 用下面5个对象来操作对应的类型
this.redisTemplate.opsForValue(); //提供了操作string类型的所有方法
this.redisTemplate.opsForList(); // 提供了操作list类型的所有方法
this.redisTemplate.opsForSet(); //提供了操作set的所有方法
this.redisTemplate.opsForHash(); //提供了操作hash表的所有方法
this.redisTemplate.opsForZSet(); //提供了操作zset的所有方法

(4) RedisTemplate sample code

@RestController
@RequestMapping("/redis")
public class RedisController {
    
    

    @Autowired
    private RedisTemplate<String, String> redisTemplate;

    /**
     * string测试
     *
     * @return
     */
    @RequestMapping("/stringTest")
    public String stringTest() {
    
    
        this.redisTemplate.delete("name");
        this.redisTemplate.opsForValue().set("name", "路人");
        String name = this.redisTemplate.opsForValue().get("name");
        return name;
    }

    /**
     * list测试
     *
     * @return
     */
    @RequestMapping("/listTest")
    public List<String> listTest() {
    
    
        this.redisTemplate.delete("names");
        this.redisTemplate.opsForList().rightPushAll("names", "刘德华", "张学友",
                "郭富城", "黎明");

        List<String> courses = this.redisTemplate.opsForList().range("names", 0,
                -1);
        return courses;
    }

    /**
     * set类型测试
     *
     * @return
     */
    @RequestMapping("setTest")
    public Set<String> setTest() {
    
    
        this.redisTemplate.delete("courses");
        this.redisTemplate.opsForSet().add("courses", "java", "spring",
                "springboot");
        Set<String> courses = this.redisTemplate.opsForSet().members("courses");
        return courses;
    }

    /**
     * hash表测试
     *
     * @return
     */
    @RequestMapping("hashTest")
    public Map<Object, Object> hashTest() {
    
    
        this.redisTemplate.delete("userMap");
        Map<String, String> map = new HashMap<>();
        map.put("name", "路人");
        map.put("age", "30");
        this.redisTemplate.opsForHash().putAll("userMap", map);
        Map<Object, Object> userMap =
                this.redisTemplate.opsForHash().entries("userMap");
        return userMap;
    }

    /**
     * zset测试
     *
     * @return
     */
    @RequestMapping("zsetTest")
    public Set<String> zsetTest() {
    
    
        this.redisTemplate.delete("languages");
        this.redisTemplate.opsForZSet().add("languages", "java", 100d);
        this.redisTemplate.opsForZSet().add("languages", "c", 95d);
        this.redisTemplate.opsForZSet().add("languages", "php", 70);
        Set<String> languages =
                this.redisTemplate.opsForZSet().range("languages", 0, -1);
        return languages;
    }

    /**
     * 查看redis机器信息
     *
     * @return
     */
    @RequestMapping(value = "/info", produces = MediaType.TEXT_PLAIN_VALUE)
    public String info() {
    
    
        Object obj = this.redisTemplate.execute(new RedisCallback<Object>() {
    
    
            @Override
            public Object doInRedis(RedisConnection connection) throws
                    DataAccessException {
    
    
                return connection.execute("info");
            }
        });
        return obj.toString();
    }

(5) The following exception occurs during access

insert image description here

Solution: set no-writes-on-bgsave-error to no in redis.conf

stop-writes-on-bgsave-error no

Guess you like

Origin blog.csdn.net/weixin_43888891/article/details/131039418
Recommended