深度好文:保姆级教程Redis高可用之主从复制
贴心式服务,手把手教你搭建redis主从复制架构,然后介绍了redis主从复制原理,全量复制和部分复制,最后演示了java代码如何操作redis。希望对你有所帮助。
Redis 主从架构
Redis 支持简单且易用的主从复制功能, 主从复制可以让从服务器成为主服务器的精确复制品。主从复制架构图如下所示:
Redis 主从架构搭建
Redis 集群搭建比较简单,从节点配置直接点信息replicaof <masterip> <masterport>
,如果主节点有认证信息可通过 masterauth <master-password>
配置指定。
cd /usr/local/
wget https://download.redis.io/releases/redis-6.2.6.tar.gz
tar -zxvf redis-6.2.6.tar.gz
cd redis-6.2.6/
make
## 到此已经安装完成
## 备份配置文件
cp redis.conf redis.conf_bak
# 创建主从工作目录
mkdir -p replication/6379 # master 节点
mkdir -p replication/6380 # 从节点
mkdir -p replication/6381 # 从节点
# 复制配置文件到主节点工作目录:
cp redis.conf replication/6379/
# 使用vim 命令修改主节点信息:
vim replication/6379/redis.conf
# 修改后台启动
daemonize yes
# redis 运行端口
port 6379
# pid号写入哪个配置文件
pidfile /var/run/redis_6379.pid
# 指定数据文件的存放位置,因为需要在一台机器启动两个实例,所以必须指定不同的位置,不然会丢失数据
dir /usr/local/redis-6.2.6/replication/6379/
# 注释上允许所有网卡访问,
# bind 127.0.0.1 -::1
# 关闭保护模式
protected-mode no
# 开启 AOF 存储
appendonly yes
按照上述步骤操作以后,master 主节点配置完成,现在可以启动 master。
/usr/local/redis-6.2.6/src/redis-server replication/6379/redis.conf
执行上面的命令,没有任何提示说明启动成功。可以使用客户端连接进行验证。
[root@beifeng redis-6.2.6]# ./src/redis-cli -p 6379
127.0.0.1:6379> set beifeng ok
OK
我们接下来以 6379 实例的配置文件为模板,对两个从节点进行配置。按照以下步骤配置 6380 节点
# 拷贝6379的配置文件到6380实例
cp replication/6379/redis.conf replication/6380/
# 替换6379为6380
sed -i 's/6379/6380/g' replication/6380/redis.conf
vim replication/6380/redis.conf
# 找到 replicaof 配置项,添加如下配置
replicaof 172.16.38.12 6379
启动 6380 从节点
/usr/local/redis-6.2.6/src/redis-server replication/6380/redis.conf
配置 6381 节点
cp replication/6380/redis.conf replication/6381/
sed -i 's/6380/6381/g' replication/6381/redis.conf
启动 6380 从节点
/usr/local/redis-6.2.6/src/redis-server replication/6380/redis.conf
可以使用 redis 客户端连接 master 节点新增数据,然后连接另外两个节点进行验证。
./src/redis-cli -p 6380 # -p 指定端口号
127.0.0.1:6380> info
# Replication
role:slave
master_host:172.16.38.12
master_port:6379
master_link_status:up
至此 redis 主从架构已经完成。是不是 so easy ~ 文末提供配置文件下载路径。
Redis 主从工作原理
如果为 master 配置了一个 slave,不管这个 slave 是否是第一次连上 master,它都会发送一个 PSYNC
命令给 master请求复制数据。
master 收到 PSYNC
命令后,会在后台进行数据持久化通过 bgsave 生成最新的 rdb 快照文件;
持久化期间,master 会继续接收客户端的请求,master 会把可能修改数据集的请求缓存在内存中。
当持久化进行完毕以后,master 会把这份 rdb 文件数据集发送给 slave,slave 会把接收到的数据进行持久化生成 rdb,然后加载到内存。然后,master 在将之前缓存在内存中的命令发送给 slave。
当 master 与 slave 之间的连接由于某些原因而断开时,slave 能够自动重连 master,如果 master 收到了多个 slave 的并发连接请求,master 只会进行一次持久化,而不是一个连接创建一次快照,然后再把这一份持久化的数据发送给多个并发连接的 slave。
主从全量复制流程图
数据部分复制
当 master 和 slave 断开重连后,一般都会对整份数据进行复制。但从 Redis2.8 版本开始,Redis 改用可以支持部分数据复制的命令PSYNC
去 master 同步数据,slave 与 master 能够在网络端口重连后只进行部分数据复制。
master 会在其内存创建一个复制数据用的缓存队列,缓存最近一段时间的数据,master 和它所有的 slave 都维护了复制的数据下标 offset 和 master 的进程 id,因此,当网络连接断开后,slave 会继续请求 master 继续进行未完成的复制,从所记录的数据下标开始。
如果 master 进程 id 变化了,或者从节点数据下标 offset 太旧,已经不在 master 的缓存队列里了,那么将会进行一次全量数据的复制。
缓冲区大小修改配置:repl-backlog-size 1mb
可以使用 Telnet 连接到 master 节点,然后发送 SYNC
命令观察数据同步。
[root@beifeng redis-6.2.6]# telnet 127.0.0.1 6379
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
##### 执行sync 观察输出
sync
$203
REDIS0009� redis-ver6.2.6�
redis-bits�@�ctime�v�Qbused-mem�P��repl-stream-db��repl-id(ff2584972b5daa74ebb8c39129e853885d9be94b�
repl-offset�=�
aof-preamble���ddbeifengokaa/��Gq�*1
$4
ping
*1
$4
ping
*1
$4
ping
*2
$6
SELECT
$1
0
*3
$3
set
$5
hello
$5
world
主从复制风暴
如果有很多从节点,多个从节点同时复制主节点导致主节点压力过大,也就是所谓的主从风暴;不仅主服务器可以有从服务器, 从服务器也可以有自己的从服务器, 多个从服务器之间可以构成一个图状结构。为了缓解主节点压力可以做如下架构,让部分从节点与从节点同步数据。
代码实战
引入 jedis
使用 jedis
驱动操作 redis,创建 maven 工程,引入如下依赖。
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>4.2.0</version>
</dependency>
基础代码示例
public class JedisTest {
public static void main(String[] args) {
JedisPoolConfig poolConfig = new JedisPoolConfig();
poolConfig.setMaxTotal(20);
poolConfig.setMaxIdle(10);
poolConfig.setMinIdle(5);
JedisPool jedisPool = new JedisPool(poolConfig,"172.16.38.6",6379);
try (Jedis jedis = jedisPool.getResource()) {
jedis.set("name", "beifeng");
}
}
}
上述代码简单演示了如何使用 java 客户端进行操作,后续会有详细介绍。
redis 主从复制是哨兵和集群的基础,希望大家多花时间重点掌握,一定要花时间自己动手实践一遍,实践出真知。