本文共 3761 字,大约阅读时间需要 12 分钟。
redis主从复制过程
Redis使用异步复制,当配置好slave后,slave与master建立连接,然后发送sync命令。无论是第一次连接还是重新连接,master都会启动一个后台进程,将 数据库快照保存到文件中,同时master主进程会开始收集新的写命令并缓存。后台进程完成写文件后,master就发送文件给slave,slave将 文件保存到硬盘上,再加载到内存中,接着master就会把缓存的命令转发给slave,后续master将收到的写命令发送给slave。
如果master同时收到多个slave发来的同步连接命令,master只会启动一个进程来写数据库镜像,然后发送给所有的slave。master同步数据时是非阻塞式的,可以接收用户的读写请求。然而在slave端是阻塞模式的,slave在同步master数据时,并不能够响应客户端的查询。从服务器会周期性的应答从复制流中处理的数据量。
可以一主多从,从服务器是只读的(
从Redis 2.6开始,从服务器支持只读模式,并且是默认模式。这个行为是由Redis.conf文件中的slave-read-only 参数控制的,可以在运行中通过CONFIG SET来启用或者禁用。从服务器像DEBUG或者CONFIG这样的管理命令还是可以运行的。不过你可以通过使用rename-command命令来为这些命令改名来增加安全性),主服务器进行读写时,会转移到从读,减轻服务器压力,主从都可以设置密码,也可以密码不一致
当主从服务器之间的连接由于某些原因断开时,从服务器可以自动进行重连接。当有多个从服务器同时请求同步时,主服务器只进行一个后台存储。
从Redis 2.8版本开始,可以配置主服务器连接N个以上从服务器才允许对主服务器进行写操作。但是,因为Redis使用的是异步主从复制,
没办法确保从服务器确实收到了要写入的数据,所以还是有一定的数据丢失的可能性。
工作原理如下:
1)从服务器每秒钟ping一次主服务器,确认处理的复制流数量。
2)主服务器记住每个从服务器最近一次ping的时间。
3)用户可以配置最少要有N个服务器有小于M秒的确认延迟。
4)如果有N个以上从服务器,并且确认延迟小于M秒,主服务器接受写操作。
还可以把这看做是CAP原则(一致性,可用性,分区容错性)不严格的一致性实现,虽然不能百分百确保一致性,但至少保证了丢失的数据不会超过M秒内的数据量。
如果条件不满足,主服务器会拒绝写操作并返回一个错误。
1)min-slaves-to-write(最小从服务器数)
2)min-slaves-max-lag(从服务器最大确认延迟)
当连接断开又重新连上之后,一般都会进行一个完整的重新同步,但是从Redis2.8开始,只重新同步一部分也可以。
部分重新同步工作原理是这样:
主服务器端为复制流维护一个内存缓冲区(in-memory backlog)。主从服务器都维护一个复制偏移量(replication offset)和master run id ,
当连接断开时,从服务器会重新连接上主服务器,然后请求继续复制,假如主从服务器的两个master run id相同,并且指定的偏移量在内存缓冲
区中还有效,复制就会从上次中断的点开始继续。如果其中一个条件不满足,就会进行完全重新同步(在2.8版本之前就是直接进行完全重新同步)。
因为主运行id不保存在磁盘中,如果从服务器重启了的话就只能进行完全同步了。
部分重新同步这个新特性内部使用PSYNC命令,旧的实现中使用SYNC命令。Redis2.8版本可以检测出它所连接的服务器是否支持PSYNC命令,不支持的
话使用SYNC命令。
一个完全重新同步需要在磁盘上创建一个RDB文件,然后加载这个文件以便为从服务器发送数据。
如果使用比较低速的磁盘,这种操作会给主服务器带来较大的压力。Redis从2.8.18版本开始尝试支持无磁盘的复制。
使用这种设置时,子进程直接将RDB通过网络发送给从服务器,不使用磁盘作为中间存储。
使用repl-diskless-sync配置参数来启动无磁盘复制。使用repl-diskless-sync-delay 参数来配置传输开始的延迟时间,以便等待
更多的从服务器连接上来。
配置
我这里是一台机器上多实例配置主从,采用一主三从,通过haproxy做从的分发。
master:6379
slave:6380、6381、6382
haproxy:6378
master
[root@localhost redis]# cat etc/redis6379.conf |grep -v "#"|sed "/^[[:space:]]*$/d"daemonize yespidfile /var/run/redis_6379.pidport 6379logfile /app/redis/logs/redis6379.logdatabases 16save 900 1save 300 10save 60 10000dbfilename 6379.rdbdir /app/redis/data/requirepass ywbz@4.117......[root@localhost bin]# ./redis-cli -p 6379 -a ywbz@4.117127.0.0.1:6379> info......# Replicationrole:masterconnected_slaves:3slave0:ip=127.0.0.1,port=6381,state=online,offset=128886182724,lag=0slave1:ip=127.0.0.1,port=6380,state=online,offset=128886182724,lag=0slave2:ip=127.0.0.1,port=6382,state=online,offset=128886120626,lag=1master_replid:9744431b03d430d64ace5aefd18aa54d3d99b317master_replid2:0000000000000000000000000000000000000000master_repl_offset:128886182724second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:128885134149repl_backlog_histlen:1048576......127.0.0.1:6379> quit[root@localhost bin]#
slave
[root@localhost redis]# cat etc/redis6380.conf |grep -v "#"|sed "/^[[:space:]]*$/d"daemonize yespidfile /var/run/redis_6380.pidport 6380logfile /app/redis/logs/redis6380.logdatabases 16save 900 1save 300 10save 60 10000dbfilename 6380.rdbdir /app/redis/data/slaveof 127.0.0.1 6379masterauth ywbz@4.117requirepass ywbz@4.117[root@localhost bin]# ./redis-cli -p 6380 -a ywbz@4.117127.0.0.1:6380> info......# Replicationrole:slavemaster_host:127.0.0.1master_port:6379master_link_status:upmaster_last_io_seconds_ago:1master_sync_in_progress:0slave_repl_offset:128890251317slave_priority:100slave_read_only:1connected_slaves:0master_replid:9744431b03d430d64ace5aefd18aa54d3d99b317master_replid2:0000000000000000000000000000000000000000master_repl_offset:128890251317second_repl_offset:-1repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:128889202742repl_backlog_histlen:1048576......127.0.0.1:6380> quit[root@localhost bin]#
转载地址:http://ryxxa.baihongyu.com/