什么是Redis主从复制
主从复制,当用户往Master端写入数据时,通过Redis Sync机制将数据文件发送至Slave,Slave也会执行相同的操作确保数据一致;且实现Redis的主从复制非常简单。
Redis主从复制原理
在Slave启动并连接到Master之后,它将主动发送一个SYNC命令。此后Master将启动后台存盘进程,同时收集所有接收到的用于修改数据集的命令,在后台进程执行完毕后,Master将传送整个数据库文件到Slave,以完成一次完全同步。而Slave服务器在接收到数据库文件数据之后将其存盘并加载到内存中。此后,Master继续将所有已经收集到的修改命令,和新的修改命令依次传送给Slaves,Slave将在本次执行这些数据修改命令,从而达到最终的数据同步。
如果Master和Slave之间的链接出现断连现象,Slave可以自动重连Master,但是在连接成功之后,一次完全同步将被自动执行。
如果Master同时收到多个 slave发来的同步连接命令,只会使用启动一个进程来写数据库镜像,然后发送给所有slave。
Redis主从复制特点
1、同一个Master可以拥有多个Slaves。
2、Master下的Slave还可以接受同一架构中其它slave的链接与同步请求,实现数据的级联复制,即Master->Slave->Slave模式;
3、Master以非阻塞的方式同步数据至slave,这将意味着Master会继续处理一个或多个slave的读写请求;
4、Slave端同步数据也可以修改为非阻塞是的方式,当slave在执行新的同步时,它仍可以用旧的数据信息来提供查询;否则,当slave与master失去联系时,slave会返回一个错误给客户端;
5、主从复制具有可扩展性,即多个slave专门提供只读查询与数据的冗余,Master端专门提供写操作;
6、通过配置禁用Master数据持久化机制,将其数据持久化操作交给Slaves完成,避免在Master中要有独立的进程来完成此操作。
Redis主从复制实现
1.在本地创建两个目录:RedisMaster、RedisSlave 。 分别存放Master服务和Slave服务。
2.修改Master服务的配置文件redis.conf(推荐使用文本编译器打开,例如:Notepad++)
3.修改Slave服务的配置文件redis.conf:
4.开启主从服务, 我们先开启Master服务
然后我们开启Slave服务:
当我们开启Slave服务时,Master服务的窗口会增加一些信息:
可以看到在Slave服务启动并连接到Master服务之后,它将主动发送一个SYNC命令,用来同步数据。Master先dump出rdb文件,然后将rdb文件全量传输给slave,然后Master把缓存的命令转发给Slave,初次同步完成。
第二次以及以后的同步实现是:Master将变量的快照直接实时依次发送给各个Slave。不管什么原因导致Slave和Master断开重连都会重复以上过程。Redis的主从复制是建立在内存快照的持久化基础上,只要有Slave就一定会有内存快照发生。虽然Redis宣称主从复制无阻塞,但由于Redis使用单线程服务,如果Master快照文件比较大,那么第一次全量传输会耗费比较长时间,且文件传输过程中Master可能无法提供服务,也就是说服务会中断。
5.下面我们来写个控制台程序来试试读写分离:
1 using ServiceStack.Redis; 2 using System; 3 using System.Collections.Generic; 4 using System.Linq; 5 using System.Text; 6 using System.Threading.Tasks; 7 8 namespace String 9 { 10 class Program 11 { 12 static void Main(string[] args) 13 { 14 RedisClient Masterclient = new RedisClient("127.0.0.1", 6379); 15 RedisClient Slaveclient = new RedisClient("127.0.0.1", 6379); 16 Console.WriteLine("Master写入数据"); 17 string data = Console.ReadLine(); 18 Masterclient.Set<string>("data", data); 19 string readmaster = Slaveclient.Get<string>("data"); 20 Console.WriteLine("Slave读取数据:"+readmaster); 21 Console.ReadKey(); 22 } 23 } 24 }
Redis主从复制存在的问题
在读《京东云实践:浅谈Redis主从复制》 时,看到一个问题:主从复制在遇到网络不稳定的情况下,Slave和Master断开(包括闪断)会导致Master需要将内存中的数据全部重新生成rdb文件(快照文件),然后传输给Slave。Slave接收完Master传递过来的rdb文件以后会将自身的内存清空,把rdb文件重新加载到内存中。这种方式效率比较低下,尤其是在数据量大的情况下,毕竟网络闪断未必丢数据或者说丢的数据只是少部分,但却要为此付出将整个内存数据都重新传输一次的代价。如果能够将闪断过程的更新数据传递给Slave,那么就不需要将Master内存中的所有数据都传递给Slave了。Redis作者在2.8中已经将这个部分复制的思路实现了。
Redis数据恢复
当Redis服务器挂掉以后,重启时将按以下优先级恢复数据到内存:
1.如果只配置了AOF,重启时加载AOF文件恢复数据。
2.如果同时配置了RBD和AOF,启动时只加载AOF文件恢复数据。
3.如果只配置了RDB,启动时将加载dump文件恢复数据。
参考文献
1.传智播客-Redis公开课,感谢传智播客
2.Stephen Liu的Redis学习手册(目录):http://www.cnblogs.com/stephen-liu74/archive/2012/04/16/2370212.html
3.构建高性能数据库缓存之redis主从复制:http://database.51cto.com/art/201407/444555.htm
4.京东云实践:浅谈Redis主从复制:http://www.searchcloudcomputing.com.cn/showcontent_76912.htm