Mysql实现企业级数据库主从复制架构实战

背景

公司规模已经造成,用户数据已成为公司的核心命脉,一次老王一不当心把数据库文件删除,经过mysqldump备份策略恢复用了两个小时,在这两小时中,公司业务中断,损失100万,老王作出深入检讨,公司也所以对于数据库的性能和可靠性提出更高要求。要求对数据库进行改造,使其承载力进行提高,故障修复时间减小,有没有能实现的方案呢? css

 

数据库常遇到的问题

1、性能问题

一、向上拓展 scale up :针对单台服务器,提升服务器的硬件性能,好比:内存,cpu等,个体自己 容易达到极限 前端

二、向外拓展 scale out :多台服务器造成集群,共同完成一件事情 mysql

2、可用性问题

一、数据库服务中断 linux

二、误操做数据损坏 sql

三、硬件故障 数据库

四、数据库升级测试遭遇bug vim

五、黑客攻击 centos

 

数据库高可用技术说明

高可用架构对于互联网服务基本是标配,不管是应用服务仍是数据库服务都须要作到高可用。虽然互联网服务号称7*24小时不间断服务,但多多少少有一些时候服务不可用,好比某些时候网页打不开,百度不能搜索或者没法发微博,发微信等。通常而言,衡量高可用作到什么程度能够经过一年内服务不可用时间做为参考,要作到3个9的可用性,一年内只能累计有8个小时不可服务,而若是要作到5个9的可用性,则一年内只能累计5分钟服务中断。因此虽然说每一个公司都说本身的服务是7*24不间断的,但实际上能作到5个9的屈指可数,甚至根本作不到,国内互联网巨头BAT(百度,阿里巴巴,腾讯)都有由于故障致使的停服问题。对于一个系统而言,可能包含不少模块,好比前端应用,缓存,数据库,搜索,消息队列等,每一个模块都须要作到高可用,才能保证整个系统的高可用。对于数据库服务而言,高可用可能更复杂,对用户的服务可用,不只仅是能访问,还须要有正确性保证,所以,对于实现数据库高可用,对互联网公司来讲极其重要! 缓存

企业级数据库高可用架构图

 

Mysql主从架构技术说明

Mysql内建的复制功能是构建大型,高性能应用程序的基础。将Mysql的数据分布到多个系统上去,这种分布的机制,是经过将Mysql的某一台主机(Master)的数据复制到其它主机(slaves)上,并从新执行一遍来实现的。复制过程当中一个服务器充当主服务器,而一个或多个其它服务器充当从服务器。主服务器将更新写入二进制日志文件,这些日志能够记录发送到从服务器的更新。当一个从服务器链接主服务器时,它通知主服务器从服务器在日志中读取的最后一次成功更新的位置。从服务器接收从那时起发生的任何更新,而后封锁并等待主服务器通知新的更新。 安全

主从复制架构图

 

 

数据库复制特性

Mysql复制解决的问题

MySQL复制技术有如下一些特色:

(1) 数据分布 (Data distribution )

(2) 负载平衡(load balancing)

(3) 备份(Backups)

(4) 高可用性和容错性 High availabilityand failover

 

Mysql复制如何工做

Mysql的复制功能主要有3个步骤:

(1) 主服务器(master)将改变记录到二进制日志(binarylog)中(这些记录叫作二进制日志事件,binary log events)

(2) 从服务器(slave)将主服务器master的binary logevents拷贝到它的中继日志(relay log)

(3) slave重作中继日志中的事件,将改变反映它本身的数据。

一、该过程的第一部分就是master记录二进制日志。在每一个事务更新数据完成以前,master在二进制日志记录这些改变。MySQL将事务串行的写入二进制日志,在事件写入二进制日志完成后,master通知存储引擎提交事务。此后可接收slave的请求

二、下一步就是slave将master的binary log拷贝到它本身的中继日志。首先,slave开始一个工做线程——I/O线程。I/O线程在master上打开一个普通的链接,而后开始在主节点上binlog dump process(二进制转存线程)。Binlog dump process从master的二进制日志中读取事件,若是已经跟上master,它会睡眠并等待master产生新的事件。I/O线程将这些事件写入中继日志。

三、 SQL slave thread(SQL从线程)处理该过程的最后一步。SQL线程从中继日志读取事件,并重放其中的事件而更新slave的数据,使其与master中的数据一致。只要该线程与I/O线程保持一致,中继日志一般会位于OS的缓存中,因此中继日志的开销很小。

 

 

