我们在平时工作中,使用最多的数据库就是 MySQL 了,随着业务的增加,如果单单靠一台服务器的话,负载过重,就容易造成宕机。
这样我们保存在 MySQL 数据库的数据就会丢失,那么该怎么解决呢?
其实在 MySQL 本身就自带有一个主从复制的功能,可以帮助我们实现负载均衡和读写分离。
对于主服务器(Master)来说,主要负责写,从服务器(Slave)主要负责读,这样的话,就会大大减轻压力,从而提高效率。
接下来,跟着小羽一起来看看它都有哪些核心知识点呢:
随着业务的增长,一台数据服务器已经满足不了需求了,负载过重。这个时候就需要减压了,实现负载均衡读写分离,一主一丛或一主多从。
主服务器只负责写,而从服务器只负责读,从而提高了效率减轻压力。
主从复制可以分为:
一主一从和一主多从是我们现在见的最多的主从架构,使用起来简单有效,不仅可以实现 HA,而且还能读写分离,进而提升集群的并发能力。
多主一从可以将多个 MySQL 数据库备份到一台存储性能比较好的服务器上。
双主复制,也就是可以互做主从复制,每个 master 既是 master,又是另外一台服务器的 salve。这样任何一方所做的变更,都会通过复制应用到另外一方的数据库中。
级联复制模式下,部分 slave 的数据同步不连接主节点,而是连接从节点。
因为如果主节点有太多的从节点,就会损耗一部分性能用于 replication ,那么我们可以让 3~5 个从节点连接主节点,其它从节点作为二级或者三级与从节点连接,这样不仅可以缓解主节点的压力,并且对数据一致性没有负面影响。
MySQL 主从复制是基于主服务器在二进制日志跟踪所有对数据库的更改。因此,要进行复制,必须在主服务器上启用二进制日志。
每个从服务器从主服务器接收已经记录到日志的数据。当一个从服务器连接到主服务器时,它通知主服务器从服务器日志中读取最后一个更新成功的位置。
从服务器接收从那时发生起的任何更新,并在主机上执行相同的更新。然后封锁等待主服务器通知的更新。
从服务器执行备份不会干扰主服务器,在备份过程中主服务器可以继续处理更新。
MySQL 的主从复制工作过程大致如下:
MySQL 建立请求的主从的详细流程如下:
一个主库,一个或多个从库,数据异步同步到从库。
这种模式下,主节点不会主动推送数据到从节点,主库在执行完客户端提交的事务后会立即将结果返给给客户端,并不关心从库是否已经接收并处理。
这样就会有一个问题,主节点如果崩溃掉了,此时主节点上已经提交的事务可能并没有传到从节点上,如果此时,强行将从提升为主,可能导致新主节点上的数据不完整。
在 MySQL cluster 中特有的复制方式。
当主库执行完一个事务,然后所有的从库都复制了该事务并成功执行完才返回成功信息给客户端。
因为需要等待所有从库执行完该事务才能返回成功信息,所以全同步复制的性能必然会收到严重的影响。
在异步复制的基础上,确保任何一个主库上的事物在提交之前至少有一个从库已经收到该事物并日志记录下来。
介于异步复制和全同步复制之间,主库在执行完客户端提交的事务后不是立刻返回给客户端,而是等待至少一个从库接收到并写到relay log 中才返回成功信息给客户端(只能保证主库的 Binlog 至少传输到了一个从节点上),否则需要等待直到超时时间然后切换成异步模式再提交。
相对于异步复制,半同步复制提高了数据的安全性,一定程度的保证了数据能成功备份到从库,同时它也造成了一定程度的延迟,但是比全同步模式延迟要低,这个延迟最少是一个 TCP/IP 往返的时间。所以,半同步复制最好在低延时的网络中使用。
半同步模式不是 MySQL 内置的,从MySQL 5.5开始集成,需要 master 和 slave 安装插件开启半同步模式。
在异步复制的基础上,人为设定主库和从库的数据同步延迟时间,即保证数据延迟至少是这个参数。
MySQL 主从复制支持两种不同的日志格式,这两种日志格式也对应了各自的复制方式。当然也有二者相结合的混合类型复制。
基于语句的复制相当于逻辑复制,即二进制日志中记录了操作的语句,通过这些语句在从数据库中重放来实现复制。
这种方式简单,二进制文件小,传输带宽占用小。但是基于语句更新依赖于其它因素,比如插入数据时利用了时间戳。
因此在开发当中,我们应该尽量将业务逻辑逻辑放在代码层,而不应该放在 MySQL 中,不易拓展。
特点:
基于行的复制相当于物理复制,即二进制日志中记录的实际更新数据的每一行。
这样导致复制的压力比较大,日志占用的空间大,传输带宽占用大。但是这种方式比基于语句的复制要更加精确。
特点:
一般情况下,默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。
配置主要要点如下:
# 如果在双主复制结构中没有设置ID的话就会导致循环同步问题
server_id=1
# 即日志中记录的是语句还是行更新或者是混合
binlog_format=mixed
# 在进行n次事务提交以后,Mysql将执行一次fsync的磁盘同步指令。将缓冲区数据刷新到磁盘。
# 为0的话由Mysql自己控制频率。
sync_binlog=n
# 为0的话,log buffer将每秒一次地写入log file中并且刷新到磁盘。
# mysqld进程崩溃会丢失一秒内的所有事务。
# 为1的话,每次事务log buffer会写入log file并刷新到磁盘。(较为安全)
# 在崩溃的时候,仅会丢失一个事务。
# 为2的话,每次事务log buffer会写入log file,但一秒一次刷新到磁盘
innodb_flush_logs_at_trx_commit=0
# 阻止从库崩溃后自动启动复制,给一些时间来修复可能的问题,
# 崩溃后再自动复制可能会导致更多的问题。并且本身就是不一致的
skip_slave_start=1
# 是否将从库同步的事件也记录到从库自身的bin-log中
# 允许备库将重放的事件也记录到自身的二进制日志中去,可以将备库当做另外一台主库的从库
log_slave_update
# 日志过期删除时间,延迟严重的话会导致日志文件占用磁盘
expire_logs_days=7
当主库的 TPS 并发较高的时候,由于主库上面是多线程写入的,而从库的SQL线程是单线程的,导致从库SQL可能会跟不上主库的处理速度。
解决方法:
当主库宕机后,数据可能丢失。
解决方法:
使用半同步复制,可以解决数据丢失的问题。
MySQL 需要注意以下事项:
主从复制带来了很多好处,当我们的主服务器出现问题,可以切换到从服务器;可以进行数据库层面的读写分离;可以在从数据库上进行日常备份。还可以保证:
MySQL 主从复制集群功能使得 MySQL 数据库支持大规模高并发读写成为可能,同时有效地保护了物理服务器宕机场景的数据备份。
将工作负载分发到各 Slave 节点上,从而提高系统性能。
在这个场景下,所有的写(write)和更新(update)操作都在 Master 节点上完成;所有的读( read)操作都在 Slave 节点上完成。通过增加更多的 Slave 节点,便能提高系统的读取速度。
数据从 Master 节点复制到 Slave 节点上,在 Slave 节点上可以暂停复制进程。可以在 Slave 节点上备份与 Master 节点对应的数据,而不用影响 Master 节点的运行。
实时数据可以在 Master 节点上创建,而分析这些数据可以在 Slave 节点上进行,并且不会对 Master 节点的性能产生影响。
可以利用复制在远程主机上创建一份本地数据的副本,而不用持久的与Master节点连接。
可以把几个不同的从服务器,根据公司的业务进行拆分。通过拆分可以帮助减轻主服务器的压力,还可以使数据库对外部用户浏览、内部用户业务处理及 DBA 人员的备份等互不影响。