Redis有三种集群模式,分别是主从、“哨兵”、Cluster集群模式。今天,我们就来说说主从模式。Redis主从模式是最简单的集群模式,类似于MySQL等数据库的主从模式。Slave同步与Redis主从原理Redis实现主从复制(Master-SlaveReplication)原理:Slave从节点服务启动并连接Master后,会主动发送SYNC命令,SYNC命令Master服务主节点收到同步命令后会发送SYNC命令启动后台保存进程,收集所有收到的修改数据集的命令。后台进程执行完毕后,Master会将整个数据库文件传输给Slave,完成一次完整的同步。Slave从节点服务接收到数据库文件数据后,将数据库文件数据保存并加载到内存中。之后Master主节点继续将收集到的所有修改命令和新的修改命令一次性发送给Slave,Slave会在本地执行这些数据修改命令,从而实现最终的数据同步。如果Master和Slave之间的链接断开,Slave可以自动重连Master,但链接成功后会自动进行全量同步。主从同步特性一个master可以有多个slave,一个slave只能有一个master的数据流向是单向的。master和slave的优点主从读写分离,提高效率,数据热备份,提供多个replicaslave同时可以接受其他slave的连接和同步请求,有效缓解master的同步压力。阻塞方式为slave提供同步服务,因此client在同步期间仍然可以提供查询和修改。从机也以非阻塞的方式进行数据同步。在同步期间,如果client发起查询请求,slave返回同步前的数据。节点故障后,集群无法正常工作,无法提供高可用性。从一个节点升级到master节点需要在master节点的单点进行人工干预,这可能会导致性能下降。主节点的存储容量是有限的。不能及时同步到从机,会造成数据不一致,降低系统的可用性。主从复制采用全量复制。复制过程中会fork子进程对内存进行快照,子进程的内存快照会保存为文件发送给slave。因此,这个过程需要足够的内存。主从复制过程中,对网络的要求非常高,网络抖动会造成全量复制,对实际系统运行造成很大的不稳定。完全同步可能会导致毫秒或秒。主从同步完整执行流程1.当slave开始第一次连接master,或者“被认为是第一次连接”(比如主从断开后重新连接),主从使用fullreplication2.从库定时任务每秒检查是否有新的master需要连接。如果找到,则与master建立套接字连接。3、从库(从)向master发送ping命令,master返回pong,则连接正常4、从库(从)向master发送auth认证信息,验证requirepass5。鉴权通过后,从库(slave)向master发送sync命令,请求数据同步6.master收到同步请求后,向slave发送run_id和offset7.slave会接收并保存发来的信息master8.master执行bgsave命令生成一个RDB文件,期间会创建一个copybuffer来记录从现在开始执行的所有写命令9.master将RDB数据发送给slave,然后发送copybufferrecordData,slave会将RDB和buffer数据存入磁盘10.slave清除原有数据,最后将从磁盘接收到的数据导入到内存中。11、master后续收到的写命令会通过之前建立的master-slave连接,增量发送给slave端。主从搭建实践CentOS7默认源是要安装Redis3.2版本,先看3.x版本的Redis主从#安装redisyum-yinstallredis#配置masterredisvim/etc/redis.confbind172.22.29.87protected-modeyesport6379daemonizeyespidfile/var/run/redis_6379.pidloglevelnoticelogfile/var/log/redis/redis.logstop-writes-on-bgsave-erroryesrdbcompressionyesrdbchecksumyesdbfilenamedump.rdbdir/var/lib/redisslave-serve-stale-datayesslave-read-onlyyesrepl-diskless-syncnorepl-diskless-sync-delay5repl-disable-tcp-nodelaynoslave-priority100requirepass123456appendonlyyesappendfilename"appendonly.aof"appendfsynceverysec#从redisbind172.22.29.88protected-modeyesport6379filepidfile/var/run_varlog.re/log/redis/redis.logstop-writes-on-bgsave-erroryesrdbcompressionyesrdbchecksumyesdbfilenamedump.rdbdir/var/lib/redisslaveof172.22.29.876379masterauth123456slave-serve-stale-datayesslave-只读yesrepl-diskless-syncnorepl-diskless-sync-delay5repl-disable-tcp-nodelaynoslave-priority100requirepass123456appendonlyyesappendfilename"appendonly.aof"appendfsynceverysec#启动redissystemctstartredis#登录redis,查看主要从信息redis-7.2cli-h21.29.87172.22.29.87:6379>auth123456OK#主库信息172.22.29.87:6379>info……#Statstotal_connections_received:2total_commands_processed:15instantaneous_ops_per_sec:1total_net_input_bytes:478total_net_output_bytes:184instantaneous_input_kbps:0.04instantaneous_output_kbps:0.01rejected_connections:0sync_full:1sync_partial_ok:0sync_partial_err:0expired_keys:0evicted_keys:0keyspace_hits:0keyspace_misses:0pubsub_channels:0pubsub_patterns:0latest_fork_usec:757migrate_cached_sockets:0#Replicationrole:masterconnected_slaves:1slave0:ip=172.22.29.88,port=6379,state=online,offset=15,lag=0master_repl_offset:15repl_backlog_active:1repl_backlog_size:1048576repl_backlog_first_byte_offset:2repl_backlog_histlen:1#从库#Statstotal_connections_received:1total_commands_processed:33instantaneous_ops_per_sec:0total_net_input_bytes:609total_net_output_bytes:11766instantaneous_input_kbps:0.01instantaneous_output_kbps:0.06rejected_connections:0sync_full:0sync_partial_ok:0sync_partial_err:0expired_keys:0evicted_keys:0keyspace_hits:0keyspace_misses:0pubsub_channels:0pubsub_patterns:0latest_fork_usec:719migrate_cached_sockets:0#Replicationrole:slavemaster_host:172.22.29.87master_port:6379master_link_status:upmaster_last_io_seconds_ago:6master_sync_in_progress:0slave_repl_offset:449slave_priority:100slave_read_only:1connected_slaves:0master_repl_offset:0repl_backlog_active:0repl_backlog_size:1048576repl_backlog_first_byte_offset:0repl_backlog_histlen:0接着在主库和从库进行set、get测试#从库执行set172.22.29.88:6379>setnameredis(error)READONLYYoucan'twriteagainstareadonlyslave.'#因为从库是只读的,set无法完成#主库执行set,get172.22.29.87:6379>setnameredisOK172。22.29.87:6379>getname"redis"#执行从库中获取172.22.29.88:6379>getname"redis"主从设置完成,测试主库挂了#停止主库systemctlstopredis#主库查询172.22.29.87:6379>getnameCouldnotconnecttoRedisat172.22.29.87:6379:Connectionrefused#Queryfromthelibrary172.22.29.88:6379>getname"redis"#Viewthelogfromthelibrary1758:S03Feb12:17:59.848*ConnectingtoMASTER172.22.29.87:63791758:S03Feb12:17:59.848*MASTER<->SLAVEsyncstarted1758:S03Feb12:17:59.849#同步套接字的错误条件:连接被拒绝#然后启动主库systemctlstartredis#检查从库日志1758:S03Feb12:18:49.918*MASTER<->SLAVEsyncstarted1758:S03Feb12:18:49.918*SYNC的非阻塞连接触发了事件。1758:S03Feb12:18:49.918*Master回复PING,复制可以继续..1758:S03Feb12:18:49.919*尝试部分重新同步(请求4cd802976b4c445f06389c15bb7720effab38107:773).1758:S03Feb12:18:49.920*从主机完全重新同步:438afef01ffe3e55a681d89dfd699c1a6eb25e5b:11758:S03Feb12:18:49.920*丢弃previ已缓存主状态。1758:S03Feb12:18:49.928*MASTER<->SLAVEsync:从master1758:S03Feb12:18:49.928*MASTER<->SLAVEsync:Flushingolddata1758:S接收94字节03Feb12:18:49.928*MASTER<->SLAVEsync:LoadingDBinmemory1758:S03Feb12:18:49.928*MASTER<->SLAVEsync:Finishedwithsuccess1758:S03Feb12:18:49.930*Background仅附加文件重写由pid115231758:S03Feb12:18:49.952*AOF重写子请求停止发送差异。11523:C03Feb12:18:49.952*父同意停止发送差异。完成AOF...11523:C03Feb12:18:49.953*连接从parent.11523:C03Feb12:18:49.953收到的0.00MBAOFdiff*SYNCappendonlyfilerewriteperformed11523:C03Feb12:18:49.953*AOF重写:写时复制使用4MB内存1758:S03Feb12:18:50.019*后台AOF重写成功终止1758:S03Feb12:18:50.019*剩余父差异成功y刷新到重写的AOF(0.00MB)1758:S03Feb12:18:50.019*后台AOF重写成功完成#查看主库日志1869:M03Feb12:18:49.526*从仅附加文件加载的数据库:0.000seconds1869:M03Feb12:18:49.526*服务器现在准备好接受端口63791869:M03Feb12:18:49.919*Slave172.22.29.88:6379请求同步1869:M03Feb12:18:49.919*Partialresynchronizationnotaccepted:Runidmismatch(Clientaskedforrunid'4cd802976b4c445f06389c15bb7720effab38107',myrunidis'438afef01ffe3e55a681d89dfd699c1a6eb25e5b')1869:M03Feb12:18:49.919*StartingBGSAVEforSYNCwithtarget:disk1869:M03Feb12:18:49.920*后台保存由pid18721872:C03Feb12:18:49.922*DB保存在磁盘上1872:C2月3日12:18:49.922*RDB:copy-on-write1869:M2MB使用的内存12:18:49.928*后台保存成功终止1869:M03Feb12:18:49.928*与slave同步172.22.29.88:6379成功主从搭建及测试完成CentOS7安装最新版Redis需要安装remi软件源#安装remi源yuminstall-yhttp://rpms.famillecollet.com/enterprise/remi-release-7.rpm#使用remi源安装redisyum--enablerepo=remiinstallredis-y#安装完成后redis6.2.6版本的主从配置与redis6.x版本和3.x版本的区别主要是改变了slaveof命令到replicaofbind127.0.0.1-::1172.22.29.89protected-modeyesport6379tcp-backlog511timeout0tcp-keepalive300daemonizeyespidfile/var/run/redis_6379.pidloglevelnoticelogfile/var/log/redis/redis.logdatabases16always-show-logonoset-proc-titleitesyes-template"{title}{listen-addr}{server-mode}"stop-writes-on-bgsave-erroryesrdbcompressionyesrdbchecksumyesdbfilenamedump.rdbrdb-del-sync-filesnodir/var/lib/redisreplicaof172.22.29.906379masterauth123456replica-serve-stale-data是副本只读yesrepl-diskless-syncnorepl-diskless-sync-delay5repl-diskless-loaddisabledrepl-disable-tcp-nodelaynoreplica-priority100acllog-max-len128lazyfree-lazy-evictionnolazyfree-lazy-expirenolazyfree-lazy-server-delnoreplica-lazy-flushnolazyfree-lazy-user-delnolazyfree-lazy-user-flushnooom-score-adjnooom-score-adj-values0200800disable-thpyesappendonlyyesappendfilename"appendonly.aof》appendfsynceverysecmaster-slave可以优化一些点slave也可以作为其他slave的master,可以有效的分担master的同步压力。master可以将数据保存操作交给slave来完成,从而避免master需要独立进程完成数据保存操作的压力repl-disable-tcp-nodelay响应网络延迟,默认关闭。禁用时,无论主节点产生多大的命令数据,都会及时发送给从节点,减少网络延迟,但同时会增加网络开销。启用后,主节点将合并较小的TCP数据包以节省网络开销。发送到从节点的时间间隔取决于Linux内核配置。一般默认为40ms。开启后,节省了网络开销,但增加了主从数据延迟缓冲区大小调整。repl-backlog-size用于设置缓冲区大小。缓冲区大小影响写入命令的数量。当主从节点偏移量超过缓冲区长度时,无法进行部分复制,只能进行全量复制。因此,为了减少全量复制,可以增加buffersize总结Redismaster-slave可以看到搭建起来非常简单,但是在生产环境中很少用到,不推荐使用Redis主从模式在生产环境中提供服务。从前面的缺点部分可以看出,当数据量达到一定程度后,主从模式的不稳定性会大大增加,但是主从原理是其他集群模式的基础,所以原理需要了解一下,后面会介绍另外两种集群模式
