mysql零距离接触-MySQL主从复制和读写分离

MySQL主从复制(Master-Slave)与读写分离(MySQL-Proxy)实践前端

Mysql做为目前世界上使用最普遍的免费数据库,相信全部从事系统运维的工程师都必定接触过。但在实际的生产环境中,由单台Mysql做为独立的数据库是彻底不能知足实际需求的,不管是在安全性,高可用性以及高并发等各个方面。mysql

所以,通常来讲都是经过 主从复制(Master-Slave)的方式来同步数据,再经过读写分离(MySQL-Proxy)来提高数据库的并发负载能力 这样的方案来进行部署与实施的。算法

以下图所示:
sql

1,MySQL主从复制入门

首先,咱们看一个图:数据库

影响MySQL-A数据库的操做,在数据库执行后,都会写入本地的日志系统A中。缓存

假设,实时的将变化了的日志系统中的数据库事件操做,在MYSQL-A的3306端口,经过网络发给MYSQL-B。安全

MYSQL-B收到后,写入本地日志系统B,而后一条条的将数据库事件在数据库中完成。服务器

那么,MYSQL-A的变化,MYSQL-B也会变化,这样就是所谓的MYSQL的复制,即MYSQL replication。网络

在上面的模型中,MYSQL-A就是主服务器,即master,MYSQL-B就是从服务器,即slave。架构

日志系统A,其实它是MYSQL的日志类型中的二进制日志,也就是专门用来保存修改数据库表的全部动做,即bin log。【注意MYSQL会在执行语句以后,释放锁以前,写入二进制日志,确保事务安全】

日志系统B,并非二进制日志,因为它是从MYSQL-A的二进制日志复制过来的,并非本身的数据库变化产生的,有点接力的感受,称为中继日志,即relay log。

能够发现,经过上面的机制,能够保证MYSQL-A和MYSQL-B的数据库数据一致,可是时间上确定有延迟,即MYSQL-B的数据是滞后的。

【即使不考虑什么网络的因素,MYSQL-A的数据库操做是能够并发的执行的,可是MYSQL-B只能从relay log中读一条,执行下。所以MYSQL-A的写操做很频繁,MYSQL-B极可能跟不上。】

2,主从复制的几种方式

同步复制

所谓的同步复制,意思是master的变化,必须等待slave-1,slave-2,...,slave-n完成后才能返回。

这样,显然不可取,也不是MYSQL复制的默认设置。好比,在WEB前端页面上,用户增长了条记录,须要等待很长时间。

异步复制

如同AJAX请求同样。master只须要完成本身的数据库操做便可。至于slaves是否收到二进制日志,是否完成操做,不用关心。MYSQL的默认设置。

半同步复制

master只保证slaves中的一个操做成功,就返回,其余slave无论。

这个功能,是由google为MYSQL引入的。

3,主从复制分析

问题1:master的写操做,slaves被动的进行同样的操做,保持数据一致性,那么slave是否能够主动的进行写操做?

假设slave能够主动的进行写操做,slave又没法通知master,这样就致使了master和slave数据不一致了。所以slave不该该进行写操做,至少是slave上涉及到复制的数据库不能够写。实际上,这里已经揭示了读写分离的概念。

问题2:主从复制中,能够有N个slave,但是这些slave又不能进行写操做,要他们干吗?能够实现数据备份。

相似于高可用的功能,一旦master挂了,可让slave顶上去,同时slave提高为master。异地容灾,好比master在北京,地震挂了,那么在上海的slave还能够继续。主要用于实现scale out,分担负载,能够将读的任务分散到slaves上。

【极可能的状况是,一个系统的读操做远远多于写操做,所以写操做发向master,读操做发向slaves进行操做】

问题3:主从复制中有master,slave1,slave2,...等等这么多MYSQL数据库,那好比一个JAVA WEB应用到底应该链接哪一个数据库?

当 然,咱们在应用程序中能够这样,insert/delete/update这些更新数据库的操做,用connection(for master)进行操做,select用connection(for slaves)进行操做。那咱们的应用程序还要完成怎么从slaves选择一个来执行select,例如简单的轮循算法。

这样的话,至关于应用程序完成了SQL语句的路由,并且与MYSQL的主从复制架构很是关联,一旦master挂了,某些slave挂了,那么应用程序就要修改了。能不能让应用程序与MYSQL的主从复制架构没有什么太多关系呢?能够看下面的图:

找一个组件,application program只须要与它打交道,用它来完成MYSQL的代理,实现SQL语句的路由。

mysql proxy并不负责,怎么从众多的slaves挑一个?能够交给另外一个组件(好比haproxy)来完成。

这就是所谓的MYSQL READ WRITE SPLITE,MYSQL的读写分离。

问题4:若是mysql proxy , direct , master他们中的某些挂了怎么办?

总统通常都会弄个副总统,以防不测。一样的,能够给这些关键的节点来个备份。

问题5:当master的二进制日志每产生一个事件,都须要发往slave,若是咱们有N个slave,那是发N次,仍是只发一次?

若是只发一次,发给了slave-1,那slave-2,slave-3,...它们怎么办?

显 然,应该发N次。实际上,在MYSQL master内部,维护N个线程,每个线程负责将二进制日志文件发往对应的slave。master既要负责写操做,还的维护N个线程,负担会很重。可 以这样,slave-1是master的从,slave-1又是slave-2,slave-3,...的主,同时slave-1再也不负责select。 slave-1将master的复制线程的负担,转移到本身的身上。这就是所谓的多级复制的概念。

问题6:当一个select发往mysql proxy,可能此次由slave-2响应,下次由slave-3响应,这样的话,就没法利用查询缓存了。

应该找一个共享式的缓存,好比memcache来解决。将slave-2,slave-3,...这些查询的结果都缓存至mamcache中。

问题7:随着应用的日益增加,读操做不少,咱们能够扩展slave,可是若是master知足不了写操做了,怎么办呢?

scale on ?更好的服务器? 没有最好的,只有更好的,太贵了。。。

scale out ? 主从复制架构已经知足不了。

能够分库【垂直拆分】,分表【水平拆分】。