Mysql数据库:主从复制与读写分离
本文主要介绍mysql数据库的主从复制和读写分离的概念和工作原理,以及详细阐释了如何搭建mysql主从复制和读写分离的过程和步骤,希望对你有帮助!
目录
5.3 半同步复制(Semi-Sync Replication)
前言
本文主要介绍Mysql数据库的主从复制与读写分离,将主从复制与负载均衡结合使用,可以极大地提高数据库系统的性能和可靠性
在这种架构中,所有的写操作都发送到主服务器,而读操作则通过负载均衡器分配到多个从服务器。这样不仅可以确保数据的一致性和安全性,还可以通过增加从服务器的数量来水平扩展系统,提高读操作的处理能力
一、Mysql主从复制概述
1、Mysql主从复制概念
MySQL主从复制(Master-Slave Replication)是一种数据库复制和数据共享的技术,它允许数据从一个MySQL数据库(主数据库)复制到一个或多个MySQL数据库(从数据库)。这种机制主要用于提高数据的可用性、实现数据的备份、以及分担数据库查询负载
核心概念:
- 主数据库(Master):主数据库是数据变更(包括插入、更新和删除操作)发生的地方。它记录所有的数据变更事件到二进制日志(Binary Log)中。
- 从数据库(Slave):从数据库从主数据库接收数据变更事件,并将这些变更应用到自己的数据集中,从而保持与主数据库的数据一致性。
- 二进制日志(Binary Log):这是主数据库上的一个文件,记录了所有对数据库进行更改的事件。这些记录可以被从数据库用来复制数据。
- 中继日志(Relay Log):从数据库接收到来自主数据库的二进制日志后,会先将其存储在自己的中继日志中,然后再应用这些变更到自己的数据集中。
2、Mysql主从复制功能和使用场景
2.1 功能(为何使用主从复制)
- 数据备份:通过将数据从主服务器复制到从服务器,可以在从服务器上进行备份操作,减少主服务器的负担
- 读写分离:主服务器处理写操作,而从服务器处理读操作,这样可以分散数据库的访问压力,提高数据库系统的整体性能
- 故障恢复:当主服务器出现故障时,可以快速切换到从服务器,保证服务的连续性和数据的完整性
- 数据分布:可以将数据复制到地理位置分散的服务器上,提高数据的本地访问速度和可用
- 负载均衡:通过增加从服务器的数量,可以将读请求分散到多个服务器上,实现负载均衡
2.2 适用场景(何时使用主从复制)
- 高可用性部署:在需要确保数据库服务高度可用的场景中,主从复制可以通过自动或手动故障转移来保证服务的持续性
- 大规模读操作:对于读操作远远多于写操作的应用,如新闻网站、社交网络等,使用主从复制可以有效地提高查询性能和系统响应速度
- 数据分析和报告:可以在从服务器上进行数据分析和生成报告,避免影响主服务器上的业务操作
- 跨地域数据同步:对于需要在多个地理位置提供快速数据访问的应用,主从复制可以将数据复制到接近用户的服务器上,减少数据访问延迟
- 在线备份:在从服务器上进行备份操作,可以避免对主服务器性能的影响,同时确保数据的安全性
3、Mysql复制的类型
3.1 基于SQL语句的复制(Statement默认)
- 原理:在这种复制模式下,主服务器上执行的SQL语句(更改数据的语句)会被记录到二进制日志中。然后,这些SQL语句会被复制到从服务器并重新执行,以此来达到主从数据一致的目的
- 优点:由于只复制SQL语句,所以数据量小,网络带宽的占用较低
- 缺点:在某些情况下,比如使用了非确定性函数(如NOW()、RAND())的SQL语句,可能会导致主从数据不一致
3.2 基于行的复制(Row)
- 原理:与SBR不同,RBR直接复制数据变更后的行的新值到从服务器。不管是通过何种SQL语句引起的数据变更,都会被复制
- 优点:可以避免SBR中由于非确定性函数等导致的数据不一致问题,适用于大多数需要精确复制的场景
- 缺点:如果变更的数据量很大,比如大批量更新操作,那么复制的数据量也会很大,对网络带宽和从服务器的处理能力提出了更高的要求
3.3 混合模式复制(Mixed)
- 原理:混合模式复制结合了SBR和RBR的优点。在这种模式下,MySQL会根据操作的类型和内容智能选择使用SBR还是RBR。对于可能导致数据不一致的操作,使用RBR;对于其他操作,则使用SBR
- 优点:能够在保证数据一致性的同时,尽可能减少复制所需的数据量
- 缺点:复制逻辑更复杂,可能需要更多的管理和调优
4、实现主从复制的工作原理
- Master节点将数据的改变记录成二进制日志(bin log),当Master上的数据发生改变时,则将其改变写入二进制日志中
- Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求 Master的二进制事件
- 同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relay log)中,Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成 sql 语句逐一执行,使得其数据和 Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒
- 首先client端(tomcat)将数据写入到master节点的数据库中,master节点会通知存储引擎提交事务,同时会将数据以(基于行、基于sql、基于混合)的方式保存在二进制日志中
- SLAVE节点会开启I/O线程,用于监听master的二进制日志的更新,一旦发生更新内容,则向master的dump线程发出同步请求
- master的dump线程在接收到SLAVE的I/O请求后,会读取二进制文件中更新的数据,并发送给SLAVE的I/O线程
- SLAVE的I/O线程接收到数据后,会保存在SLAVE节点的中继日志中
- 同时,SLAVE节点中的SQL线程,会读取中继日志中的数据,更新在本地的mysql数据库中
- 最终,完成slave——>复制master数据,达到主从同步的效果
注:
- 中继日志通常会位于 OS 缓存中,所以中继日志的开销很小
- 复制过程有一个很重要的限制,即复制在 Slave上是串行化的,也就是说 Master上的并行更新操作不能在 Slave上并行操作
5、Mysql三种同步方式
5.1 异步复制(Async Replication)
默认同步方式是异步复制。主库将更新写入Binlog日志文件后,不需要等待数据更新是否已经复制到从库中,就可以继续处理更多的请求。Master将事件写入binlog,但并不知道Slave是否或何时已经接收且已处理。
在异步复制的机制的情况下,如果Master宕机,事务在Master上已提交,但很可能这些事务没有传到任何的Slave上。假设有Master->Salve故障转移的机制,此时Slave也可能会丢失事务。MySQL复制默认是异步复制,异步复制提供了最佳性能。
5.2 同步复制(Sync Replication)
主库将更新写入Binlog日志文件后,需要等待数据更新已经复制到从库中,并且已经在从库执行成功,然后才能返回继续处理其它的请求。
同步复制提供了最佳安全性,保证数据安全,数据不会丢失,但对性能有一定的影响。
5.3 半同步复制(Semi-Sync Replication)
主库提交更新写入二进制日志文件后,等待数据更新写入了从服务器中继日志中,然后才能再继续处理其它请求。该功能确保至少有1个从库接收完主库传递过来的binlog内容已经写入到自己的relay log里面了,才会通知主库上面的等待线程,该操作完毕。
半同步复制,是最佳安全性与最佳性能之间的一个折中。
MySQL 5.5版本之后引入了半同步复制功能,主从服务器必须安装半同步复制插件,才能开启该复制功能。如果等待超时,超过rpl_semi_sync_master_timeout参数设置时间(默认值为10000,表示10秒),则关闭半同步复制,并自动转换为异步复制模式。当master dump线程发送完一个事务的所有事件之后,如果在rpl_semi_sync_master_timeout内,收到了从库的响应,则主从又重新恢复为增强半同步复制。
ACK (Acknowledge character)即是确认字符。
6、Mysql主从复制延迟
6.1 主从复制延迟的原因
MySQL数据库中的主从复制延迟主要是由于从服务器在复制和应用主服务器上的更改时出现了延迟。这种延迟可能由多种因素引起,包括但不限于:
-
网络延迟:主服务器和从服务器之间的网络延迟可能导致复制数据的速度变慢。如果服务器之间的网络连接不稳定或带宽有限,复制延迟就会增加
-
硬件性能差异:如果从服务器的硬件(如CPU速度、磁盘I/O性能、内存大小等)不如主服务器,那么它在处理复制数据时可能会更慢,导致延迟
-
高负载:如果主服务器或从服务器承受着高负载,例如处理大量的写操作或复杂查询,可能会导致复制过程变慢,增加延迟
-
大事务:主服务器上的大事务需要在从服务器上完整复制和重放。如果事务非常大,复制和应用这些事务可能需要更长的时间,从而导致延迟
-
复制配置:复制配置不当也可能导致延迟。例如,如果启用了基于行的复制(row-based replication)而数据变更很频繁,可能会产生大量的复制数据,从而增加延迟
-
并发写入:在某些情况下,从服务器上的并发写入操作可能会与复制过程争夺资源,导致复制应用速度减慢
-
SQL线程单一:在MySQL复制架构中,从服务器上的SQL线程是单线程的,这意味着在任何给定时间点,只有一个复制事件被应用。这可能成为复制延迟的瓶颈,尤其是在高更新频率的场景中
6.2 如何解决主从复制延迟
-
优化网络连接:确保主从服务器之间的网络连接稳定和高速。使用高性能的网络设备和优化网络配置可以减少数据传输延迟。
-
优化主从服务器配置:确保主从服务器的硬件配置足够强大,包括CPU、内存和磁盘性能。这可以提高数据处理和传输的效率,减少延迟。
-
调整主从同步参数:通过调整MySQL的主从同步参数来优化同步效率。例如,可以调整binlog相关参数,增加binlog大小,调整同步线程数等。
-
避免长事务:长事务可能会导致主从复制延迟,因为在事务未提交之前,主库的binlog日志不会被发送到从库。尽量避免长事务的执行。
-
监控和优化数据库性能:定期监控数据库性能,包括主从服务器的负载、IO等情况,及时发现并解决潜在问题。
-
使用并行复制:MySQL 5.6及以上版本支持并行复制,可以提高数据同步的效率,减少延迟。
-
定期清理binlog日志:定期清理不再需要的binlog日志,避免日志文件过大影响同步效率。
-
考虑使用第三方工具:有一些第三方工具可以帮助优化主从复制,如pt-heartbeat、pt-table-checksum等工具
7、Mysql主从服务器版本问题
主从服务器的MySQL版本应该是兼容的,最好是相同的主要版本号。虽然MySQL通常支持跨版本的主从复制,但最好保持主从服务器版本一致以避免潜在的兼容性问题
若主从服务器版本不一致,从服务器的版本一定要高于主,保证可以向下兼容,因为若主服务器的版本更新,低版本的从服务器无法兼容的
8、中途加入新从服务器,需要怎样配置
如数据中途加入主从复制的库,需要导出主服务器库的库文件并且导入到从服务器中
步骤:
-
创建数据库备份:
在主服务器上执行数据库备份操作,以便将备份数据用于初始化新的从服务器
-
导入备份到新的从服务器:
将主服务器上的数据库备份文件导入到新的从服务器,确保新的从服务器具有与主服务器一致的初始数据
-
配置从服务器连接信息:
在新的从服务器上编辑MySQL配置文件,指定主服务器的连接信息,包括主服务器的地址、端口号、用户名和密码
-
启动从服务器:
启动新的从服务器,并确保它可以成功连接到主服务器
-
开始复制:
在新的从服务器上执行命令,使其开始从主服务器上获取数据并进行复制。这通常包括使用change master to
命令指定主服务器的位置以及登录凭据
-
监控同步状态:
监控新的从服务器的同步状态,确保数据能够正常地从主服务器同步到新的从服务器
注:
- 确保主服务器的二进制日志包含了新从服务器加入之前的所有操作,以便新的从服务器能够完整地进行数据同步
- 在执行任何配置更改之前,务必备份数据库以防止意外数据丢失
二、搭建Mysql主从复制
1、环境部署
设备 | 操作系统 | IP地址 | 所需工具/软件/安装包 |
Master主服务器 | CentOS7 | 172.16.12.10 | ntp 、 mysql-boost-5.7.20.tar.gz |
Slave1从服务器 | CentOS7 | 172.16.12.12 | ntpdate 、mysql-boost-5.7.20.tar.gz |
Slave2从服务器 | CentOS7 | 172.16.12.13 | ntpdate 、 mysql-boost-5.7.20.tar.gz |
关闭所有设备的防火墙和核心防护
[root@localhost ~]#systemctl stop firewalld
[root@localhost ~]#setenforce 0
2、搭建Master主服务器
2.1 安装mysql软件
#修改主机名,方便区分对应的服务器
[root@localhost ~]#hostnamectl set-hostname master
[root@localhost ~]#bash
#master主服务器需编译安装的mysql软件
可参考《Mysql数据库概念与安装》:http://t.csdnimg.cn/wkJLr
2.2 部署主与从服务器的时间同步
#部署主与从服务器的时间同步
[root@master ~]#yum install -y ntp
[root@master ~]#vim /etc/ntp.conf
server 127.127.12.0
#设置本地是时钟源,注意修改网段
fudge 127.127.12.0 stratum 8
#设置时间层级为8(限制在15内)
[root@master ~]#systemctl start ntpd
2.3 修改mysql配置文件
[root@master ~]#vim /etc/my.cnf
server-id = 1
log-bin=master-bin
#添加,主服务器开启二进制日志
binlog_format = MIXED
log-slave-updates=true
#添加,允许slave从master复制数据时可以写入到自己的二进制日志
[root@master ~]#systemctl restart mysqld
2.4 在Master上为Slave授权
[root@master ~]#mysql -uroot -p123456
grant replication slave on *.* to 'myslave'@'172.16.12.%' identified by '123456';
#为172.16.12.网段的从服务器授权
flush privileges;
[root@master ~]#show master status; #查看主服务器当前状态
#File 列显示日志名,Fosition 列显示偏移量
3、搭建Slave1从服务器
3.1 安装mysql软件
#修改主机名,方便区分对应的服务器
[root@localhost ~]#hostnamectl set-hostname slave1
[root@localhost ~]#bash
#Slave从服务器需编译安装的mysql软件
可参考《Mysql数据库概念与安装》:http://t.csdnimg.cn/wkJLr
3.2 部署主与从服务器的时间同步
[root@slave1 ~]#yum -y install ntpdate
[root@slave1 ~]#service ntpd start
/usr/sbin/ntpdate 172.16.12.10
#进行时间同步,指向Master服务器IP
[root@slave1 ~]#date
[root@slave1 ~]#crontab -e
*/20 * * * * /usr/sbin/ntpdate 172.16.12.10
3.3 修改mysql配置文件
[root@slave1 ~]#vim /etc/my.cnf
server-id = 2
#修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin
#添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index
#添加,定义中继日志文件的位置和名称
relay_log_recovery = 1
#选配项
#当 slave 从库宕机后,假如 relay-log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay-log,并且重新从 master 上获取日志,这样就保证了relay-log 的完整性。默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为 1 时, 可在 slave 从库上开启该功能,建议开启
[root@slave1 ~]#systemctl restart mysqld
3.4 配置主从同步
[root@slave1 ~]#mysql -u root -p
change master to master_host='172.16.12.10' , master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=602;
#配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致,每个人的都不一样
#master_host='172.16.12.10':设置主服务器的IP地址为192.168.44.60。
#master_user='myslave':设置用于复制的用户为'myslave',这个用户在主服务器上必须拥有replication slave权限
#master_password='123456':设置复制用户的密码为'123456'。在实际生产环境中,务必使用强密码
#master_log_file='master-bin.000001':指定从哪个二进制日志文件开始复制,这里是从'master-bin.000001'文件开始
#master_log_pos=602:指定在上述二进制日志文件中的起始位置为1743
#执行这个命令之后,从服务器将开始尝试连接主服务器,并从指定的日志文件和位置开始接收并执行主服务器上的数据变更事件,以实现主从复制的功能。在执行此命令前,请确保主服务器的二进制日志配置正确,且从服务器有权访问主服务器。此外,执行完该命令后通常还需要执行START SLAVE命令来启动复制进程
3.5 启动同步,并查看slave1状态
start slave; #启动同步,如有报错执行 reset slave;
show slave status\G #查看 Slave 状态
#确保 IO 和 SQL 线程都是 Yes,代表同步正常
Slave_IO_Running: Yes #负责与主机的io通信
Slave_SQL_Running: Yes #负责自己的slave mysql进程
注:
一般 Slave_IO_Running: No 的可能性(一步步排查):
- 网络不通
- my.cnf配置有问题
- 设置主从同步时:密码、file文件名、pos偏移量不对
- 防火墙、核心防护没有关闭
4、搭建Slave2从服务器
4.1 安装mysql软件
#修改主机名,方便区分对应的服务器
[root@localhost ~]#hostnamectl set-hostname slave2
[root@localhost ~]#bash
#Slave2从服务器需编译安装的mysql软件
可参考《Mysql数据库概念与安装》:http://t.csdnimg.cn/wkJLr
4.2 部署主与从服务器的时间同步
[root@slave2 ~]#yum -y install ntpdate
[root@slave2 ~]#service ntpd start
/usr/sbin/ntpdate 172.16.12.10
#进行时间同步,指向Master服务器IP
[root@slave2 ~]#date
[root@slave2 ~]#crontab -e
*/20 * * * * /usr/sbin/ntpdate 172.16.12.10
4.3 修改mysql配置文件
[root@slave2 ~]#vim /etc/my.cnf
server-id = 3
#修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin
#添加,开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=slave-relay-bin.index
#添加,定义中继日志文件的位置和名称
relay_log_recovery = 1
#选配项
#当 slave 从库宕机后,假如 relay-log 损坏了,导致一部分中继日志没有处理,则自动放弃所有未执行的 relay-log,并且重新从 master 上获取日志,这样就保证了relay-log 的完整性。默认情况下该功能是关闭的,将 relay_log_recovery 的值设置为 1 时, 可在 slave 从库上开启该功能,建议开启
[root@slave2 ~]#systemctl restart mysqld
4.4 配置主从同步
[root@slave2 ~]#mysql -u root -p
change master to master_host='172.16.12.10' , master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=602;
#配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致,每个人的都不一样
#master_host='172.16.12.10':设置主服务器的IP地址为192.168.44.60。
#master_user='myslave':设置用于复制的用户为'myslave',这个用户在主服务器上必须拥有replication slave权限
#master_password='123456':设置复制用户的密码为'123456'。在实际生产环境中,务必使用强密码
#master_log_file='master-bin.000001':指定从哪个二进制日志文件开始复制,这里是从'master-bin.000001'文件开始
#master_log_pos=602:指定在上述二进制日志文件中的起始位置为1743
#执行这个命令之后,从服务器将开始尝试连接主服务器,并从指定的日志文件和位置开始接收并执行主服务器上的数据变更事件,以实现主从复制的功能。在执行此命令前,请确保主服务器的二进制日志配置正确,且从服务器有权访问主服务器。此外,执行完该命令后通常还需要执行START SLAVE命令来启动复制进程
4.5 启动同步,并查看slave2状态
start slave; #启动同步,如有报错执行 reset slave;
show slave status\G #查看 Slave 状态
#确保 IO 和 SQL 线程都是 Yes,代表同步正常
Slave_IO_Running: Yes #负责与主机的io通信
Slave_SQL_Running: Yes #负责自己的slave mysql进程
注:
一般 Slave_IO_Running: No 的可能性(一步步排查):
- 网络不通
- my.cnf配置有问题
- 设置主从同步时:密码、file文件名、pos偏移量不对
- 防火墙、核心防护没有关闭
5、验证主从复制效果
5.1 Master主服务器操作
进入master主服务器的数据库中,创建xgy库并在库中创建class表
[root@master ~]#mysql -uroot -p123456
create database xgy;
use xgy;
create table class(id int(3) primary key,name varchar(10),address varchar(50));
show tables;
5.2 从服务器上查看是否数据同步
show databases;
show tables in xgy;
三、Mysql读写分离概述
1、Mysql读写分离概念
读写分离,是主数据库负责处理所有的写操作(插入、更新、删除),并负责维护数据的一致性。写操作在主数据库上执行后,会通过主从复制机制将数据变更同步到从数据库。从数据库是主数据库的副本,用于处理读操作(查询)。从数据库通过主从复制机制从主数据库同步数据变更,以保持数据的一致性
在读写分离架构中,通常会使用负载均衡器将读请求分发到不同的从数据库上,以均衡系统的负载,提高整体性能和并发处理能力
尽管主从复制可以提高性能,但需要注意数据一致性的问题。在读写分离架构中,由于主从同步的延迟,可能会出现数据不一致的情况,需要采取相应的措施来处理
2、Mysql读写分离的功能和适用场景
2.1 功能(为何使用读写分离)
-
提高性能:通过将读操作和写操作分离,读写分离可以有效减轻主数据库的负担,提高系统的整体性能
-
负载均衡:通过在多个从数据库上分发读请求,可以实现负载均衡,避免单点故障,提高系统的并发处理能力
-
提高可用性:读写分离架构可以提高系统的可用性。如果主数据库发生故障,可以快速切换到从数据库,确保系统的正常运行
-
扩展性:读写分离可以方便地扩展数据库系统。通过添加更多的从数据库,可以横向扩展系统的读取能力,应对不断增长的读取需求
-
故障恢复:当主数据库发生故障时,从数据库可以顶替主数据库的角色,保证系统的持续运行,降低系统宕机的风险
2.2 适用场景(何时使用读写分离)
-
高并发读取:适用于读操作频繁、写操作相对较少的场景,如新闻网站、电子商务平台等,能够显著提升系统的读取性能
-
数据报表查询:对于需要大量数据分析和报表生成的应用,读写分离可以加快数据查询速度,提高报表生成的效率
-
全文搜索:对于需要进行全文搜索的应用,读写分离可以将搜索操作分担到从数据库上,减轻主数据库的压力
-
分布式部署:在分布式系统中,通过读写分离可以简化数据访问模式,提高系统的整体性能和稳定性
-
大型社交平台:适用于大型社交平台等需要处理大量用户读取请求的场景,通过读写分离可以更好地应对高并发读取的挑战
总之,Mysql读写分离适用于读操作频繁、写操作相对较少的场景,能够提高系统的性能、可用性和扩展性,是许多高负载应用和网站常用的数据库架构设计模式
3、实现Mysql读写分离的方法
目前较为常见的 MySQL 读写分离分为以下两种:
(1)基于程序代码内部实现
- 原理:在代码中根据 select、insert 进行路由分类,这类方法也是目前生产环境应用最广泛的
- 优点:性能较好,因为在程序代码中实现,不需要增加额外的设备为硬件开支;缺点是需要开发人员来实现,运维人员无从下手
- 缺点:并不是所有的应用都适合在程序代码中实现读写分离,像一些大型复杂的Java应用,如果在程序代码中实现读写分离对代码改动就较大
(2)基于中间代理层实现
代理一般位于客户端和服务器之间,代理服务器接到客户端请求后通过判断后转发到后端数据库,
有以下代表性程序
① MySQL-Proxy:MySQL-Proxy 为 MySQL 开源项目,通过其自带的 lua 脚本进行SQL 判断
② Atlas:由奇虎360的Web平台部基础架构团队开发维护的一个基于MySQL协议的数据中间层项目。它是在mysql-proxy 0.8.2版本的基础上,对其进行了优化,增加了一些新的功能特性。360内部使用Atlas运行的mysql业务,每天承载的读写请求数达几十亿条。支持事物以及存储过程
③ Amoeba:由陈思儒开发,作者曾就职于阿里巴巴。该程序由Java语言进行开发,阿里巴巴将其用于生产环境。但是它不支持事务和存储过程
由于使用MySQL Proxy 需要写大量的Lua脚本,这些Lua并不是现成的,而是需要自己去写。这对于并不熟悉MySQL Proxy 内置变量和MySQL Protocol 的人来说是非常困难的
Amoeba是一个非常容易使用、可移植性非常强的软件。因此它在生产环境中被广泛应用于数据库的代理层
4、实现读写分离的工作原理
- 客户端所有的写操作(插入、更新、删除)可以通过Amoeba服务器将请求调度到主服务器上进行
- 客户端所有的读操作(查询)可以通过Amoeba服务器将请求分发到多个从数据库上进行,以实现负载均衡
- 主服务器和从服务器的数据通过主从复制机制保持数据的一致性
- 这种架构模式可以提高系统的性能、可用性和扩展性,是许多高负载应用和网站常用的数据库架构设计模式
四、搭建Mysql读写分离
1、环境部署
基于上面的Mysql主从复制的搭建,然后再进行读写分离的搭建
设备 | 操作系统 | IP地址 | 所需工具/软件/安装包 |
Master主服务器 | CentOS7 | 172.16.12.10 | ntp 、 mysql-boost-5.7.20.tar.gz |
Slave1从服务器 | CentOS7 | 172.16.12.12 | ntpdate 、mysql-boost-5.7.20.tar.gz |
Slave2从服务器 | CentOS7 | 172.16.12.13 | ntpdate 、 mysql-boost-5.7.20.tar.gz |
Amoeba | CentOS7 | 172.16.12.11 | jdk-6u14-linux-x64.bin、amoeba-mysql-binary-2.2.0.tar.gz |
客户端 | CentOS7 | 172.16.12.15 | mariadb |
2、搭建Amoeba服务器
#修改主机名,方便区分对应的服务器
[root@localhost ~]#hostnamectl set-hostname Amoeba
[root@localhost ~]#bash
2.1 安装Amoeba软件
因为 Amoeba 基于是 jdk1.5 开发的,所以官方推荐使用 jdk1.5 或 1.6 版本,高版本不建议使用。
将jdk-6u14-linux-x64.bin 和 amoeba-mysql-binary-2.2.0.tar.gz.0 上传到/opt目录下
#先安装 java 环境
[root@amoeba opt]#cd /opt/
[root@amoeba opt]#cp jdk-6u14-linux-x64.bin /usr/local/
[root@amoeba opt]#cd /usr/local/
[root@amoeba local]#chmod +x jdk-6u14-linux-x64.bin
[root@amoeba local]#./jdk-6u14-linux-x64.bin
#按空格到最后一行
#按yes,再按enter
[root@amoeba local]#mv jdk1.6.0_14/ /usr/local/jdk1.6
#为了让系统能够识别这个版本的jdk,需设置环境变量
[root@amoeba local]#vim /etc/profile.d/jdk.sh
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin
[root@amoeba local]#source /etc/profile.d/jdk.sh
[root@amoeba local]#java -version
##安装 Amoeba软件##
[root@amoeba local]#mkdir /usr/local/amoeba
[root@amoeba local]#tar zxvf /opt/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@amoeba local]#chmod -R 755 /usr/local/amoeba/
[root@amoeba local]#/usr/local/amoeba/bin/amoeba
#如显示amoeba start|stop 说明安装成功
2.2 配置Amoeba读写分离及两个从服务器读负载均衡
先必须在Master、Slave1、Slave2 的mysql上开放权限给 Amoeba 访问
grant all on *.* to test@'172.16.12.%' identified by '123456';
Amoeba服务器配置Amoeba服务:
[root@amoeba local]#cd /usr/local/amoeba/conf/
[root@amoeba conf]#cp amoeba.xml amoeba.xml.bak #备份配置文件,万一修改错误,可恢复
[root@amoeba conf]#vim amoeba.xml #修改amoeba配置文件
第30修改
<property name="user">amoeba</property>
第32修改
<property name="password">123456</property>
第115修改
<property name="defaultPool">master</property>
第117去掉注释–
<property name="writePool">master</property>
<property name="readPool">slaves</property>
2.3 修改数据库配置文件
[root@amoeba conf]#cp dbServers.xml dbServers.xml.bak
[root@amoeba conf]#vim dbServers.xml #修改数据库配置文件
第23注释掉
作用:默认进入test库 以防mysql中没有test库时,会报错
<!-- mysql schema
<property name="schema">test</property>
-->
第26修改
<!-- mysql user -->
<property name="user">test</property>
第28-30去掉注释
<property name="password">123456</property>
第45修改,设置主服务器的名Master
<dbServer name="master" parent="abstractServer">
第48修改,设置主服务器的地址
<property name="ipAddress">192.168.223.10</property>
第52修改,设置从服务器的名slave1
<dbServer name="slave1" parent="abstractServer">
第55修改,设置从服务器1的地址
<property name="ipAddress">192.168.223.9</property>
第58复制上面6行粘贴,设置从服务器2的名slave2和地址
<dbServer name="slave2" parent="abstractServer">
<property name="ipAddress">192.168.223.11</property>
第65修改
<dbServer name="slaves" virtual="true">
第71修改
<property name="poolNames">slave1,slave2</property>
[root@amoeba conf]#/usr/local/amoeba/bin/amoeba start&
#启动Amoeba软件,按ctrl+c 返回
[root@amoeba conf]#netstat -anpt | grep java
#查看8066端口是否开启,默认端口为TCP 8066
3、客户端配置
#修改主机名,方便区分客户端
[root@localhost ~]#hostnamectl set-hostname PC
[root@localhost ~]#bash
通过amoeba服务器代理访问mysql ,在通过客户端连接mysql后写入的数据只有主服务会记录,然后同步给从服务器
[root@pc ~]#yum install -y mariadb mariadb-server
#使用yum快速安装MySQL虚拟客户端
[root@pc ~]#systemctl start mariadb.service
[root@pc ~]#mysql -u amoeba -p123456 -h 172.16.12.11 -P8066
#远程访问amoeba服务器
4、测试读写分离(关闭同步)
4.1 前提部署
slave1从服务器操作:
stop slave; #关闭同步
use xgy;
insert into class values('1','dayu','this is slave1');
#插入表数据
select * from class;
slave2从服务器操作:
stop slave; #关闭同步
use xgy;
insert into class values('2','cxli','this is slave2');
#插入表数据
select * from class;
master主服务器操作:
insert into class values('3','ckja','this is master');
select * from class;
4.2 测试
读测试:
use xgy;
select * from class;
#客户端分别向slave1和slave2读取数据,因为slave1和slave2都关闭了同步,显示的只是在两个从服务器上添加的数据,没有主服务器同步的数据
写测试:
在客户端写一条表数据,测试在哪个mysql服务器上有该数据
insert into class values('4','dsff','this is PC');
三个mysql服务器上查看表数据:是否有客户端写入的新数据
5、测试读写分离(开启同步)
5.1 前提部署
#在两个从服务器上开启同步
start slave;
5.2 测试
客户端读测试:
五、总结
1、主从同步复制原理
核心重点:
①两个日志:二进制日志、中继日志
二进制日志:
- 主服务器上的二进制日志包含了所有对数据的修改操作,以事件形式记录
- 这些事件会被传播到从服务器,从服务器根据这些事件来保持与主服务器数据的一致性
中继日志:
- 从服务器上的中继日志用于存储从主服务器获取的二进制日志事件
- 从服务器会读取主服务器的二进制日志,并将这些事件写入中继日志中,然后应用到本地数据库
②三个关键线程:Dump Thread、I/O Thread、SQL Thread
Dump Thread:
- 当从服务器连接到主服务器请求复制时,主服务器会创建一个Binlog Dump线程,负责将二进制日志事件发送给从服务器。
I/O Thread:
- 从服务器上的I/O线程负责连接到主服务器并读取主服务器上的二进制日志文件,然后将其写入到本地的中继日志中。
SQL Thread:
- 从服务器上的SQL线程负责读取中继日志中的事件,并在本地数据库中执行这些事件,以实现数据同步。
2、读写分离使用什么方式
- 通过amoeba代理服务器,实现只在主服务器上写,只在从服务器上读
- 主数据库处理事务性查询,从数据库处理select 查询
- 数据库复制被用来把事务查询导致的变更同步的集群中的从数据库
3、如何查看主从同步状态是否成功
- 在从服务器上内输入 show slave status\G 查看主从信息查看里面有IO线程的状态信息,还有master服务器的IP地址、端口事务开始号
- 当 Slave_IO_Running和Slave_SQL_Running都是YES时 ,表示主从同步状态成功
4、如果从服务器的I/O不是yes,如何排查
- 首先排查网络问题,使用ping 命令查看从服务器是否能与主服务器通信
- 再查看防火墙和核心防护是否关闭(增强功能)
- 接着查看从服务slave是否开启
- 两个从服务器的server-id 是否相同导致只能连接一台
- master_log_file master_log_pos的值跟master值是否一致
5、show slave status能看到哪些重要信息
- IO线程的状态信息
- master服务器的IP地址、端口、事务开始的位置
- 最近一次的错误信息和错误位置
- 最近一次的I/O报错信息和ID
- 最近一次的SQL报错信息和id
6、主从复制慢(延迟)会有哪些可能?如何解决?
主从复制慢(延迟)的原因:
- 主服务器的负载过大,被多个睡眠或僵尸线程占用,导致系统负载过大,从库硬件比主库差,导致复制延迟
- 主从复制单线程,如果主库写作并发太大,来不及传送到从库,就会到导致延迟
- 慢sql语句过多
- 网络延迟
主从复制慢(延迟)的的解决方法:
-
优化网络连接:确保主从服务器之间的网络连接稳定和高速
-
优化主从服务器配置:确保主从服务器的硬件配置足够强大,包括CPU、内存和磁盘性能
-
调整主从同步参数:通过调整MySQL的主从同步参数来优化同步效率。例如,可以调整binlog相关参数,增加binlog大小,调整同步线程数等。
-
避免长事务:尽量避免长事务的执行
-
监控和优化数据库性能:定期监控数据库性能,包括主从服务器的负载、IO等情况,及时发现并解决潜在问题
-
使用并行复制:MySQL 5.6及以上版本支持并行复制,可以提高数据同步的效率,减少延迟
-
定期清理binlog日志:定期清理不再需要的binlog日志,避免日志文件过大影响同步效率
-
考虑使用第三方工具:有一些第三方工具可以帮助优化主从复制,如pt-heartbeat、pt-table-checksum等工具
开放原子开发者工作坊旨在鼓励更多人参与开源活动,与志同道合的开发者们相互交流开发经验、分享开发心得、获取前沿技术趋势。工作坊有多种形式的开发者活动,如meetup、训练营等,主打技术交流,干货满满,真诚地邀请各位开发者共同参与!
更多推荐
所有评论(0)