try redis (五) -- master -slave 主从复制
參考官网原文:http://redis.io/topics/replication
參考文章 :http://in.sdo.com/?p=1187
注意事项
Redis 的复制说白了就是通过配置 将slave 当做 masters 的复制。可是有有几个须要注意点:
1、Redis使用的是一部复制。
从Redis 2.8開始。slaves 将定期确认从复制流中处理的数量
2、一个master 能够有多个slavers
3、slaves能够接受其它slaves 的连接。
4、Redis的复制是不会堵塞master 的,也就是所谓的 non-blocking.这就意味着当一个或者多个slaves 在处理最初的同步时,master能够继续他的查询操作等。
5、为了有多个仅仅读slaves,能够用俩做一些伸缩性的复制。
6、复制操作有可能也能够避免Redis将全部的数据集写入disk的损失。
master持久化变与复制的安全性
当 Redis 复制使用的时候,它是强烈建议master的持久化是开启的,当没法开启持久化比方须要延迟。Redis 须要配置成 禁止自己主动重新启动
为了更好的 理解为什么master 在自己主动重新启动的 情况下。关闭持久化配置是危急的。
可能造成数据从master 和全部slaves 中擦除,我们看一个样例
1、我们启动nodeA 作为master。同一时候设置A 为持久化 turned down 。
node B、C 从A 中复制数据
2、假设A 突然挂了,然后能够重新启动,可是因为没有开启持久化。
重新启动后数据集为空
3、这个似乎 B 和 C将从 A 中复制空的数据集,这样原来的一些老的数据就被擦除了。
当 redis 系统为了提高可用率,会将master的持久化给关闭。
可是不论什么时候,数据安全都是最重要的,复制功能在没有配置持久化,同一时候又自己主动重新启动的机器中是不可取的。
Reids 复制时怎么工作的
当启动一个slave 。连接后他会发送一个SYNC命令。在它第一次连接或者又一次连接master的时候,这个都是正常的。
master 開始后台进行保存操作。同一时候開始開始缓存全部收到的改变数据集的命令。当后台保存成功,master将 保存在硬盘上的 数据集文件(dump.rdb) 读入到内存中 ,发送给slave。
然后master将发送全部缓存命令,这好比是一个命令流,是redis协议本身实现的
Slaves 能够自己主动冲洗连接。
当 master <-> salve 连接由于某些原因中断的时候。
当master收到多个并发 slave 同步请求的时候。会有一个单独的线程专门来保存他们。
同一时候在网上找打一个 比較好的一个状态流程的解释
- Slave端在配置文件里加入了slave of指令,于是Slave启动时读取配置文件。初始状态为REDIS_REPL_CONNECT。
- Slave端在定时任务serverCron(Redis内部的定时器触发事件)中连接Master,发送sync命令,然后堵塞等待master发送回其内存快照文件(最新版的Redis已经不须要让Slave堵塞)。
- Master端收到sync命令简单推断是否有正在进行的内存快照子进程,没有则马上開始内存快照,有则等待其结束。当快照完毕后会将该文件发送给Slave端。
- Slave端接收Master发来的内存快照文件,保存到本地,待接收完毕后,清空内存表。又一次读取Master发来的内存快照文件,重建整个内存表数据结构。并终于状态置位为 REDIS_REPL_CONNECTED状态,Slave状态机流转完毕。
- Master端在发送快照文件过程中,接收的不论什么会改变数据集的命令都会临时先保存在Slave网络连接的发送缓存队列里(list数据结构)。待快照完毕后,依次发给Slave,之后收到的命令同样处理。并将状态置位为 REDIS_REPL_ONLINE。
redis.conf 关于 配置
port 6379
指定Redis监听port,默认port为6379
################################# REPLICATION ###################################
maseter-slave 复制 须要注意几个点
1、redis 复制时一部实现的。可是你能够配置 master 在不能连接到一个给定数量的slaves 的时候,禁止写入
2、redis slaves 能够局部的再同步数据到master 假设master突然断掉。然后启动。
3、复制时自己主动进行的。不须要用户调用。假设slavers 与master 无法连接。slaves 会尝试连接master.同一时候再同步slaves上的数据到master上
######################################################################################
slaveof <masterId> <masterPort>
假设配置了slaveof 属性。意味着当前节点是 slave。同一时候确定了master的ip 和 port
slave