I/O线程:将master数据库二进制日志拉到slave数据库上,并将二进制日志写到中继日志,写完以后,他会睡眠并等待master数据库二进制日志更新,一旦更新,就会写入slave数据库的中继日志中

SQL线程:读取中继日志的事件,并在数据库中执行,写入到内存中,使slave数据库的数据与master数据库中的数据一致

 

Mysql实现企业级数据库主从复制架构实战

注意:slave数据库只能是可读的,不能是可写的,若是改变了slave数据库的数据,master不能从slave数据库上同步数据,致使主从数据库数据不一致。

实战演练

1、环境准备

centos系统服务器2台、一台用户作Mysql主服务器,一台用于作Mysql从服务器,都在同一个网段中,配置好yum源、防火墙关闭、各节点时钟服务同步、各节点之间能够经过主机名互相通讯

2、准备步骤:

一、iptables -F && setenforce 清空防火墙策略,关闭selinux

二、拿两台服务器都使用yum方式安装Mysql服务,要求版本一致

三、分别启动两台服务器mysql服务,确保服务正常

3、实现步骤:

一、配置master主服务器

对master进行配置,包括打开二进制日志,指定惟一的servr ID。例如,在配置文件加入以下值

vim /etc/my.cnf

server-id=1 #配置server-id,让主服务器有惟一ID号(让从服务器知道他的主服务器是谁)

log-bin=mysql-bin #打开Mysql日志,日志格式为二进制

skip-name-resolve#关闭名称解析,(非必须)

而后重启数据库服务

systemctl restart mariadb

2.建立复制账号

在Master的数据库中创建一个备份账户:每一个slave使用标准的MySQL用户名和密码链接master

。进行复制操做的用户会授予REPLICATION SLAVE权限。(给从服务器受权,让他能从主服务器拷贝二进制日志)

mysql

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO slave@'192.168.10.%' IDENTIFIED BY 'magedu';

3.查看主服务器状态

在Master的数据库执行show master status,查看主服务器二进制日志状态

四、配置slave从服务器

对slave进行配置,打开中继日志,指定惟一的servr ID,设置只读权限。在配置文件加入以下值

vim /etc/my.cnf

server-id=2 #配置server-id,让从服务器有惟一ID号

relay_log = mysql-relay-bin #打开Mysql日志,日志格式为二进制

read_only = 1 #设置只读权限

log_bin = mysql-bin #开启从服务器二进制日志

log_slave_updates = 1 #使得更新的数据写进二进制日志中

而后重启数据库服务

systemctl restart mariadb

5.启动从服务器复制线程

让slave链接master,并开始重作master二进制日志中的事件。

mysql

CHANGE MASTER TO MASTER_HOST='192.168.10.190',

MASTER_USER='slave',

MASTER_PASSWORD='magedu',

MASTER_LOG_FILE='mysql-bin.000001',

MASTER_LOG_POS=278;

执行start slave;# 启动复制线程。

六、查看从服务器状态

可以使用SHOW SLAVE STATUS\G查看从服务器状态,以下所示,也可用show processlist \G查看前复制状态:

mysql

SHOW SLAVE STATUS\G

Slave_IO_Running: Yes #IO线程正常运行

Slave_SQL_Running: Yes #SQL线程正常运行

7.测试

理想的结果是在主服务器上添加的数据,在从服务器上也会同步

在主服务器上

 

在从服务器上

4、添加新slave服务器

假如master已经运行好久了,想对新安装的slave进行数据同步,甚至它没有master的数据。

此时,有几种方法可使slave从另外一个服务开始,例如,从master拷贝数据,从另外一个slave克隆,从最近的备份开始一个slave。为了加快Slave与master同步,可用如下方式先进行数据同步:

(1)master的某个时刻的数据快照;

(2)数据库的备份数据

(3)master的二进制日志文件。

 

实现主从从架构

也能够搭建主从从架构,让从服务器之间进行复制

就是在从服务器也开启二进制日志,而后从的从I/O线程再将从的二进制日志给拷贝过来写入到本身的relay log中,而后sql线程再读取relay log中的事件,在数据库中执行,写入到内存中。

 

Mysql复制过滤器

复制过滤器:

仅复制有限一个或几个数据库相关的数据,而非全部;由复制过滤器进行;

有两种实现思路:

(1) 主服务器

主服务器仅向二进制日志中记录有关特定数据库相关的写操做;

