紧接上篇博文《MariaDB/Mysql之主从架构的复制原理及主从/双主配置详解(一)》mysql
3.四、发送复制事件到其它slave
sql
当设置log_slave_updates时,你可让slave扮演其它slave的master。此时,slave把SQL线程执行的事件写进行本身的二进制日志(binary log),而后,它的slave能够获取这些事件并执行它。以下:数据库
复制过滤可让你只复***务器中的一部分数据,有两种复制过滤:在master上过滤二进制日志中的事件;在slave上过滤中继日志中的事件。以下:服务器
在早期的MySQL是不支持多主服务器复制(Multimaster Replication)——即一个slave能够有多个master的场景,可是MariaDB目前已经支持。可是,经过一些简单的组合,咱们却能够创建灵活而强大的复制体系结构。
网络
在实际应用场景中,MySQL复制90%以上都是一个Master复制到一个或者多个Slave的架构模式,主要用于读压力比较大的应用的数据库端廉价扩展解决方案。由于只要Master和Slave的压力不是太大(尤为是Slave端压力)的话,异步复制的延时通常都不多不多。尤为是自从Slave端的复制方式改为两个线程处理以后,更是减少了Slave端的延时问题。而带来的效益是,对于数据实时性要求不是特别Critical的应用,只须要经过廉价的pcserver来扩展Slave的数量,将读压力分散到多台Slave的机器上面,便可经过分散单台数据库服务器的读压力来解决数据库端的读性能瓶颈,毕竟在大多数数据库应用系统中的读压力仍是要比写压力大不少。这在很大程度上解决了目前不少中小型网站的数据库压力瓶颈问题,甚至有些大型网站也在使用相似方案解决数据库瓶颈。session
以下:架构
你们应该都比较清楚,从一个Master节点能够复制出多个Slave节点,可能有人会想,那一个Slave节点是否能够从多个Master节点上面进行复制呢?这是彻底能够实现的,目前在MariaDB中已经实现multi-master replication 功能;可参考《MariaDB多源(主)复制》异步
实际上,MySQL并不支持其它一些DBMS支持的多主服务器复制(Multimaster Replication),这是MySQL的复制功能很大的一个限制(多主服务器的难点在于解决更新冲突),可是,若是你实在有这种需求,你能够采用MySQL Cluster,以及将Cluster和Replication结合起来,能够创建强大的高性能的数据库平台。可是,能够经过其它一些方式来模拟这种多主服务器的复制。
ide
示例:双主模式配置:函数
环境:
Master1/Master2 | Platfrom | IP | APP Version |
Master1 | CentOS6.5_X86-64 | 172.16.41.1 | mariadb-10.0.10 |
Master2 | CentOS6.5_X86-64 | 172.16.41.2 | mariadb-10.0.10 |
1.配置双主:
server-id = 1 |
主配置文件/etc/my.cnf [mysqld]段中,修改以下行:
log-bin = /mydata/binlogs/master1-bin relay-log = /mydata/relaylogs/relay-bin 确保中继日志选项开启 MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'relay_log'; |
auto-increment-offset = 1 //起始值 auto-increment-increment = 2 //步长 确保自动增加选项已开启: MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'auto_inc%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 2 | | auto_increment_offset | 1 | +--------------------------+-------+ |
(4)建立有复制权限的用户,命令以下:
MariaDB [(none)]> CREATE USER 'luccy'@'172.16.41.2' IDENTIFIED BY 'qazwsx123'; MariaDB [(none)]> REVOKE ALL PRIVILEGES ,GRANT OPTION FROM 'luccy'@'172.16.41.2'; MariaDB [(none)]> GRANT RELOAD,LOCK TABLES, REPLICATION CLIENT ,REPLICATION SLAVE ON *.* TO 'luccy'@'172.16.41.2'; MariaDB [(none)]> FLUSH PRIVILEGES; |
(1)修改server-id#
server-id = 2 |
log-bin = /mydata/binlogs/master2-bin relay-log = /mydata/relaylogs/relay-bin 确保中继日志选项开启 MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'relay_log'; |
(3)添加下面两项,以免在MySQL自动为INSERT语句选择不互相冲突的值
auto-increment-offset = 2 //起始值 auto-increment-increment = 2 //步长 确保自动增加选项已开启: MariaDB [(none)]> SHOW GLOBAL VARIABLES LIKE 'auto_inc%'; +--------------------------+-------+ | Variable_name | Value | +--------------------------+-------+ | auto_increment_increment | 2 | | auto_increment_offset | 2 | +--------------------------+-------+ |
(4)建立有复制权限的用户,命令以下:
MariaDB [(none)]> CREATE USER 'jerry'@'172.16.41.1' IDENTIFIED BY 'qazwsx123'; MariaDB [(none)]> REVOKE ALL PRIVILEGES ,GRANT OPTION FROM 'jerry'@'172.16.41.1'; MariaDB [(none)]> GRANT RELOAD,LOCK TABLES, REPLICATION CLIENT ,REPLICATION SLAVE ON *.* TO 'jerry'@'172.16.41.1'; MariaDB [(none)]> FLUSH PRIVILEGES; |
若是此时两台服务器均为新创建,且无其它写入操做,各服务器只需记录当前本身二进制日志文件及事件位置,以之做为另外的服务器复制起始位置便可
#Master1: MariaDB [(none)]> SHOW MASTER STATUS; +--------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +--------------------+----------+--------------+------------------+ | master1-bin.000001 | 969 | | | +--------------------+----------+--------------+------------------+ #Master2: MariaDB [(none)]> SHOW MASTER STATUS; +--------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +--------------------+----------+--------------+------------------+ | master2-bin.000001 | 314 | | | +--------------------+----------+--------------+------------------+ |
各服务器接下来指定对另外一台服务器为本身的主服务器
#Master1指向Master2 MariaDB [(none)]> CHANGE MASTER TO MASTER_USER='luccy',MASTER_HOST='172.16.41.2',MASTER_PASSWORD='qazwsx123',MASTER_LOG_FILE='master2-bin.000005',MASTER_LOG_POS=328; #Master2指向Master1 MariaDB [(none)]> CHANGE MASTER TO MASTER_USER='jerry',MASTER_HOST='172.16.41.1',MASTER_PASSWORD='qazwsx123',MASTER_LOG_FILE='master1-bin.000005',MASTER_LOG_POS=1592; |
启动个服务器复制进程
#Master1 MariaDB [(none)]> START SLAVE; MariaDB [mysql]> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.41.2 Master_User: jerry Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master2-bin.000006 Read_Master_Log_Pos: 328 Relay_Log_File: relay-bin.000004 Relay_Log_Pos: 617 Relay_Master_Log_File: master2-bin.000006 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: .......... .......... #Master2 MariaDB [(none)]> START SLAVE; MariaDB [(none)]> SHOW SLAVE STATUS\G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 172.16.41.1 Master_User: luccy Master_Port: 3306 Connect_Retry: 60 Master_Log_File: master1-bin.000005 Read_Master_Log_Pos: 1592 Relay_Log_File: relay-bin.000002 Relay_Log_Pos: 537 Relay_Master_Log_File: master1-bin.000005 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: .......... |
双主测试:
(1)在Master1上建立数据库 testdb: MariaDB [(none)]> CREATE DATABASE testdb; MariaDB [(none)]> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | test | | testdb | +--------------------+ 在Master2上查看结果与在Master1上所查得结果同样! (2)在Master1上建立数据库 mydb: MariaDB [(none)]> SHOW DATABASES; +--------------------+ | Database | +--------------------+ | information_schema | | mydb | | mysql | | performance_schema | | test | | testdb | +--------------------+ 在Master1上查看结果与在Master2上所查得结果同样! (3)在Master1的mydb上面新建一张表mytable1,并插入语句 MariaDB [(none)]> use mydb MariaDB [mydb]> CREATE TABLE mytable1 (ID INT AUTO_INCREMENT UNIQUE KEY, Name CHAR(20)); MariaDB [mydb]> DESC mytable1; +-------+----------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +-------+----------+------+-----+---------+----------------+ | ID | int(11) | NO | PRI | NULL | auto_increment | | Name | char(20) | YES | | NULL | | +-------+----------+------+-----+---------+----------------+ MariaDB [mydb]> INSERT INTO mytable1(Name) VALUES ('larry'),('jim'),('jerry'); Query OK, 3 rows affected (0.01 sec) Records: 3 Duplicates: 0 Warnings: 0 MariaDB [mydb]> SELECT * FROM mytable1; +----+-------+ | ID | Name | +----+-------+ | 1 | larry| //自动增加的效果,在Master1上定义的起始值为1,步径为2 | 3| jim | | 5 | jerry| +----+-------+ 在Master2上面插入字段(以上内容已经同步到Master2) MariaDB [mydb]>INSERT INTO mytable1(Name) VALUES ('Zhang San'),('Li Si'),('Wang Wu'); MariaDB [mydb]> SELECT * FROM mytable1; +----+-----------+ | ID | Name | +----+-----------+ | 1 | larry | | 3 | jim | | 5 | jerry | | 6 | Zhang San | | 8 | Li Si | | 10 | Wang Wu | +----+-----------+ //看来不是想要的结果,虽说MySQL自动为INSERT选择的值不会再出现互相冲突的状况,可是貌似没有按数字排序,找不到解决这个问题的办法,除非不选择用双主模式! |
这是master-master结构变化而来的,它避免了M-M的缺点,实际上,这是一种具备容错和高可用性的系统。它的不一样点在于其中一个服务只能进行只读操做。如图:
在有些应用场景中,可能读写压力差异比较大,读压力特别的大,一个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架构。
固然,若是条件容许,我更倾向于建议你们经过拆分红多个Replication集群来解决
上述瓶颈问题。毕竟Slave并无减小写的量,全部Slave实际上仍然仍是应用了全部的数据变动操做,没有减小任何写IO。相反,Slave越多,整个集群的写IO总量也就会越多,咱们没有很是明显的感受,仅仅只是由于分散到了多台机器上面,因此不是很容易表现出来。
此外,增长复制的级联层次,同一个变动传到最底层的Slave所须要通过的MySQL也会更多,一样可能形成延时较长的风险。而若是咱们经过分拆集群的方式来解决的话,可能就会要好不少了,固然,分拆集群也须要更复杂的技术和更复杂的应用系统架构。
级联复制在必定程度上面确实解决了Master由于所附属的Slave过多而成为瓶颈的问题,可是他并不能解决人工维护和出现异常须要切换后可能存在从新搭建Replication的问题。这样就很天然的引伸出了DualMaster与级联复制结合的Replication架构,我称之为Master-Master-Slaves架构
和Master-Slaves-Slaves架构相比,区别仅仅只是将第一级Slave集群换成了一台单独的Master,做为备用Master,而后再从这个备用的Master进行复制到一个Slave集群。
这种DualMaster与级联复制结合的架构,最大的好处就是既能够避免主Master的写入操做不会受到Slave集群的复制所带来的影响,同时主Master须要切换的时候也基本上不会出现重搭Replication的状况。可是,这个架构也有一个弊端,那就是备用的Master有可能成为瓶颈,由于若是后面的Slave集群比较大的话,备用Master可能会由于过多的SlaveIO线程请求而成为瓶颈。固然,该备用Master不提供任何的读服务的时候,瓶颈出现的可能性并非特别高,若是出现瓶颈,也能够在备用Master后面再次进行级联复制,架设多层Slave集群。固然,级联复制的级别越多,Slave集群可能出现的数据延时也会更为明显,因此考虑使用多层级联复制以前,也须要评估数据延时对应用系统的影响。