在企业应用中,成熟的业务通常数据量都比较大
单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求
配置多台主从数据库服务器以实现读写分离
所以要做主从服务器,保证安全性
做一写一读服务器,将提升性能
1、什么是读写分离
读写分离,基本的原理是让主数据库处理事务性增、改、删操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。
2、什么时候要读写分离
数据库不一定要读写分离,如果程序使用数据库较多时,而更新少,查询多的情况下会考虑使用。利用数据库主从同步,再通过读写分离可以分担数据库压力,提高性能。
3、主从复制与读写分离
在实际的生产环境中,数据库服务器进行读和写,是不能满足实际需求的。无论是在安全性、高可用性还是高并发等各个方面都是完全不能满足实际需求的。因此,通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。有点类似于rsync,但是不同的是rsync是对磁盘文件做备份,而mysql主从复制是对数据库中的数据、语句做备份。
主从复制的目的:把在主服务器上输入的同步给从服务器mysql
读写分离的目的:在主服务器上写,在从服务器上读,提高性能
4、mysql支持的复制类型
(1)STATEMENT:基于语句的复制。在服务器上执行sql语句,在从服务器上执行同样的语句,优点:mysql默认采用基于语句的复制,执行效率高。缺点:在高并发情况下,命令顺序会混乱,导致主从服务器的数据不一致
(2)ROW:基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍。优点:精确性高,缺点:效率慢,占用空间大
(3)MIXED:混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制。
5、主从复制的工作过程
-
master(Binlog dump thread)
-
slave(I/O thread 、SQL thread)
-
Master 的一条线程
-
Slave 中的两条线程
(1)Master节点将数据的改变记录成二进制日志(bin log),当Master上的数据发生改变时,则将其改变写入二进制日志中。
(2)Slave节点会在一定时间间隔内对Master的二进制日志进行探测其是否发生改变,如果发生改变,则开始一个I/O线程请求 Master的二进制事件。
(3)同时Master节点为每个I/O线程启动一个dump线程,用于向其发送二进制事件,并保存至Slave节点本地的中继日志(Relay log)中,Slave节点将启动SQL线程从中继日志中读取二进制日志,在本地重放,即解析成 sql 语句逐一执行,使得其数据和 Master节点的保持一致,最后I/O线程和SQL线程将进入睡眠状态,等待下一次被唤醒。
7.搭建 MySQL主从复制
1.主从服务器时间同步
bash
yum install ntp -y
# 安装ntp
vim /etc/ntp.conf
# 修改ntp配置文件,在最后添加
server 127.127.80.0
#设置本地是时钟源,注意修改网段
fudge 127.127.80.0 stratum 8
#设置时间层级为8(限制在15内)
service ntpd start
# 启动时间同步
bash
yum install ntp ntpdate -y
# 从服务器安装
service ntpd start
/usr/sbin/ntpdate 192.168.64.10
# 和主服务器进行时间同步
crontab -e
# 设置定时任务
*/30 * * * * /usr/sbin/ntpdate 192.168.64.10
# 每半小时执行一次时间同步
2.主服务器的mysql配置
bash
vim /etc/my.cnf
# 在server-id=1下添加
log-bin=mysql-bin #添加,主服务器开启二进制日志
binlog_format=mixed
#选配项
expire_logs_days=7 #设置二进制日志文件过期时间,默认值为0,表示logs不过期
max_binlog_size=500M #设置二进制日志限制大小,如果超出给定值,日志就会发生滚 动,默认值是1GB
skip_slave_start=1 #阻止从库崩溃后自动启动复制,崩溃后再自动复制可能会导致数 据不一致的
"双1设置",数据写入最安全
innodb_flush_logs_at_trx_commit=1
#redo log(事务日志)的刷盘策略,每次事务提交时MySQL都会 把事务日志缓存区的数据写入日志文件中,并且刷新到磁盘中, 该模式为系统默认
sync_binlog=1 #在进行每1次事务提交(写入二进制日志)以后,Mysql将执行 一次fsync的磁盘同步指令,将缓冲区数据刷新到磁盘
bash
systemctl restart mysqld
mysql -u root -pabc123
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.64.%' IDENTIFIED BY '123456'; # 创建用户供服务器登录
FLUSH PRIVILEGES;
3.从服务器的mysql配置
bash
vim /etc/my.cnf
server-id = 2
#修改,注意id与Master的不同,两个Slave的id也要不同
relay-log=relay-log-bin
#开启中继日志,从主服务器上同步日志文件记录到本地
relay-log-index=relay-log-bin.index
#定义中继日志文件的位置和名称,一般和relay-log在同一目录
bash
systemctl restart mysqld
mysql -u root -pabc123
CHANGE master to master_host='192.168.64.10',master_user='myslave',master_password='123456',master_log_file='mysql-bin.000001',master_log_pos=451;
#配置同步,注意 master_log_file 和 master_log_pos 的值要与Master查询的一致
bash
start slave; #启动同步,如有报错执行 reset slave;
show slave status\G #查看 Slave 状态
延迟的产生
当主库的TPS并发较高时,由于主库上面是多线程写入的,而从库的SQL线程是单线程的,导致从库SQL可能会跟不上主库的处理速度(生产者比消费者快,导致商品堆积)。