概述
单机Mysql的缺点:
- 读写请求都落在一台机器上,压力较大。
- 低可用性,因为是单机单节点,一旦该节点挂了,服务就对外不可用了。
- 容灾性低,因为单机,如果没有做及时备份的话,一旦机器出现不可挽回灾难的话,就会造成数据的丢失。
…
优点:简单。
所以,就需要主从架构的出现:
好处:
- 使用主从架构并实现读写分离,主服务器负责写,从服务器负责读,可以降低服务器的压力,并且通过扩展从服务器可以提高读性能。
- 高可用性,用双主双从架构达到主节点的主备切换,达到高可用。
- 容灾性好,每个从节点都是主节点的副本,如果主节点数据丢失,有不会造成数据丢失。
…
Mysql主从复制原理
- Master节点必须开启二进制日志binLog,每次数据变更,都会记录到日志里面。
- 主从服务器之间建立IO线程进行通信。
- 从服务器通过IO线程读取主节点的binLog,并把它写到中继日志(Relay log)中,所以从服务器要开启中继日志。
- 从服务器的SQL线程从中继日志读取内容进行数据的复制。
主从复制之间遵循AP,也就是数据一致性会存在一定的延时。
跟Redis主从复制的从头开始完全复制不一样,Mysql会从某个切入点(偏移量)开始复制。
搭建
一主一从
一台主机,一台从机。
- 配置主机/etc/my.cnf.
#配置主服务器唯一Id,要在整个集群中唯一。
server-id=1
#配置开启binLog
log-bin=mysql-bin
#配置要写入binlog日志文件的数据库名称
binlog-do-db=producer
#binlog日志文件格式类型
binlog_format=STATEMENT
binlog日志文件格式类型有三种:
- STATEMENT:这种格式就类似redis的AOF,就是把修改数据的每一条sql语句写入日志,然后从节点通过执行这些语句达到复制的作用。
但是这种格式的缺点是一些变化的变量,可能会导致数据不一致,比如update xx set time=now() where id=5,这条语句,在主节点执行时,和在从节点执行时的时间点回不一样,这就会导致主从复制的数据不一致。 - ROW:把数据变化的一行行数据记录到日志中去,然后从服务器执行修改,这个直接就记录变化后的数据,所以像now()这些也不会导致数据不一致。但是缺点是 如果是全表更新或者大范围更新,比如update xx set name=‘xxx’ ,没有条件,导致全表更新,比如这个表有1000w条数据,那么日志文件就会记录着1000w行数据,会变得非常大,然后从服务器一条条更新,效率也会慢,此时如果是STATEMENT的哈,就只是一条sql语句而已。
- MIXID:这个格式解决了部分数据不一样的问题,他会把update xx set time=now() where id=5这样涉及这种变量函数的sql用ROW模式记录,像没有这些函数就以STATEMENT格式记录。但是还是会有一点问题,一些系统变量,比如@@host_name,这些数据不一致就避免不了。
- 配置从服务器/etc/my.cnf
#设置集群唯一节点id
server-id=2
#启用中继日志
relay-log=mysql-relay
- 重启主节点和从节点。
- 防火墙开放相关端口,用于通信。
firewall-cmd --permanent --add-port=3306/tcp
firewall-cmd --permanent --add-port=3308/tcp
firewall-cmd --permanent --add-port=14723/tcp
firewall-cmd --reload
- 主机创建用户,用于给从机进行复制时使用。
GRANT REPLICATION SLAVE ON *.* TO 'slave'@'%' IDENTIFIED BY 'abc123456';
- 主机使用命令查看状态。
show master status
File是binlog的文件名,Position是偏移量,binlog_do_db是要复制数据库名称。
- 从机使用一系列命令进行主机的复制:
#停止复制
stop slave;
#重新设置master
reset master;
#这五个命令复制一起执行
#设置master节点的ip
CHANGE MASTER TO MASTER_HOST='192.168.18.142',
#设置登录用户,就是各个创建的专门用于主从复制的用户
MASTER_USER='slave',
#密码
MASTER_PASSWORD='abc123456',
#binlog文件名,上面的查看状态时的文件名
MASTER_LOG_FILE='mysql-bin.000001',
#偏移量
MASTER_LOG_POS=438;
#开始主从复制
start slave;
#查看状态
show slave status\G;
看到红框中的两项为yes,就证明成功。
- 验证:
主机创建数据库producer,也就是主从复制的库。
然后从机查看是否复制。
复制成功。
主机创建表。
查看从机:
复制成功。
主机新增数据:
查看从机:
成功。
搭建成功。
双主双从
如果是一主一从的架构,一旦主机宕机了,就无法对外提供写服务了,所以可以使用双主双从的架构,一个主机是另外一个主机的备机,一旦主机宕机,备机就会切换成主机。
原理:
主机M1,备用主机M2,S1是M1的从机,S2是M2的从机。备机跟主机之间也会互相复制,已达到主备切换时数据的完整性。
搭建:(是在上面的一主一从基础上搭建)
- 新增一台从机,配置不用改。也就是两台从机,但是server-id不能重复。
- 修改主机的配置:
在上面主机基础上新增三个配置:
#主机会作为另一个主机的从机,在这个时候,也要开启复制。
log-slave-updates
#表示自增字段的步长,如果是2,并且开始值是1,就会1、3、5这样自增
auto-increment-increment=2
#自增字段起始值,设置这两个配置的目的是为了避免主备双写时id冲突
auto-increment-offset=1
备用主机M2跟M1大部分相同,以下列出不同项:
server-id=3
#自增字段起始值,设置这两个配置的目的是为了避免主备双写时id冲突
#m1是1,m2是2,这样就不会导致冲突。
auto-increment-offset=2
- 重启主备服务器。备主机m2添加一个可供从机复制的账号,跟上面m1的添加方式一样。
- 配置从机s2,与s1配置一样,只是server-id要唯一。
- 重启两台从机,两台从机使用stop slave;reset master命令停止复制。并且先删除数据库producer,因为等下要对producer库进行主从复制操作,并且要重新配置接入点。
- 查看两台主机的master状态:
s1复制m1.
CHANGE MASTER TO MASTER_HOST='192.168.18.142',
MASTER_PORT=3306,
MASTER_USER='slave',
MASTER_PASSWORD='abc123456',
MASTER_LOG_FILE='mysql-bin.000003',
MASTER_LOG_POS=328;
#执行完上面执行这个
start slave;
s2复制m2:
CHANGE MASTER TO MASTER_HOST='192.168.18.145',
MASTER_PORT=3306,
MASTER_USER='slave',
MASTER_PASSWORD='abc123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=443;
#执行完上面执行这个
start slave;
查看两台从机状态,看到上面红框,就表示复制成功。
7. m1复制m2,m2复制m1,就是这两台主机要互为主从。
两台主机先执行stop slave;reset master;这两个命令。
先查看此时的两台主机的状态:
然后
m1,也就是142执行下面:
CHANGE MASTER TO MASTER_HOST='192.168.18.145',
MASTER_PORT=3306,
MASTER_USER='slave',
MASTER_PASSWORD='abc123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
start slave;
然后m2,也就是145,执行下面:
CHANGE MASTER TO MASTER_HOST='192.168.18.142',
MASTER_PORT=3306,
MASTER_USER='slave',
MASTER_PASSWORD='abc123456',
MASTER_LOG_FILE='mysql-bin.000001',
MASTER_LOG_POS=154;
start slave;
然后查看两台主机的slave状态:
注意那些文件名,偏移量,ip,端口要看自身具体。
此时搭建成功,验证:
主机m1上创建数据库producer。
查看其他三台是否同步。
这里就只贴一台了。实际上一台备机、2台从机都复制了。
创建表:
查看其他主机:也都有了。
插入数据:
查看其他主机:
插入两条,并且自增是1、3,符合上面m1的配置。m2插入两条数据:
其他查看:
emmm5.7好像已经解决了冲突问题了.
至此,搭建完毕。