现在的位置: 首页 > 综合 > 正文

mysql replication 主从复制实现性能扩展

2013年05月22日 ⁄ 综合 ⁄ 共 3746字 ⁄ 字号 评论关闭

mysql replication能异步的将一个mysql server的instance中的数据完整的复制到另一个mysql server的instance中,虽然是异步的,但延迟非常少,利用这样优越的性能就能保证系统数据的安全性和系统可扩展的可靠性。

replication优点

replication功能的优点很明显,将一台数据库上的数据复制到多台数据库中,组成一个mysql集群,对外服务的mysql从一台变成多台,减少了一台数据库上的负载压力,提高了整体的处理性能,而由于数据复制的延迟很低,数据可靠性也能得到保证,进而还可以实现读写分离。

replication的实现原理

replication实现异步的将一台mysql(master)的数据复制到另一个mysql(slave)中,这整个过程是由三个线程来完成的,slave端有sql和IO两个线程,剩下了一个IO线程在master端。

要实现replication功能必须在master端打开binary log,因为整个复制过程就是slave从master端获取该日志然后顺序执行该日志中的操作而实现数据的复制。要在master端打开binary log功能可以通过在启动mysql时使用“—log-bin”参数,或者在my.cnf配置文件中的mysqld参数组增加“log-bin”参数项,我选用了后者,如下图所示:

当有mysql有数据更新时便会在/data/mysql/data/mysqld-bin里产生名字格式为mysql-bin.xxxxxx的binary log文件,如下图:

整个复制过程大概如下:

  • slave端的io线程连接上master,并请求相应的binary log日志内容;
  • master接收到slave的日志请求后,负责复制的io线程根据请求去读取相应的日志文件内容,并将数据返回给slave的io线程。返回的数据除了包含日志内容外,还返回本次读取的binary log日志文件名称和内容在文件中的位置,以便下次接着从上次读取的位置接着往下读取;
  • slave的io线程接收到数据以后,将接收到的数据追加到slave端的relay log文件(mysql-relay-bin.xxxx)中,并将数据中的有关master端的bin-log文件名和位置记录到master-info文件中;
  • slave的sql线程检测到relay log中增加了新内容后,会马上解析log中的内容成相应的query,并执行。达到的效果就是保证slave和master的数据一致。

slave端的两个io和sql线程保证了从master端获取数据和生成query并执行两个过程是异步并发执行的,这样就可以降低slave端同步数据的延迟时间,减少数据丢失的可能性,提高系统性能。

 replication实现级别

mysql的复制可以是基于query语句级别(statement level),也可以是数据行记录级别(row level),还有就是两者的混合方式(mixed),可以通过mysql.cnf的binlog_format参数设置,三者的设置值分别为statement,row,mixed,设置不同的值binary log中的日志格式也会不同。下面介绍这三种格式的不同:

1. row level:binary log中记录的是每一行的数据,slave会根据数据的异同对数据库进行修改。它的优点是直接复制数据,简单安全可靠;复制的数据带有主键的话,复制会快很多;执行insert,update,delete语句时锁更少。它的缺点有:bin-log日志会大很多,因为一条update语句可能更改的数据会有成千上万条,这样会在bin-log中追加成千上万条记录;因为有大量的数据写入,操作时间长,可能会产生并发写问题。

2. statement level:binary log记录的是每一条更改数据的query,slave同步数据时直接执行获取的query。它的优点有:bin-log会小很多,写入的数量少了,io成本降低了,性能提高了;bin-log可以用于数据还原;主从mysql版本可以不一样。它的缺点有:不是所有的update操作都可以被复制,尤其是含有不确定操作的时候;当where语句中没有索引的时候,更新操作会全表扫描,从而有更多得行级锁。总得来说因为是执行query,所以影响范围比row
level大很多。

3. mixed level:从5.1.8版本开始,mysql支持mixed模式,也就是前面两种模式的结合。在这种模式下mysql会自动对数据更改选择更适合的日志记录格式。

replication 架构

1. 常见的master-slaves架构,就是一台master复制数据到一台或多台slave,大概90%的主从复制会使用这种架构,将master上的读压力分散到多台slave上,因为在很多系统中读压力往往会大于写压力;

2. 双master架构。为了当master进行维护的时候系统能正常工作,需要将slave切换成master来进行正常的服务,这可能造成的问题是当原master重新启动后数据和实际的不一致了,这种情况下就得重新搭建replication环境让master和slave互换身份,但这会给我带来很多额外的工作。可以搭建一个双master环境,在这个双master环境里,两个mysql server互相将对方视为自己的master,自己作为slave。这样无论哪一方数据发生了更改都能同步到另一方,如果其中一个master停机维护,重启后也不会有任何的数据问题。当然如果双master都提供写服务的话也会有一定的数据冲突问题,这就得靠一些业务手段来保证或者只将其中一台机器作为备份机;

3. 除了上述常见的架构外,还有级联复制架构,即master-slave-slave,一个master连接几个slave,这几个slave再连接几个slave。还有双master级联架构,即master-master-slave-slave,这两种架构不常使用就不再详细介绍了,大概了原理都类似。

 replication实现

实现步骤如下:

1. master开启binary log。开启binary log的方式前面已经介绍过了,在启动mysql时使用—log-bin参数或者在my.cnf中配置log-bin,并设置server-id后重启mysql;

log-bin        = /data/mysql/data/mysqld-bin
server-id = 1

2. master创建一个专门用来复制的用户;

 grant replication slave on *.* to 'slave1'@'192.168.1.99' identified by 'slave1';

3.得到master当前binary log日志名和偏移量,这个操作的目的是为了在从数据库启动后,从这个点开始进行数据的恢复;

4. 将master数据备份到slave,可以用mysqldump或者直接copy数据文件,不过在做备份之前要将master锁表,防止备份期间数据发生的更改,造成数据的不一致;

5.
接着修改slave的
my.cnf增加server-id参数指定复制使用的用户master服务器的ip,端口以及开始执行复制日志的文件和位置;

[mysqld]
server-id=2
log_bin = /var/log/mysql/mysql-bin.log
master-host =192.168.1.100
master-port = 3306
master-user = slave1
master-password = slave1
master-log-file = 'mysql-bin.000029'
master-log-pos = '29683082'
master-connect-retry=60
replicate-do-db =test 

6. 在slave上启动slave进程:start slave;

7. 在slave上进行show slave status

mysql> SHOW SLAVE STATUS\G

*************************** 1. row ***************************
Slave_IO_State: Waiting for master to send event
Master_Host: 192.168.1.100
Master_User: slave1
Master_Port: 3306
Connect_Retry: 3
Master_Log_File: mysql-bin.000029
Read_Master_Log_Pos: 29683082
Relay_Log_File: gbichot-relay-bin.003
Relay_Log_Pos: 548
Relay_Master_Log_File: mysql-bin .003
Slave_IO_Running: Yes
Slave_SQL_Running: Yes

完成上述7个步骤,一个简单的replication环境已经搭建完毕。合理的利用replication功能,能用很低的成本换来很高的性能提升。

抱歉!评论已关闭.