一、 Replication
Replication的思想是将数据在集群的多个节点同步、备份,以提高集群数据的可用性(HA);Mysql使用Replication架构来实现上述目的,同时可以提升了集群整体的并发能力。。
Replication具有如下优点:
1)扩展:将负载分布在多个slaves上以提高性能,所有的writes以及事务中的read操作都将有master处理,其他reads将转发给slaves;对于“读写比”较高的应用,replication可以通过增加slaves节点来提高并发能力;因为write只能在master上提交,因此架构扩展对提升write并发能力并不明显,对于writes密集性应用我们应该考虑其他架构。
2)数据安全:slave可以中断自己的replication进程,这不会打断master上的数据请求,所以可以在slave上运行backup服务,定期全量backup是保护数据的手段之一。(如果在master上执行backup,需要让master处于readonly状态,这也意味这所有的write请求需要阻塞)。
3)分析:数据在master上创建,那么数据分析可以在slave上进行,这将不会影响master的性能。利用mysql做数据分析(或者数据分析平台的源数据),通常都是将某个slave作为数据输入端。
4)远距数据分布:如果master的物理位置较远,你可以在临近需求的地方部署slaves,以便就近使用数据,而不需要总是访问远端的master,这在数据分析、数据备份与容灾等方面有很大帮助。
二、Sharding和Replication
1.replication机制的优缺点
优点:
负载高时可以通过replication机制来提高读写的吞吐和性能。
缺点:
首先它的有效很依赖于读操作的比例,Master往往会成为瓶颈所在,写操作需要顺序排队来执行,过载的话Master首先扛不住,Slaves的数据同步的延迟也可能比较大,而且会大大耗费CPU的计算能力,因为write操作在Master上执行以后还是需要在每台slave机器上都跑一次。
2.sharding技术的优缺点
sharding技术可以弥补replication机制的缺点。因为sharding可以很好的扩展,我们知道每台机器无论配置多么好它都有自身的物理上限,所以当我们应用已经能触及或远远超出单台机器的某个上限的时候,我们惟有寻找别的机器的帮助或者继续升级的我们的硬件,但常见的方案还是横向扩展, 通过添加更多的机器来共同承担压力。我们还得考虑当我们的业务逻辑不断增长,我们的机器能不能通过线性增长就能满足需求?Sharding可以轻松的将计算,存储,I/O并行分发到多台机器上,这样可以充分利用多台机器各种处理能力,同时可以避免单点失败,提供系统的可用性,进行很好的错误隔离。
三、Mysql主从复制的原理
1. 主从复制过程
主从复制通过三个过程实现,其中一个过程发生在主服务器上,另外两个过程发生在从服务器上。具体情况如下:
主服务器将用户对数据库的写操作以二进制格式保存到Binary Log(二进制日志)文件中, 然后由Binlog Dump 线程将二进制日志文件传输给从服务器。
从服务器通过一个 I/O 线程将主服务器的二进制日志文件中的写操作复制到一个叫 Relay Log 的中继日志文件中。
从服务器通过另一个 SQL 线程将 Relay Log 中继日志文件中的写操作依次在本地执行,从而实现主从服务器之间的数据的同步。
(1)BinLog Dump线程
该线程运行在主服务器上,主要工作是把 Binary Log 二进制日志文件的数据发送给从服务器。
使用 SHOW PROCESSLIST语句,可查看该线程是否正在运行。
(2)I/O线程
从服务器执行 START SLAVE 语句后,会创建一个 I/O 线程。此线程运行在从服务器上,与主服务器建立连接,然后向主服务器发出同步请求。之后,I/O 线程将主服务器发送的写操作复制到本地 Relay Log 日志文件中。
使用 SHOW SLAVE STATUS语句,可查看 I/O 线程状态。
(3)SQL线程
该线程运行在从服务器上,主要工作是读取 Relay Log 日志文件中的更新操作,并将这些操作依次执行,从而使主从服务器的数据保持同步。
2. 复制级别
1. 基于语句的复制: 在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高。 一旦发现没法精确复制时,会自动选着基于行的复制。
2. 基于行的复制:把改变的内容复制过去,而不是把命令在从服务器上执行一遍. 从mysql5.0开始支持
3. 混合类型的复制: 默认采用基于语句的复制,一旦发现基于语句的无法精确的复制时,就会采用基于行的复制。
四、Replication的三种常用架构
1. Master - Slaves ( 常规复制架构)
在实际应用场景中,MySQL复制90%以上都是一个Master复制到一个或者多个Slave的架构模式,主要用于读压力比较大的应用的数据库端廉价扩展解决方案。因为只要Master和Slave的压力不是太大(尤其是Slave端压力)的话,异步复制的延时一般都很少很少。尤其是自从Slave端的复制方式改成两个线程处理之后,更是减小了Slave端的延时问题。而带来的效益是,对于数据实时性要求不是特别严格的应用,只需要通过廉价的pcserver来扩展Slave的数量,将读压力分散到多台Slave的机器上面,即可通过分散单台数据库服务器的读压力来解决数据库端的读性能瓶颈,毕竟在大多数数据库应用系统中的读压力还是要比写压力大很多。这在很大程度上解决了目前很多中小型网站的数据库压力瓶颈问题,甚至有些大型网站也在使用类似方案解决数据库瓶颈。
2. Master - Master (dualMaster复制架构)
有些时候,简单的从一个MySQL复制到另外一个MySQL的基本Replication架构,可能还会需要在一些特定的场景下进行Master的切换。如在Master端需要进行一些特别的维护操作的时候,可能需要停MySQL的服务。这时候,为了尽可能减少应用系统写服务的停机时间,最佳的做法就是将我们的Slave节点切换成Master来提供写入的服务。
但是这样一来,我们原来Master节点的数据就会和实际的数据不一致了。为了解决这个问题,我们可以通过搭建DualMaster环境来避免很多的问题。何谓DualMaster环境?实际上就是两个MySQLServer互相将对方作为自己的Master,自己作为对方的Slave来进行复制。这样,任何一方所做的变更,都会通过复制应用到另外一方的数据库中。
可能有些读者朋友会有一个担心,这样搭建复制环境之后,难道不会造成两台MySQL之间的循环复制么?实际上MySQL自己早就想到了这一点,所以在MySQL的BinaryLog中记录了当前MySQL的server-id,而且这个参数也是我们搭建MySQLReplication的时候必须明确指定,而且Master和Slave的server-id参数值比需要不一致才能使MySQLReplication搭建成功。一旦有了server-id的值之后,MySQL就很容易判断某个变更是从哪一个MySQLServer最初产生的,所以就很容易避免出现循环复制的情况。而且,如果我们不打开记录Slave的BinaryLog的选项(--log-slave-update)的时候,MySQL根本就不会记录复制过程中的变更到BinaryLog中,就更不用担心可能会出现循环复制的情形了。下如将更清晰的展示DualMaster复制架构组成:
通过DualMaster复制架构,我们不仅能够避免因为正常的常规维护操作需要的停机所带来的重新搭建Replication环境的操作,因为我们任何一端都记录了自己当前复制到对方的什么位置了,当系统起来之后,就会自动开始从之前的位置重新开始复制,而不需要人为去进行任何干预,大大节省了维护成本。
不仅仅如此,DualMaster复制架构和一些第三方的HA管理软件结合,还可以在我们当前正在使用的Master出现异常无法提供服务之后,非常迅速的自动切换另外一端来提供相应的服务,减少异常情况下带来的停机时间,并且完全不需要人工干预。
当然,我们搭建成一个DualMaster环境,并不是为了让两端都提供写的服务。在正常情况下,我们都只会将其中一端开启写服务,另外一端仅仅只是提供读服务,或者完全不提供任何服务,仅仅只是作为一个备用的机器存在。为什么我们一般都只开启其中的一端来提供写服务呢?主要还是为了避免数据的冲突,防止造成数据的不一致性。因为即使在两边执行的修改有先后顺序,但由于Replication是异步的实现机制(CAP),同样会导致即使晚做的修改也可能会被早做的修改所覆盖。
3. Master –Slaves - Slaves (级联复制架构)
在有些应用场景中,可能读写压力差别比较大,读压力特别的大,一个Master可能需要上10台甚至更多的Slave才能够支撑注读的压力。这时候,Master就会比较吃力了,因为仅仅连上来的SlaveIO线程就比较多了,这样写的压力稍微大一点的时候,Master端因为复制就会消耗较多的资源,很容易造成复制的延时。
遇到这种情况如何解决呢?这时候我们就可以利用MySQL可以在Slave端记录复制所产生变更的BinaryLog信息的功能,也就是打开—log-slave-update选项。然后,通过二级(或者是更多级别)复制来减少Master端因为复制所带来的压力。也就是说,我们首先通过少数几台MySQL从Master来进行复制,这几台机器我们姑且称之为第一级Slave集群,然后其他的Slave再从第一级Slave集群来进行复制。从第一级Slave进行复制的Slave,我称之为第二级Slave集群。如果有需要,我们可以继续往下增加更多层次的复制。这样,我们很容易就控制了每一台MySQL上面所附属Slave的数量。这种架构我称之为Master-Slaves-Slaves架构
这种多层级联复制的架构,很容易就解决了Master端因为附属Slave太多而成为瓶颈的风险。下图展示了多层级联复制的Replication架构。
五、读写分离
读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。
读写分离的好处:
1. 增加冗余
2. 增加了机器的处理能力
3. 对于读操作为主的应用,使用读写分离是最好的场景,因为可以确保写的服务器压力更小,而读又可以接受点时间上的延迟。
读写分离在实现上一般采用复制的方式,读在Slave端,写和事务在Master端,按照其实现可分为如下两种大类:
1. 程序修改mysql操作类
在数据库操作时直接指定读写库的位置,这种方式优点:直接和数据库通信,简单快捷的读写分离和随机的方式实现的负载均衡,权限独立分配
缺点:数据段和程序的耦合度太高,自己维护更新,增减服务器在代码处理。
2. 数据库代理
使用mysql官方(mysql proxy)或者第三方数据库代理(如mycat)将数据库连接抽象和屏蔽,优点:直接实现读写分离和负载均衡,不用修改代码,缺点:增加额外耗时和性能损耗。
六、Replication的常用方案
1、master-master架构
两台服务器装mysql,各自作为对方的从机接受对方发来的数据,做到数据的同步备份,感觉和master-slave基本实现原理是一样的。这样保证了数据的一致性,如何保证其中一台服务器故障,自动切换到另外的一个master上呢,使用MMM(MySQL Master-Master Replication Manager)来管理。
2、heartbeat+drbd+mysql主从复制
基本原理与1相似,这里需要做一个master库的冗余备份,使用drbd来保证不同服务器中两个master库的数据一致性。利用heartbeat来完成其中一台服务器发生故障后的自动切换。结构如下图:
3、Mysql + keepalived 实现双主热备读写分离
keepalived主要用于实现故障切换和热备,作为mysql的补充。