binlog_do_db=

binlog_ignore_db=

(2) 从服务器

从服务器的SQL THREAD仅重放关注的数据库或表相关的事件,并将其应用于本地;

Replicate_Do_DB=

Replicate_Ignore_DB=

 

企业常见数据库架构

1、单一master和多slave

在实际应用场景中,MySQL复制90%以上都是一个Master复制到一个或者多个Slave的架构模式,主要用于读压力比较大的应用的数据库端廉价扩展解决方案。由于只要Master和Slave的压力不是太大(尤为是Slave端压力)的话,异步复制的延时通常都不多不多。尤为是自从Slave端的复制方式改为两个线程处理以后,更是减少了Slave端的延时问题。而带来的效益是,对于数据实时性要求不是特别高的应用,只须要经过廉价的pcserver来扩展Slave的数量,将读压力分散到多台Slave的机器上面,便可经过分散单台数据库服务器的读压力来解决数据库端的读性能瓶颈,毕竟在大多数数据库应用系统中的读压力仍是要比写压力大不少。这在很大程度上解决了目前不少中小型网站的数据库压力瓶颈问题,甚至有些大型网站也在使用相似方案解决数据库瓶颈。

单一master和多slave架构图

(1) 不一样的slave扮演不一样的做用(例如使用不一样的索引,或者不一样的存储引擎);

(2) 用一个slave做为备用master,只进行复制;#主服务器挂了以后,可在从服务器执行

1> 在备机上执行STOP SLAVE 和RESET MASTER

2> 查看show slave status \G;

3> 而后修改应用的链接地址。

(3) 用一个远程的slave,用于灾难恢复;

2、互为主从Master-Master(Master-Master in Active-Active Mode)

Master-Master复制的两台服务器,既是master,又是另外一台服务器的slave。这样,任何一方所作的变动,都会经过复制应用到另一方的数据库中。

即:在两台服务器上既执行master的操做又执行slave的操做(注意:两台数据库都必须是可写的)

 

互为主从复制过程

互为主从:两个节点各自都要开启binlog和relay log;

一、数据不一致;

二、自动增加id;

 

什么是自增加ID?

对于某些惟一性的字段,能够经过设置自增加ID来实现,自增加ID的数据,表明这个表中存在一条惟一的记录;而自增加id是确定不会重复的;

 

建立表,设置ID为自增加

create table userInfo (id int PRIMARY KEY AUTO_INCREMENT,name varchar(50) NOT NULL);

 

两边插入数据看数据增加

insert into userInfo(name) value('xiao'),('da'),('lao');

 

定义一个节点使用奇数id

auto_increment_increment=2 #表示自增加字段每次递增的量

auto_increment_offset=1 #表示自增加字段从那个数开始

另外一个节点使用偶数id

auto_increment_increment=2

auto_increment_offset=2

 

配置:

一、server_id必需要使用不一样值;

二、均启用binlog和relay log; read only = 0(由于互为主从,因此必须是可写的)

三、存在自动增加id的表,为了使得id不相冲突,须要定义其自动增加方式;

服务启动后执行以下两步:

四、都受权有复制权限的用户帐号;

五、各把对方指定为主节点;

 

实验:数据库互为主从复制步骤

1.修改mysql配置文件

一台数据库服务器上

vim /etc/my.cnf

server-id = 1

log_bin = mysql_bin

relay_log = relay-log

skip-name-resolve = on

log_slave_updates = 1

auto_increment_increment=2

auto_increment_offset=1

另外一台数据库服务器上

vim /etc/my.cnf

server-id = 2

relay_log = relay-log

log_bin = mysql-log

skip-name-resolve = on

log_slave_updates = 1

auto_increment_increment=2

auto_increment_offset=2

修改完配置文件后,重启数据库服务

systemctl restart mariadb

2.建立复制账号

分别在两台数据库服务器上建立复制帐号

mysql

GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO slave@'192.168.10.%' IDENTIFIED BY 'magedu';

3.启动从服务器复制线程

让slave链接master,并开始重作master二进制日志中的事件。

mysql

CHANGE MASTER TO MASTER_HOST='192.168.10.190',

MASTER_USER='slave',

MASTER_PASSWORD='magedu',

MASTER_LOG_FILE='mysql-bin.000001',

MASTER_LOG_POS=278;

执行start slave;# 启动复制线程。

另外一台数据库服务器也是如此

四、查看从服务器状态

