MySQL主从复制读写分离

MySQL主从复制读写分离

MySQL使用主从复制与读写分离的原因

1、在企业应用中,成熟的业务通常数据量都比较大
2、单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求
(myisam基于表级锁定;innodb基于行级锁定 --存储引擎不能满足并发读、写的需求)
3、配置多台主从数据库服务器以实现读写分离

MySQL主从复制原理

  • MySQL的复制类型

1.基于语句的复制
2.基于行的复制
3.混合类型的复制(语句、行、日志文件)

  • MySQL读写分离原理

1、只在主服务器上写,只在从服务器上读
2、主数据库处理事务性查询,从数据库处理select查询
3、数据库复制用于将事务性查询的变更同步到集群中的从数据库
4、复制的基本过程如下:

① Master将用户对数据库更新的操作以二进制格式保存到Binary Log日志文件中
② Slave上面的IO进程连接上Master,并请求从指定日志文件的指定位置(或者从最开始的日志)之后的日志内容
③ Master接收来自Slave的IO进程的请求后,通过负责复制的IO进程根据请求信息读取制定日志指定位置之后的日志信息,返回给Slave的IO进程。返回信息中除了日志所包含的信息之外,还包括本次返回的信息已经到Master端的bin-log文件的名称以及bin-log的位置
④ Slave的IO进程接收到信息后,将接收到的日志内容依次添加到Slave端的relay-log文件的最末端,并将读取到的Master端的bin-log的文件名和位置记录到master-info文件中,以便在下一次读取的时候能够清除的告诉Master“我需要从某个bin-log的哪个位置开始往后的日志内容,请发给我”
⑤ SlaveSql进程检测到relay-log中新增了内容后,会马上解析relay-log的内容称为在Master端真实执行时候的那些可执行的内容,并在自身执行

部署MySQL主从复制读写分离

环境

主库:20.0.0.15
从库:20.0.0.13  20.0.0.14
amoeba:20.0.0.11
客户机:20.0.0.10

必须先保持时间同步
这里先做个简单的时间同步

所有机器都写
ntpdate ntp.aliyun.com
  • 主库
[root@glt6 ~]# vi /etc/my.cnf

server-id = 1 #服务器id,每个服务器不能相同
log_bin=master-bin  #主服务器日志文件
log_slave_updates=true  #允许中继日志读取主服务器的二进制日志

[root@glt6 ~]# systemctl restart mysqld.service 
[root@glt6 ~]# ls /usr/local/mysql/data/ #查看生成的二进制日志文件
[root@glt6 ~]# ls /usr/local/mysql/data/
aaa       ggg             ibdata1      ib_logfile1  master-bin.000001  mysql               sys
auto.cnf  ib_buffer_pool  ib_logfile0  ibtmp1       master-bin.index   performance_schema
[root@glt6 ~]#  mysql -uroot -p123456
mysql> grant replication slave on *.* to 'myslave'@'20.0.0.%' identified by '123456'; #为所有服务器所有库授权
mysql> flush privileges; #更新权限
mysql> show grants for 'myslave'@'20.0.0.%'; 
+--------------------------------------------------------+
| Grants for myslave@20.0.0.%                            |
+--------------------------------------------------------+
| GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'20.0.0.%' |
+--------------------------------------------------------+


mysql> show master status;
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |     2169 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
  • 从库(20.0.0.13 20.0.0.14)
[root@glt4 ~]# vi /etc/my.cnf

server-id = 2  #三台数据库id不同
relay_log=relay-log-bin #从主服务器上同步日志文件记录到本地中继日志
relay_log_index=slave-relay-bin.index #定义中继日志的索引
systemctl restart mysqld.service 
[root@glt4 ~]# mysql -uroot -p123456
mysql> change master to master_host='20.0.0.15',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=2169;
mysql> start slave; #启动从服务器
mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 20.0.0.15
                  Master_User: myslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: master-bin.000001
          Read_Master_Log_Pos: 2169
               Relay_Log_File: relay-log-bin.000004
                Relay_Log_Pos: 588
        Relay_Master_Log_File: master-bin.000001
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
              Replicate_Do_DB: 
  • 读写分离(amoeba服务器)
[root@amoeba ~]# tar zxvf jdk-8u91-linux-x64.tar.gz
[root@amoeba ~]# mv jdk1.8.0_91/ /usr/local/java
[root@amoeba ~]# vi /etc/profile.d/java.sh #环境文件最后添加
export JAVA_HOME=/usr/local/java #设置java根目录
export PATH=$PATH:$JAVA_HOME/bin #在PATH环境变量中添加JAVA根目录下的bin子目录

[root@server1 ~]# source /etc/profile.d/java.sh 
[root@server1 ~]# echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/usr/local/java/bin
[root@server1 ~]# 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)

unzip amoeba-mysql-3.0.5-RC-distribution.zip 
mv amoeba-mysql-3.0.5-RC/ /usr/local/amoeba
chmod -R 755 /usr/local/amoeba/
vim /usr/local/amoeba/jvm.properties 
32	#JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize    =16m -XX:MaxPermSize=96m"
33	JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k"
  • 在三台MySQL上给amoeba授权
mysql> grant all on *.* to 'test'@'20.0.0.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.01 sec)
  • 修改amoeba主配置文件
