学习MySQL之主从复制与读写分离一篇就够了!(数据库并发能力的提升)
Posted 分享录
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学习MySQL之主从复制与读写分离一篇就够了!(数据库并发能力的提升)相关的知识,希望对你有一定的参考价值。
在实际的生产环境中,如果对mysql数据库的读和写都在一台数据库服务器中操作,无论是在安全性、高可用性,还是高并发等各个方面都是不能满足实际需求的。因此,一般通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。
文章目录
一、主从复制
1.11:MySQL的复制类型
1.12:主从复制的作用
1.1:MySQL主从复制原理
1.2:MySQL主从复制的工作过程
二:项目搭建:MySQL主从复制搭建
2.11:主服务器
2.12:从服务器:
2.1:设置时间同步
二、修改服务器的配置
2.1:主服务器:
2.2:从服务器:
2.3、效果验证
三:MySQL之读写分离
3.1:读写分离的概述
3.2:读写分离的基本原理
3.3:怎么实现读写分离?
3.4:MySQL读写分离原理
3.5:MySQL读写能提高系统性能的原因:
四:MySQL读写分离搭建
4.41:读写分离
4.31:在master新建库和表
4.32:在两台从服务器上看是否有库及表生成
4.33:两台从服务器停止服务
4.21服务器授权
4.21:Amoeba的配置
4.22:安装amoeba
4.1:配置amobeba服务器(192.168.158.20)
4.2:项目操作
4.3:客户机登录测试
4.4:在主服务上插入内容不会同步(通过amoeba操作)
本次项目压缩包
一、主从复制
将主数据库中的DDL和DML操作通过二进制日志(BINLOG)传输到从数据库上,然后将这些日志重新执行(重做);从而使得从数据库的数据与主数据库保持一致。
1.1:MySQL主从复制原理
1.11:MySQL的复制类型
基于语句的复制
在主服务器上执行的语句,从服务器执行同样的语句。
基于行的复制
把改变的内容复制到从服务器。混合类型的复制
一旦发现基于语句无法精确复制时,就会采取基于行的复制。
1.12:主从复制的作用
主数据库出现的问题,可以切换到从数据库
可以进行数据层层面的读写分离
可以在从数据库上进行日程备份
1.2:MySQL主从复制的工作过程
Binary log:主数据库的二进制日志
Relay log:从服务器的中继日志
第一步:master在每个事务更新数据完成之前,将该操作记录串行地写入到binlog文件中。
第二步:salve开启一个I/OThread,该线程在master打开一个普通连接,主要工作是binlog dumpprocess。如果读取的进度已经跟上了master,就进入睡眠状态并等master产生新的事件。I/O线程最终的目的是将这些事件写入到中继日志中。
第三步:SQL Thread会读取中继日志,并顺序执行该日志中的SQL事件,从而与主数据库中的数据保持一致。
二:项目搭建:MySQL主从复制搭建
主服务器master | 从服务器slave |
---|---|
192.168.158.10 | 192.168.158.30 |
2.1:设置时间同步
2.11:主服务器
安装时间功能
[root@server1 ~]# yum -y install ntp
修改时间服务的配置文件
[root@server1 ~]# vim /etc/ntp.conf
#合适位置插入
server 127.127.1.0 //本地是时钟源 fudge
127.127.1.0 stratum 8 //设置时间层级为8
1
2
3
4
5
6
7
开启服务,并关闭防火墙
[root@server1 ~]# systemctl stop firewalld
[root@server1 ~]# setenforce 0
1
2
2.12:从服务器:
安装ntp包
[root@server3 ~]# yum -y install ntp ntpdate
1
开启服务,并关闭防火墙
[root@server3 ~]# systemctl start ntpd
[root@server3 ~]# systemctl stop firewalld
[root@server3 ~]# setenforce 0
1
2
3
进行时间同步
[root@server3 ~]# /usr/sbin/ntpdate 192.168.158.10 #主服务器地址
26 Oct 20:53:39 ntpdate[76504]: the NTP socket is in use, exiting
1
2
二、修改服务器的配置
2.1:主服务器:
mysql主服务器配置
vim /etc/my.cnf
server-id = 11 //指定id号,服务器的唯一标识,不能相同
log-bin=master-bin //主服务器日志文件
log-slave-updates=true //从服务器更新二进制日志
1
2
3
4
重启服务
[root@server1 ~]# systemctl restart mysqld
1
登录数据库,给从服务器授权
[root@server1 ~]# mysql -u root -pabc123
mysql> GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.158.%' IDENTIFIED BY '123123'; #授权从服务器访问主服务器
Query OK, 0 rows affected, 1 warning (0.01 sec)
mysql> flush privileges; #刷新权限列表
Query OK, 0 rows affected (0.01 sec)
mysql> show master status; #查看主服务器状态
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 864 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
#File和Position这两个值在后面配置从服务器的时候会用到,slave应从该点在master上进行新的更新
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
2.2:从服务器:
修改配置文件
[root@server3 ~]# vi /etc/my.cnf
server-id = 22
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
1
2
3
4
重启服务
[root@server3 ~]# systemctl restart mysqld
1
登录数据库,配置同步
[root@server3 ~]# mysql -u root -pabc123 #登录数据库
mysql: [Warning] Using a password on the command line interface can be insecure.
Welcome to the MySQL monitor. Commands end with ; or g.
Your MySQL connection id is 3
Server version: 5.7.20 Source distribution
Copyright (c) 2000, 2017, Oracle and/or its affiliates. All rights reserved.
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
Type 'help;' or 'h' for help. Type 'c' to clear the current input statement.
mysql> change master to master_host='192.168.158.10',master_user='myslave',master_password='123123',master_log_file='master-bin.000001',master_log_pos=864; #配置同步
Query OK, 0 rows affected, 2 warnings (0.02 sec)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
start slave; //开启从服务
show slave statusG; //查看状态
Slave_IO_Running:连接到主库,并读取主库的日志到本地,生成本地日志文件
Slave_SQL_Running:读取本地日志文件,并执行日志里的SQL命令。
1
2
3
4
2.3、效果验证
在主服务器上新建一个数据库,查看从服务器上是否有 test 库
从服务器验证
三:MySQL之读写分离
3.1:读写分离的概述
读写分离是高性能数据库集群的一种方式,其本质是将访问压力分散到集群中的多个节点,但是没有分散存储压力。
业务服务器将写操作发给数据库主机,将读操作发给数据库从机通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力。
3.2:读写分离的基本原理
数据库服务器搭建主从集群,一主一从、一主多从都可以。
数据库主机负责读写操作,从机只负责读操作。
数据库主机通过复制将数据同步到从机,每台数据库服务器都存储了所有的业务数据。
3.3:怎么实现读写分离?
实现MySQL读写分离的前提是我们已经将MySQL主从复制配置完毕
Mysql读写分离基本原理是让master数据库处理操作,slave数据库处理读操作。master将写操作的变更同步到各个slave节点。
3.4:MySQL读写分离原理
读写分离就是只在主服务器上写,只在从服务器上读
主数据库处理事务性査询,而从数据库处理 select査询
数据库复制被用来把事务性査询导致的变更同步到集群中的从数据库
3.5:MySQL读写能提高系统性能的原因:
物理服务器增加,机器处理能力提升,拿硬件换性能。
master直接写的是并发的,slave通过主库发来的binlog恢复是异步
salve可以单独设置一些参数来提升其读的性能
增加冗余,提高可用性
四:MySQL读写分离搭建
4.1:配置amobeba服务器(192.168.158.20)
读写分离安装java环境(amoeba软件基于java平台运行)
关闭防火墙
读写分离是在主从复制的基础上进行配置的,所以先搭建主从复制再搭建读写分离。
准备5 台centos7虚拟机,其中三台搭建 Mysql服务器(一台为主服务器,其余两台为从服务器)
一台虚拟机用来做 Amoeba,实现读写分离。
一台做应用客户端,进行操作验证。
服务器 | 地址 |
---|---|
主服务器master | 192.168.158.10 |
从服务器slave1 | 192.168.158.30 |
从服务器slave2 | 192.168.158.40 |
Amoeba服务器 | 192.168.158.20 |
客户机 | 192.168.158.50 |
4.2:项目操作
4.21服务器授权
#每台服务器都如此操作
mysql> grant all privileges on *.* to 'test'@'192.168.158.%' identified by 'abc123';
mysql> show grants for test@'192.168.158.%';
mysql> flush privileges;
1
2
3
4
4.21:Amoeba的配置
1、关闭防火墙,挂载本地共享文件夹,把 jdk 安装包放在 /usr/local目录下
[root@server2 ~]# tar zxf jdk-8u91-linux-x64.tar.gz
[root@server2 ~]# mv jdk1.8.0_91/ /usr/local/java
[root@server2 ~]# vi /etc/profile
#末行添加
export JAVA_HOME=/usr/local/java
export JRE_HOME=/usr/local/java/jre
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$JAVA_HOME/bin:$AMOEBA_HOME/bin
1
2
3
4
5
6
7
8
[root@server2 ~]# source /etc/profile
[root@server2 ~]# java -version
openjdk version "1.8.0_131"
OpenJDK Runtime Environment (build 1.8.0_131-b12)
OpenJDK 64-Bit Server VM (build 25.131-b12, mixed mode)
1
2
3
4
5
4.22:安装amoeba
[root@server2 ~]# unzip amoeba-mysql-3.0.5-RC-distribution.zip
[root@server2 ~]# mv amoeba-mysql-3.0.5-RC /usr/local/amoeba
[root@server2 ~]# chmod -R 755 /usr/local/amoeba/
[root@server2 ~]vi /usr/local/amoeba/jvm.properties
#JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize=16m -XX:MaxPermSize=96m" #添加注释
JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k" #添加此行
1
2
3
4
5
6
[root@server2 ~]# cd /usr/local/amoeba/bin/
[root@server2 bin]# launcher
[root@server2 bin]# netstat -anpt | grep 8066
1
2
3
vi /usr/local/amoeba/conf/amoeba.xml
<property name="user">test</property> #28行修改
<property name="password">123456</property> #30行修改
······
</property>
<property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property>
<property name="LRUMapSize">1500</property>
<property name="defaultPool">master</property> #修改
<property name="writePool">master</property> #修改
<property name="readPool">slaves</property> #修改
<property name="needParse">true</property>
</queryRouter>
1
2
3
4
5
6
7
8
9
10
11
12
vi /usr/local/amoeba/conf/dbServers.xml
<property name="user">test</property> #26行修改
<property name="password">abc123</property> #28行修改
······
<dbServer name="master" parent="abstractServer"> #修改
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.158.10</property> #主服务器ip
</factoryConfig>
</dbServer>
<dbServer name="slave1" parent="abstractServer"> #修改
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.158.30</property> #从服务器1ip
</factoryConfig>
</dbServer>
<dbServer name="slave2" parent="abstractServer"> #修改
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.158.40</property> #从服务器2ip
</factoryConfig>
</dbServer>
<dbServer name="slaves" virtual="true"> #修改
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name="loadbalance">1</property>
<!-- Separated by commas,such as: server1,server2,server1 -->
<property name="poolNames">slave1,slave2</property> #修改
</poolConfig>
</dbServer>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
[root@server2 bin]# cd /usr/local/amoeba/bin/
[root@server2 bin]# launcher
1
2
4.3:客户机登录测试
[root@localhost ~]# yum -y install mariadb*
[root@localhost ~]# systemctl start mariadb
[root@localhost ~]# netstat -anpt | grep 3306
tcp 0 0 0.0.0.0:3306 0.0.0.0:* LISTEN 14846/mysqld
[root@localhost ~]# mysql -utest -p123456 -h 192.168.158.20 -P 8066 #amoeba服务器地址,此处为大写的P
1
2
3
4
5
4.31:在master新建库和表
mysql> create database test;
2 mysql> use test;
3 mysql> create table abc(id int(2) not null primary key, name varchar(48), score char(48));
4 mysql> show tables;
1
2
3
4
4.32:在两台从服务器上看是否有库及表生成
mysql> show databases;
mysql> use test;
mysql> show tables;
mysql> select * from abc;
1
2
3
4
4.33:两台从服务器停止服务
mysql> stop slave;
1
4.4:在主服务上插入内容不会同步(通过amoeba操作)
主服务器
因为停止了同步服务,所以从服务器不会同步到主服务器的内容
mysql> insert into abc values(2,'lisi',89);
1
从服务器
mysql> select * from abc;
#表为空
1
2
4.41:读写分离
以下为读写分离的原理图。
下面在数据库中的操作,为验证读写分离是否成功。
测试读写分离
从服务器1
mysql> insert into abc values(3,'wangwu',60);
mysql> select * from abc;
1
2
从服务器2
mysql> insert into abc values(4,'siri',60);
mysql> select * from abc;
1
2
分别在客户端上测试(第一次在从服务器1写入数据后读数据,第二次在从服务器2写入数据后读数据)
MySQL [test]> select * from abc;
MySQL [test]> select * from abc;
1
2
在通过客户端连接数据库后写入的数据只有主会记录,然后同步给从-从服务器,从而实现读写分离
MySQL [test]> insert into abc values(5,'cc',90); #客户机
mysql> select * from abc; #主
mysql> select * from abc; #从1
mysql> select * from abc; #从2
1
2
3
4
在客户端上看不到新插入的数据,因为同步没有开启,只有主服务器上可以看到数据
MySQL [test]> select * from abc;
MySQL [test]> select * from abc;
1
2
在开启同步后,主服务器上的数据会同步到各从服务器上中,但从服务器上的自己增加的数据不会同步,只有本地保存
#从1
mysql> start slave;
mysql> select * from abc;
#从2
mysql> start slave;
mysql> select * from abc;
客户端:
MySQL [test]> select * from abc;`
1
2
3
4
5
6
7
8
本次项目压缩包
链接: https://pan.baidu.com/s/1xyoaFgd0O1JkblmblwFcxw
提取码: t15y
------------END-----------
更多原创文章请扫描上面(微信内长按可识别)二维码访问我的个人网站(https://www.xubingtao.cn),或者打开我的微信小程序: 可以评论以及在线客服反馈问题,其他平台小程序和APP请访问:https://www.xubingtao.cn/?p=1675。祝大家生活愉快!
以上是关于学习MySQL之主从复制与读写分离一篇就够了!(数据库并发能力的提升)的主要内容,如果未能解决你的问题,请参考以下文章
(转)学会数据库读写分离分表分库——用Mycat,这一篇就够了!
基于 Spring Boot 的 MySQL 实现读写分离,看这篇就够了!