企业级Redis开发运维从入门到实践 (20)— Redis复制的原理与优化

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/zx711166/article/details/82971705

什么是主从复制

单机有什么问题?

单机存在机器故障、容量瓶颈、QPS(每秒查询率)瓶颈的问题。

主从复制的作用
  • 数据副本
  • 扩展读性能;

一对一的主从结构
在这里插入图片描述

一对多的主从结构(主从备份、读写分离)
在这里插入图片描述

简单示例
主节点 set 数据后,从节点可以 get 到主节点中写入的数据。
在这里插入图片描述

总结
  • 一个 master 可以有多个 salve。
  • 一个 salve 只能有一个 master。
  • 数据流向是单向的,master 到 slave。

主从复制的配置 — 介绍

两种实现方式
  • slaveof命令
  • 配置
命令实现

实现复制

  1. client客户端执行 slaveof 命令;
  2. 从节点向客户端返回消息(异步过程);
  3. 从节点从主节点复制数据。

在这里插入图片描述

从节点通过slave of切换新的主节点

通过slaveof命令还可以实现切主操作,所谓切主是指把当前从节点对主节点的复制切换到另一个主节点。
执行slaveof{newMasterIp} {newMasterPort}命令即可,
例如把6380节点从原来的复制6379节点变为复 制6381节点,如图6-3所示

  1. 断开与旧主节点复制关系;
  2. 与新主节点建立复制关系;
  3. 删除从节点当前所有数据;
  4. 对新主节点进行复制操作。
    在这里插入图片描述

取消复制

  1. client客户端执行 slaveof no one 命令;
  2. 从节点与主节点断开连接(之前从主节点复制的数据不会被清除,之后主节点新写入的数据不会同步到从节点);
  3. 从节点向客户端返回消息(同步过程);
  4. 从节点晋升为主节点。

在这里插入图片描述

修改配置
# 当前节点称为某一个主节点的从节点
slaveof  ip  port

# 设置该从节点只读
slave-read-only  yes
比较
方式 命令 配置
优点 无需重启 统一配置
缺点 不便于管理 需要重启

主从复制的配置 — 验证

  1. 创建一个配置文件目录,存放Redis启动配置文件
[root@localhost config]# ll
total  88
-rw-r--r--   1  carlosfu    staff       41K     10   7    22:56   redis.log
  1. 创建6379服务(主节点)的配置文件
[root@localhost config]# cp redis.conf  redis-6379.conf
[root@localhost config]# vim  redis-6379.conf
...
# daemonize表示以守护线程方式启动Redis,默认是no
daemonize yes
...
# pidfile表示进程PID文件
pidfile /var/run/redis-6379.pid
...
# port表示服务端口号
port 6379
...
# logfile表示日志文件
logfile "6379.log"
...
# save表示配置RDB自动save条件,实际生产不会使用
#save 900 1
#save 300 10
#save   60 10000
...
# dbfilename表示设置RDB文件名,防止单机多节点是RDB文件产生混乱
dbfilename   dump-6379.rdb
...
# dir表示dbfilename文件的工作目录
dir /opt/soft/redis/redis/data/
...
wq!
  1. 创建6380服务(从节点)的配置文件
[root@localhost config]# cp redis-6379.conf  redis-6380.conf
[root@localhost config]# vim  redis-6380.conf
...
# daemonize表示以守护线程方式启动Redis,默认是no
daemonize yes
...
# pidfile表示进程PID文件
pidfile /var/run/redis-6380.pid
...
# port表示服务端口号
port 6380
...
# logfile表示日志文件
logfile "6380.log"
...
# save表示配置RDB自动save条件,实际生产不会使用
#save 900 1
#save 300 10
#save   60 10000
...
# dbfilename表示设置RDB文件名,防止单机多节点是RDB文件产生混乱
dbfilename   dump-6380.rdb
...
# dir表示dbfilename文件的工作目录
dir /opt/soft/redis/redis/data/
...
# slaveof <masterip> <masterport>表示对从节点配置主节点信息
slaveof 127.0.01 6379
...
wq!
  1. 查看配置文件
