21、Redis的主从同步

学习目标:

1、了解主从配置的原理

2、掌握主从搭建

学习过程:

       和mysql类似,redis也可以做主从服务器同步的功能,主从服务器的使用场景可以做读写分离,在写数据时使用主服务器,读时使用从服务器,这样就可以减轻服务器的压力。但是仅仅使用主从配置,并不能保证高可用性。如果主服务器挂了,客户端并不会自动选择从服务器的。虽然数据还是在从服务器,并没有丢失,但是事实上客户端已经是不可用的了,需要手动的修改客户端的连接地址。

      还需要注意的是主服务器没有使用持久化,那么在重启主服务时,所有从服务器里面原理保存的数据也会冲掉。所以如果仅仅采用主从模式,并不适合把redis作为储存数据使用,数据丢失时常会发生的。

    但是后面学到的sentinel(哨兵机制)会依赖主从同步,所以主从同步还是必须要学习的。

1、实践

(1)这里当然也需要使用两台redis服务器,我先使用flushdb清空了之前的所有的数据,然后登陆主服务器,先设置几个值,用于后面实验使用的。

192.168.137.101  主服务器

192.168.137.102 从服务器

127.0.0.1:6379> set pre1 liu1
OK
127.0.0.1:6379> set pre2 liu2
OK

(2)主从服务器的配置非常简单,只需要修改从服务器就可以了,打开从服务器redis.conf

设置下面几个属性

slaveof <masterip> <masterport>    指定master的ip和port

masterauth <master-password>       master有验证的情况下

例如:

slaveof 192.168.137.101 6379

masterauth 123456

然后重启从服务器。

2、使用info查看情况

输入info命令

# Replication
role:slave
master_host:192.168.137.101
master_port:6379
master_link_status:up
master_last_io_seconds_ago:3
master_sync_in_progress:0
slave_repl_offset:28
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:9525940eea02b1c3e0809a6f9c8febe45249250c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:28
second_repl_offset:-1
repl_backlog_active:1
repl_backlog_size:1048576
repl_backlog_first_byte_offset:1

如果master_link_status:up表示主服务器是通畅的。

3、登录从服务器

127.0.0.1:6379> get pre1
"liu1"

可以看到在同步启动之前的设置的数据也全部同步过来了。我们登陆一下主服务器,随便set个值

127.0.0.1:6379> set name liubao
OK

再登录从服务器,就可以get出来了。

127.0.0.1:6379> get name
"liubao"

   如果想要保证数据能达到高可用性,那么可以引入sentinel(哨兵机制),哨兵有点类似keepalive,会不断的检查当前的所有主从服务器是否可用,如果从服务器不可用会自动从集群中删除,如果主服务器不可用,那么还需要通过选举自动从服务器中选出新的主服务器。

4、复制同步的偏移量

还记得在启动从服务器时,我们往主服务器添加了几条数据,但是只要从服务器启动后,前面的数据都可以同步过来,下面我们可以做一个实验,先把从服务器关闭了,然后往主服务器插入100000条数据,然后再重启从服务器,看一下能不能同步过来。先关闭从服务器,然后运行下面代码,添加到主服务器

@Test
public void testMore() {
	Jedis jedis = new Jedis("192.168.137.101", 6379);
	jedis.auth("123456");
	
	for (int i = 0; i < 100000; i++) {
		jedis.set("name" + i, "liubao" + i);
	}
	jedis.close();
}

插入数据后再启动从服务器。发现从服务器还是可以同步数据的,为什么呢?可以分别再主服务器和从服务都运行info,查看一下,复制情况,原来再从服务器和主服务器都会记录同步的偏移量,如果从服务器落后了,会自动根据原来记录的偏移量追上主服务器。

主服务器:

# Replication
role:master
connected_slaves:1
slave0:ip=192.168.137.102,port=6379,state=online,offset=8666972,lag=0
master_replid:9525940eea02b1c3e0809a6f9c8febe45249250c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:8666972

从服务器:

# Replication
role:slave
master_host:192.168.137.101
master_port:6379
master_link_status:up
master_last_io_seconds_ago:1
master_sync_in_progress:0
slave_repl_offset:8666972
slave_priority:100
slave_read_only:1
connected_slaves:0
master_replid:9525940eea02b1c3e0809a6f9c8febe45249250c
master_replid2:0000000000000000000000000000000000000000
master_repl_offset:8666972

Redis 同步的是指令流,主节点会将指令记录在本地的内存中,然后异步将 buffer 中的指令同步到从节点,从节点同步的指令流成功后,记录本身的同步后的偏移量,同时向主节点反馈从服务器同步到偏移量,这样主服务器也就知道从服务器同步到哪里了,但是如果需要同步的指令很多,超过了缓存的大小(类似FIFO,超过的指令会给抹去),缓存的大小是通过 repl-backlog-size,可以看一下说明,默认是1M,这里我就不再翻译了,还有另外一个参数repl-backlog-ttl,是在在没有Slave的情况下过多久释放的时间阈值。

# slave data when slaves are disconnected for some time, so that when a slave
# wants to reconnect again, often a full resync is not needed, but a partial
# resync is enough, just passing the portion of data the slave missed while
# disconnected.
#
# The bigger the replication backlog, the longer the time the slave can be
# disconnected and later be able to perform a partial resynchronization.
#
# The backlog is only allocated once there is at least a slave connected.
#
# repl-backlog-size 1mb

说到这里就有一个疑问了,如果从服务器关闭的时间比较长,主服务器缓存的大小(repl-backlog-size)超过了1M,那么同步的命令肯定会覆盖了一部分,是否会操作主从不一致的问题。通过前面的实验,我们发现主从并没有不一致,redis又是怎么做到这一点的呢,这里哦我们就要说一下同步的过程了:

1、从服务器向主服务器发送SLAVEOF命令,让当前服务器成为Slave; 
2、从服务器根据自己是否保存Master runid来判断是否是第一次复制,如果是第一次同步向主服务器发送PSYNC ? -1 命令来进行完整同步,向Master发送PSYNC runid offset,PSYNC 命令时redis2.8后才有的,参数意义时:runid(主服务器的id)、offset(复制偏移量)。
3、主服务器如果一致则会再次判断offset偏移量和本机的偏移量相差有没有超过复制积压缓冲区大小,如果没有那么就给Slave发送CONTINUE,从服务器执行失去连接期间丢失的命令即可。这样断线后重连的效率就会更高。
4、如果offset差距超过了复制积压缓冲区大小,那么就会返回FULLRESYNC runid offset,Slave将runid保存起来,并进行全量同步。

所以在生产环境中可以适当的调大一点repl-backlog-size,毕竟全量的同步效率会比较高。

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值