可以使用SHOW SLAVE STATUS\G查看从服务器状态,以下所示,也可用show processlist \G查看前复制态:

mysql

SHOW SLAVE STATUS\G

Slave_IO_Running: Yes #IO线程正常运行

Slave_SQL_Running: Yes #SQL线程正常运行

两台数据库服务器都显示如上结果就ok

5.建立表,设置ID为自增加,两边插入数据看数据增加

在一台数据库服务器上

mysql

create database dnf;

use dnf;

create table userinfo (id int PRIMARY KEY AUTO_INCREMENT,name varchar(20) NOT NULL);

insert into userinfo (name) values('ni'),('wo'),('ta');

而后查看表,由于是自增加id,从1开始,步长为2,因此添加的数据id为1,3,5

而后在另外一台数据库服务器插入数据,由于是自增加id,从2开始,步长为2,因此新添加的数据id为6,8,10

 

排错:当配置文件中配置中继日志格式不当心配置错了,或者让slave链接master,执行sql语句不当心写错了,都有可能致使start slave;报错,此时能够show slave status\G;会出现一大串信息,里面会提示错误。找到错误之后,重置slave,reset slave;从新设置,而后再start slave;

注意:mysql的错误日志很是重要,能够提供错误信息,从而找到错误缘由。

 

互为主从容易致使数据不一致,此时咱们能够用两个实例来互为主从

mysql优化:

1.能够用数据缓存,常见的memcache

2.数据库自己有不少缓存机制,可以使用对应的缓存策略

3.对数据来讲,竟可能使用索引

4.对请求而言,能够实现读写分离,对读请求负载均衡

5.对大数据库或者表,可根据业务逻辑进行分库分表

6.多有的优化,尽量网内存中存放

 

 

半同步复制

异步复制(Asynchronous replication)

MySQL默认的复制便是异步的,主库在执行完客户端提交的事务后会当即将结果返给给客户端,并不关心从库是否已经接收并处理,这样就会有一个问题,主若是crash掉了,此时主上已经提交的事务可能并无传到从上,若是此时,强行将从提高为主,可能致使新主上的数据不完整

全同步复制(Fully synchronous replication)

当主库执行完一个事务,全部的从库都执行了该事务才返回给客户端。由于须要等待全部从库执行完该事务才能返回,因此全同步复制的性能必然会收到严重的影响。须要有超时时间。

半同步复制(Semisynchronous replication)

介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是马上返回给客户端,而是等待至少一个从库接收到并写到relay log中才返回给客户端。相对于异步复制,半同步复制提升了数据的安全性,同时它也形成了必定程度的延迟,这个延迟最少是一个TCP/IP往返的时间。因此,半同步复制最好在低延时的网络中使用。

 

半同步复制

支持多种插件:/usr/lib64/mysql/plugins/

须要安装方可以使用:

mysql> INSTALL PLUGIN plugin_name SONAME 'shared_library_name';

半同步复制:

semisync_master.so

semisync_slave.so

 

主节点:

INSTALL PLUGIN rpl_semi_sync_master SONAME 'semisync_master.so';

MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';

+------------------------------------+-------+

| Variable_name | Value |

+------------------------------------+-------+

| rpl_semi_sync_master_enabled | OFF |

| rpl_semi_sync_master_timeout | 10000 |

| rpl_semi_sync_master_trace_level | 32 |

| rpl_semi_sync_master_wait_no_slave | ON |

+------------------------------------+-------+

MariaDB [mydb]> SET GLOBAL rpl_semi_sync_master_enabled=ON/1;

stop slave;

start slave;

 

从节点:

INSTALL PLUGIN rpl_semi_sync_slave SONAME 'semisync_slave.so';

MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';

+---------------------------------+-------+

| Variable_name | Value |

+---------------------------------+-------+

| rpl_semi_sync_slave_enabled | OFF |

| rpl_semi_sync_slave_trace_level | 32 |

+---------------------------------+-------+

MariaDB [mydb]> STOP SLAVE IO_THREAD;

MariaDB [mydb]> SET GLOBAL rpl_semi_sync_slave_enabled = ON ;

MariaDB [mydb]> SHOW GLOBAL VARIABLES LIKE 'rpl_semi%';

MariaDB [mydb]> START SLAVE IO_THREAD;

stop slave;

start slave;

可查看从库错误日志观察是否生效

master错误日志

slave错误日志

相关文章
相关标签/搜索