[root@localhost config]# ll
-rw-r--r--   1  carlosfu    staff       41K     10   7    22:59   redis-6379.log
-rw-r--r--   1  carlosfu    staff       41K     10   7    23:01   redis-6380.log
-rw-r--r--   1  carlosfu    staff       41K     10   7    22:56   redis.log
  1. 启动6379的服务(主节点)、验证服务是否正常、查看节点信息
[root@localhost config]# redis-server redis-6379.conf
[root@localhost config]# ps -ef | grep  redis-server
501	77051		1	0	11:01 下午	??	     0:00.01	redis-server	*:6379
501	77057	76575	0	11:01 下午	ttys001	 0:00.00	grep --color=auto  --exclude-dir-.bar --exclude-dir-CVS --exclude-dir=.git --exclude-dir=.hg --exclude-dir=.svn redis-server

# 连接客户端
[root@localhost config]# redis-cli
# 查看节点信息
127.0.0.1:6379> info replication
# Replication
role:master												  #节点角色
connected_slaves:0								  #连接从节点个数
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6379> exit
  1. 启动6380的服务(从节点)、验证服务是否正常、查看节点信息
# 启动6380的服务
[root@localhost config]# redis-cli -p 6380
Could not connect to Redis at 127.0.0.1:6379:    Connection refused not connected> exit
[root@localhost config]# redis-server redis-6380.conf
[root@localhost config]# ll
total 264
-rw-r--r--   1  carlosfu    staff         0B     10   30    23:01   6379.log
-rw-r--r--   1  carlosfu    staff         0B     10   30    23:02   6380.log
-rw-r--r--   1  carlosfu    staff       41K     10   30    22:59   redis-6379.log
-rw-r--r--   1  carlosfu    staff       41K     10   30    23:01   redis-6380.log
-rw-r--r--   1  carlosfu    staff       41K     10   30    22:56   redis.log

# 查看服务是否启动成功
[root@localhost config]# ps -ef | grep  redis-server | grep 6380
501	77080		1	0	11:02 下午	??	     0:00.01	redis-server	*:6380

# 查看节点信息
[root@localhost config]# redis-cli -p 6380 info replication
# Replication
role:slave												     #节点角色
master_hosts:127.0.0.1                           #主节点ip
master_port:6379									 #主节点端口
master_link_status:up                              #与主节点连接状态,up为正常
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:43
slave_priority:100
slave_read_only:1
connected_slaves:0								  #连接从节点个数
master_repl_offset:0
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
  1. 数据同步
# 主节点写入数据
[root@localhost config]# redis-cli
127.0.0.1:6379> set hello world
OK
127.0.0.1:6379> exit