root@amoeba ~]# vi /usr/local/amoeba/conf/amoeba.xml 
28	<property name="user">amoeba</property> #修改root为amoeba
30	<property name="password">123456</property> #添加数据库登陆密码
83                 <property name="defaultPool">master</property> #修改multiPool为master
85                 <!-- #注释,需删除
86                 <property name="writePool">master</property> #主库写权限
87                 <property name="readPool">slaves</property> #从库读权限
88                 --> #注释,需删除
  • 修改dbServers.xml 文件
root@amoeba ~]# vi /usr/local/amoeba/conf/dbServers.xml
22                         <!-- mysql schema --> #注释行
 23                         <property name="schema">mysql</property> #MySQL5.7版本没有默认的test库,所以修改为mysql(5.7默认的数据库)
 24 
 25                         <!-- mysql user --> #注释行
 26                         <property name="user">test</property>
 27                         <!-- mysql password --> #注释行
 28                         <property name="password">123456</property>
#配置三台MySQL服务器主机名和地址
 43         <dbServer name="master"  parent="abstractServer"> #修改server1为master
 44                 <factoryConfig>
 45                         <!-- mysql ip -->
 46                         <property name="ipAddress">20.0.0.11</property> #修改为主库master的IP地址
 47                 </factoryConfig>
 48         </dbServer>
 49 
 50         <dbServer name="slave1"  parent="abstractServer"> #修改为slave1
 51                 <factoryConfig>
 52                         <!-- mysql ip -->
 53                         <property name="ipAddress">20.0.0.12</property> #修改为从库1IP
 54                 </factoryConfig>
 #添加下面slave2模块
 
  <dbServer name="slave2"  parent="abstractServer"> 
                   <factoryConfig>
                           <!-- mysql ip -->
                            <property name="ipAddress">20.0.0.13</property>
                    </factoryConfig>

 57         <dbServer name="slaves" virtual="true">
 58                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
 59                         <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
 60                         <property name="loadbalance">1</property>
 61 
 62                         <!-- Separated by commas,such as: server1,server2,server1 -->
 63                         <property name="poolNames">slave1,slave2</property> #修改为slave1,slave2
 64                 </poolConfig>
 65         </dbServer>

/usr/local/amoeba/bin/launcher #启动anoeba
 at com.meidusa.toolkit.net.util.LoopingThread.run(LoopingThread.java:59)
 2021-01-04 21:59:09 [INFO] Project Name=Amoeba-MySQL, PID=5003 , System shutdown ....
^C
netstat -anpt | grep 8066
tcp6       0      0 :::8066                 :::*                    LISTEN      4622/java  
  • 客户机验证

[root@client1 ~]# mysql -uamoeba -p123456 -h 20.0.0.11 -P8066

MySQL [(none)]>
  • 主库
mysql> create database ggg;
mysql> use ggg;
Database changed
mysql> create table aaa(id int(2), name char(32), age int(3));
  • 从库
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| aaa                |
| ggg                |
| mysql              |
| performance_schema |
| sys                |
+--------------------+

mysql> use ggg;
Database changed
mysql> show tables;
+---------------+
| Tables_in_ggg |
+---------------+
| aaa           |
+---------------+
  • 从库2 上一样效果

  • 从库1关闭服务

mysql> stop slave;
  • 主库添加数据
mysql> insert into aaa values(1,'zhangsan',33);
mysql> select * from aaa;
Empty set (0.00 sec)
重启服务
mysql> start slave;
Query OK, 0 rows affected (0.00 sec)
mysql> select * from aaa;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   33 |
+------+----------+------+
#数据将会显示
  • 关闭两台从库服务
    mysql> stop slave;
  • 向从库中写数据
#从库1
mysql> insert into aaa values(2,'lisi',20);

#从库2
mysql> insert into aaa values(3,'jiuer',22);
其中主库不会显示  只有从库会显示
  • 客户端查看数据库
MySQL [ggg]> select * from aaa
    -> ;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   33 |
|    3 | jiuer    |   22 |
+------+----------+------+

MySQL [ggg]> select * from aaa;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   33 |
|    2 | lisi     |   20 |
+------+----------+------+

#发现访问的数据为轮询机制
  • 在客户端上写入数据
MySQL [ggg]> insert into aaa values(4,'zhaosi',22);

只有主库会记录

mysql> select * from aaa;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   33 |
|    4 | zhaosi   |   22 |
+------+----------+------+

开启同步
从库1


mysql> start slave;
mysql> select * from aaa;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   33 |
|    3 | jiuer    |   22 |
|    4 | zhaosi   |   22 |
+------+----------+------+
从库2
mysql> select * from aaa;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   33 |
|    2 | lisi     |   20 |
|    4 | zhaosi   |   22 |
+------+----------+------+

**在开启同步后,主服务器上的数据会同步到各从服务器上中,但从服务器上的自己增加的数据不会同步,只会本地保存**
  • 客户端访问依然保持轮询

MySQL [ggg]> select * from aaa;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   33 |
|    2 | lisi     |   20 |
|    4 | zhaosi   |   22 |
+------+----------+------+

MySQL [ggg]> select * from aaa;
+------+----------+------+
| id   | name     | age  |
+------+----------+------+
|    1 | zhangsan |   33 |
|    3 | jiuer    |   22 |
|    4 | zhaosi   |   22 |
+------+----------+------+
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值