一、概述

master同步自己数据到slave上。

数据流向是单向的,master到slave。

可以一个master有多个slave。

一个slave只能有一个master。

主从复制主要解决单机故障的问题。

可以读写分离,master写,而读可以分流到各个slave上。

不会故障自动转移。

1.主要作用:

1.为数据提供多个副本

2.扩展了redis读的性能,可以做读写分离。

2.实现主从复制的两种方式

1.slave of 命令  无需重启

如果希望B成为A的从节点,在B机器上执行slaveof a的ip a的port

如果从节点不想再做从节点,则在从节点上执行 slaveof no one   这样并不会清除从节点已经同步的数据

2.修改配置文件   需要重启

这里两台机器node1是master,node2是slave。两台机器都要安装redis

先根据单机介绍安装好node1,然后拷贝到node2上

cd /app

scp -r redis root@node2:/app

【一】linux安装redis(单机版)、3种启动方式、及配置文件介绍。

修改node2的配置文件

cd /app/redis/config/

vi redis-6379.conf

protected-mode no
port 6379
daemonize yes
pidfile /var/run/redis_6379.pid
logfile "6379.log"
dir /app/redis/data
slave-read-only yes
slaveof node1 6379

slaveof node1 6379  配置它是谁的从节点

slave-read-only yes  从节点只做读的操作

启动master

启动slave

cd /app/redis/src

./redis-server /app/redis/config/redis-6379.conf

分别在node1和node2的命令行输入info replication

redis master 变成了slave redis slaveof_主从复制

redis master 变成了slave redis slaveof_偏移量_02

测试数据是否同步到从节点

在node1的redis中 set test master

redis master 变成了slave redis slaveof_主从复制_03

在node2的redis中 get test

redis master 变成了slave redis slaveof_主从复制_04

runid

redis每次启动都有一个runid。

slave知道master的runid,如果slave察觉到master的runid发生了变化,slave会从master中全量同步数据,因为master可能重启可能做了很大的变化。

输入info可以查看runid

redis master 变成了slave redis slaveof_redis_05

偏移量

redis master 变成了slave redis slaveof_redis_06

二、同步机制

1.全量复制

redis master 变成了slave redis slaveof_redis_07

全量复制,复制的是数据

psync runid offset 第一个参数是runid,第二个参数是偏移量。

第一次复制不知到runid和偏移量用 psync ? -1

过程说明:

1.slave 服务启动,slave 会建立和 master 的连接,第一次复制发送 psync ? -1命令。

2.master看到是psync ? -1知道是全量复制,是第一次复制,会发送runId和offerset给slave。

3.slave保存master发过来的信息

4.master 启动一个后台线程使用bgsave命令将数据库快照保存到 RDB 文件中

注意:此时如果生成 RDB 文件过程中存在写数据操作会导致 RDB 文件和当前主 redis 数据不一致,所以此时 master 主线程会开始收集写命令并缓存起来

5.master发送RDB文件给slave

6.master 把缓存的命令转发给 slave

7和8.slave 将文件保存到磁盘上,然后加载到内存恢复

注意:

1.如果 master 同时收到多个 slave 发来的同步连接命令,只会启动一个进程来写数据库镜像,然后发送给所有 slave。

2.后续 master 收到的写命令都会通过开始建立的连接发送给 slave。

3.当 master 和 slave 的连接断开时 slave 可以自动重新建立连接。

发生场景:

全量同步一般只在slave第一次连接master,或者部分重同步失败时进行,当然实际上slave可以随时发起全量同步。

2.增量同步

当一个 master 实例和一个 slave 实例连接正常时, master 会发送一连串的命令流来保持对 slave 的更新,以便于将自身数据集的改变复制给 slave :包括客户端的写入、key 的过期或被逐出等等(slave不会主动过期key)。

增量同步,master发给slave的不是数据,是命令。

3.部分复制

如果:从节点第一次全量复制后,运行一段时间从节点停止运行,再启动从节点时可能只有少部分数据和主节点 不同步,此时从节点只需要向主节点请求部分复制就行了

slave的偏移量在master的repl_back_buffer内,就部分复制。

注意:如果从节点网络中断时间过长,导致主节点没有能够完整地保存中断期间执行的写命令,则无法进行部分复制,仍使用全量复制。

redis master 变成了slave redis slaveof_偏移量_08

报错

使用主从复制的时候有一个slave一直在同步master的时候连接超时,master上info查不到这个slave。下面的slave的日志

WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and then reboot or run the command 'sysctl vm.overcommit_memory=1' for this to take effect.
5517:S 07 Aug 18:41:23.427 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > /sys/kernel/mm/transparent_hugepage/enabled' as root, and add it to your /etc/rc.local in order to retain the setting after a reboot. Redis must be restarted after THP is disabled.
5517:S 07 Aug 18:41:23.428 * DB loaded from disk: 0.000 seconds
5517:S 07 Aug 18:41:23.428 * The server is now ready to accept connections on port 6379
5517:S 07 Aug 18:41:23.428 * Connecting to MASTER node1:6379
5517:S 07 Aug 18:41:23.429 * MASTER <-> SLAVE sync started
5517:S 07 Aug 18:42:24.263 # Timeout connecting to the MASTER...
5517:S 07 Aug 18:42:24.264 * Connecting to MASTER node1:6379
5517:S 07 Aug 18:42:24.265 * MASTER <-> SLAVE sync started
5517:S 07 Aug 18:43:25.249 # Timeout connecting to the MASTER...
5517:S 07 Aug 18:43:25.250 * Connecting to MASTER node1:6379
5517:S 07 Aug 18:43:25.251 * MASTER <-> SLAVE sync started
5517:S 07 Aug 18:44:26.082 # Timeout connecting to the MASTER...
5517:S 07 Aug 18:44:26.083 * Connecting to MASTER node1:6379
5517:S 07 Aug 18:44:26.084 * MASTER <-> SLAVE sync started
5517:S 07 Aug 18:45:27.933 # Timeout connecting to the MASTER...
5517:S 07 Aug 18:45:27.933 * Connecting to MASTER node1:6379
5517:S 07 Aug 18:45:27.934 * MASTER <-> SLAVE sync started
5517:S 07 Aug 18:46:28.771 # Timeout connecting to the MASTER...
5517:S 07 Aug 18:46:28.771 * Connecting to MASTER node1:6379
5517:S 07 Aug 18:46:28.772 * MASTER <-> SLAVE sync started
5517:S 07 Aug 18:47:29.616 # Timeout connecting to the MASTER...
5517:S 07 Aug 18:47:29.617 * Connecting to MASTER node1:6379
5517:S 07 Aug 18:47:29.618 * MASTER <-> SLAVE sync started