#从节点查看数据
[root@localhost config]# redis-cli -p 6380
127.0.0.1:6380> get hello
"world"
# 从节点设置了只读,set将会报错
127.0.0.1:6380> set hello java
(error) READONLY you con`t write against a read only slave.
127.0.0.1:6379> exit
  1. 查看6379日志(主节点)
[root@localhost config]# cd ../data
[root@localhost data]# ll
total 32
-rw-r--r--   1  carlosfu    staff      1.9K     10   30    23:02   6379.log
-rw-r--r--   1  carlosfu    staff      2.1K     10   30    23:02   6380.log
-rw-r--r--   1  carlosfu    staff       18B     10   30    23:02   dump-6379.rdb
-rw-r--r--   1  carlosfu    staff       18B     10   30    23:02   dump-6380.rdb
[root@localhost data]# cat 6379.log
...
# 连接从节点
77051:M 30 Oct 23:02:31.398 * Slave 127.0.0.1:6380 asks for synchronization
# 全量复制请求
77051:M 30 Oct 23:02:31.398 * Full resync requested by slave 127.0.0.1:6380
# 准备通过 bgsave 创建一个 RDB 以便于进行同步
77051:M 30 Oct 23:02:31.398 * Starting BGSAVE for SYNC with target: disk
# 执行 bgsave 创建 RDB
77051:M 30 Oct 23:02:31.398 * Backgrounp saving started by pid 77083
# DB 落盘到硬盘中
77083:M 30 Oct 23:02:31.398 * DB saved on disk
# bgsave 生成 RDB 文件成功
77051:M 30 Oct 23:02:31.417 * Backgrounp saving terminated with success
# 从节点同步成功
77051:M 30 Oct 23:02:31.417 * Synchronization with slave 127.0.0.1:6379 succeeded
...
  1. 查看6380日志(从节点)
[root@localhost data]# cat 6380.log
...
# 连接主节点
77080:S 30 Oct 23:02:31.396 * Connecting to MASTER 127.0.0.1:6379
# 主从复制已经开始
77080:S 30 Oct 23:02:31.397 * MASTER < - > SLAVE sync started
# 用于同步触发事件的非阻塞连接
77080:S 30 Oct 23:02:31.396 * Non blocking connect for SYNC fired the event
# 主节点ping恢复,复制继续
77080:S 30 Oct 23:02:31.396 * Master replied to PING, replication can continue...
# 部分重新同步不可能(没有缓存的主控)
77080:S 30 Oct 23:02:31.396 * Partial resynchronization not possible (no cached master)
# 从主机完全恢复(345dda992e5064bc80e01f96ea90f729b722b2ea是Redis节点的run_id)
77080:S 30 Oct 23:02:31.399 * Full resync from master: 345dda992e5064bc80e01f96ea90f729b722b2ea:1
# 从主机接收18字节(18字节是RDB文件)
77080:S 30 Oct 23:02:31.417 * MASTER < - > SLAVE sync: receiving 18 bytes from master
# 刷新旧数据
77080:S 30 Oct 23:02:31.417 * MASTER < - > SLAVE sync: Flushing old data
# 加载数据到内存中
77080:S 30 Oct 23:02:31.417 * MASTER < - > SLAVE sync: Loading DB in memory
# 成功完成复制
77080:S 30 Oct 23:02:31.417 * MASTER < - > SLAVE sync: Finished with success

# 查看服务信息
[root@localhost data]# redis-cli info
# Server
...
run_id:345dda992e5064bc80e01f96ea90f729b722b2ea
...
  1. 取消复制:从节点取消复制后变为主节点,重新连接复制,从节点的数据将会被清除
# 取消6380的复制
[root@localhost data]# redis-cli -p 6380
127.0.0.1:6380> slaveof no one
OK
127.0.0.1:6380> info replication
# Replication
role:master												#节点角色
connected_slaves:0								#连接从节点个数
master_repl_offset:549
repl_backlog_active:0
repl_backlog_size:1048576
repl_backlog_first_byte_offset:0
repl_backlog_histlen:0
127.0.0.1:6380> exit

# 在6379里写入数据
[root@localhost data]# redis-cli -p
127.0.0.1:6379> info replication
# Replication
role:master												#节点角色
connected_slaves:0								#连接从节点个数
master_repl_offset:577
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:2
repl_backlog_histlen:576
127.0.0.1:6379> mset a b c d f g h
OK
127.0.0.1:6379> dbsize
(integer) 5
127.0.0.1:6379> exit

[root@localhost data]# redis-cli -p 6380
127.0.0.1:6380> dbsize
(integer) 1
# 清除数据
127.0.0.1:6380> flushall
OK
# 写入不同的数据
127.0.0.1:6380> set abc6380 hello
OK
# 重新连接6379进行复制
127.0.0.1:6380> slaveof 127.0.0.1 6379
OK
# 原来的数据被清除了
127.0.0.1:6380> get abc6380
(nil)
127.0.0.1:6380> exit

猜你喜欢

转载自blog.csdn.net/zx711166/article/details/82971705