MySQL主从复制与读写分离

目录

MySQL主从复制与读写原理

MySQL支持的复制类型

MySQL主从复制的工作过程

配置MySQL主从复制

配置三台虚拟机安装mysql环境

配置102.103的mysql环境

建立时间同步环境

MySQL主服务器设置

为服务器创建一个账户,便于从服务器从主服务器进行日志进步

从服务器设置

测试主从同步

创建一个新的auth

不想同步把数据写到从服务器当中

在102主机上模拟故障

搭建MySQLD读写分离

MySQL读写分离原理

主机结构

搭建MySQL读写分离

安装JDK

安装amoeba

解压amoeba安装包创建一个目录解压到一个目录下

来到101分别在主、从服务器上授权

配置amoeba配置文件

配置连接后台数据库的文件dbServers

启动amoeba软件


MySQL主从复制与读写原理

MySQL的主从复制和MySQL的读写分离两者有着紧密联系,首先要部署主从复制,只有主从复制完成了,才能在此基础上进行数据的读写分离

MySQL支持的复制类型
  1. 基于语句的复制。在主服务器上执行的SQL语句,在从服务器上执行同样的语句。MySQL默认采用基于语句的复制,效率比较高
  2. 基于行的复制。把改变的内容复制过去,而不是把命令在从服务器上执行一遍
  3. 混合类型的复制。默认采用基于语句的复制,一旦发现基于语句无法精确复制时,就会采用基于行的复制
  4. 全局事务标识符GTID
MySQL主从复制的工作过程

  1. 在每个事务更新完成之前,Master将这些改变记录进二进制日志。写入二进制日志完成后,Master通知存储引擎提交事务
  2. Slave将Master的Binary log复制到其中继日志(Relay log)。首先,Slave开始一个工作线程----I/O线程,I/O线程在Master上打开一个普通的连接,然后开始Binlog dump process。Binlog dump process从Master的二进制日志中读取事件,如果已经跟上Master,它会睡眠并等待Master产生新的事件。I/O线程将这些事件写入中继日志。
  3. SQLslave thread(SQL从线程)处理该过程的最后一步。SQL线程中继日志读取事件,并重放其中的事件而更新Slave数据,将其与Master中的数据保持一致。只要该线程与I/O线程保持一致,中继日志通常会位于OS的缓存中,所以中继日志的开销很小。复制过程有一个很重要的限制,即复制在Slave上是串行化的,也就是说Master上的并行更新操作不能在Selave上并行操作。

配置MySQL主从复制

配置三台虚拟机安装mysql环境

192.168.10.101

192.168.10.102

192.168.10.103

配置102.103的mysql环境
[root@localhost ~]# bash install_mysql5.7.28_bin.sh
[root@localhost ~]# ./install_mysql5.7.28_bin.sh
建立时间同步环境
[root@localhost ~]# yum -y install ntp
[root@localhost ~]# vi /etc/ntp.conf
server 127.127.1.0
fudge 127.127.1.0 stratum 8

[root@localhost ~]#systemctl restart ntpd
[root@localhost ~]#systemctl enable ntpd

在从节点上进行时间同步
[root@localhost ~]# yum -y install ntp
[root@localhost ~]#ntpdate 192.168.10.102
MySQL主服务器设置
[root@localhost ~]# vim /etc/my.cnf
server-id=11
log-bin=master-bin
binlog-format=MIXED
replicate-ignore-db=test
binlog-ignore-db=test
binlog-cache-size=1M
expire-logs-days=3
[root@localhost ~]# systemctl restart mysqld
  1. server-id=11
  • 这个参数指定了MySQL服务器的唯一标识符,用于在复制环境中区分不同的服务器。每个服务器在复制拓扑中必须有唯一的 server-id。
  1. log-bin=master-bin
  • 这个参数启用了二进制日志(Binary Log)。二进制日志记录了所有对MySQL数据库的修改操作,包括数据变更和结构变更。master-bin 是二进制日志文件的基本名称,实际文件名会在后面加上一个序列号。
  1. binlog-format=MIXED
  • 这个参数指定了二进制日志的格式。MIXED 格式是一种混合格式,根据具体的操作来决定使用 STATEMENT、ROW 或 MIXED 格式。不同的格式有不同的优劣,MIXED 格式通常能在大多数情况下提供最佳的性能和兼容性。
  1. replicate-ignore-db=test
  • 这个参数指定了在复制过程中忽略的数据库。在这个例子中,test 数据库中的操作将不会被复制到从服务器上。
  1. binlog-cache-size=1M
  • 这个参数设置了二进制日志缓存的大小。二进制日志缓存用于临时存储写入的日志事件,以提高性能。在这里,缓存大小设置为 1MB。
  1. expire-logs-days=3
  • 这个参数指定了二进制日志文件的过期时间。即在三天后,MySQL会自动删除旧的二进制日志文件,以释放磁盘空间。
  1. log-slave-updates=true
  • 这个参数指定了在从服务器上是否记录复制操作。设置为 true 表示在从服务器上记录复制事件,这对于链式复制和复杂的复制拓扑结构非常有用。
为服务器创建一个账户,便于从服务器从主服务器进行日志进步
[root@localhost ~]# mysql -uroot -ppwd123
mysql> grant replication slave on *.* to 'myslave'@'192.168.10.%' identified by '123456';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;         #更新用户权限值

 mysql> show master status;          #查看主节点的当前状态
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      451 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)

从服务器设置

打开102.103主机点击所有会话设置

[root@localhost ~]# vim /etc/my.cnf           #102设置
server-id=22
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
[root@localhost ~]# systemctl restart mysqld


[root@localhost ~]# vim /etc/my.cnf            #103设置
server-id=33                   
relay-log=relay-log-bin
relay-log-index=slave-relay-bin.index
[root@localhost ~]# systemctl restart mysqld

建立连接写入到102.103中

mysql> change master to master_host='192.168.10.101',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=451;
在服务器上设置到哪里去同步日志文件,使用的账号与密码,以及同步的位置点
mysql> start slave;        #开启从服务器的同步功能
mysql> show slave status\G;

两个线程服务开启,说明已经开始同步

测试主从同步
创建一个新的auth
mysql> create database auth;
mysql> use auth
mysql> show databases;           #到102.103依次去查看是否有auth查询的到
+--------------------+
| Database           |
+--------------------+
| information_schema |
| auth               |
| mysql              |
| performance_schema |
| sys                |
+--------------------+
5 rows in set (0.00 sec)
不想同步把数据写到从服务器当中
101
mysql> create table t1(id int(10),name char(20));
mysql> insert into t1 values(1,'zhangsan');

[root@localhost ~]# vim /etc/my.cnf           #102设置
server-id=22
relay-log=relay-log-bin
replicate-ignore-db=test
relay-log-index=slave-relay-bin.index
[root@localhost ~]# systemctl restart mysqld


mysql> select * from test.t1;
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
+------+----------+



103没设置依旧同步
mysql> select * from test.t1;
+------+----------+
| id   | name     |
+------+----------+
|    1 | zhangsan |
|    1 | zhangsan |
+------+----------+
2 rows in set (0.00 sec)

主服务器可以读可以写

从服务器可以写但不可以读

在102主机上模拟故障
mysql> stop slave;        #只能在关闭的情况下进行修改

搭建MySQLD读写分离

MySQL读写分离原理
  • 只在主服务器上写,只在从服务器上读
  • 主数据库处理事务性查询,从数据库处理SELECT查询
  • 数据库复制用于将事务性查询的变更同步到集群中的从数据库
  • 读写分离方案
  1. 基于程序代码内部实现
  2. 基于中间代理层实现(MySQL-Proxy Amoeba)

主机结构

除了三台服务器,还需要一台amoeba主机作为代理服务器和一台客户端主机作为测试机

这里再打开两台虚拟机,一共就是五台主机

搭建MySQL读写分离

安装JDK

来到104主机

安装这俩个安装包

因为amoeba是java开发的,所以导入amoeba的tar包和jdk的二进制文件

因为他是二进制的文件所以有一个执行权

[root@localhost ~]# chmod +x jdk-6u14-linux-x64.bin
[root@localhost ~]# ./jdk-6u14-linux-x64.bin
Do you agree to the above license terms? [yes or no]
yes
Press Enter to continue.....         #回车继续

将安装的目录移动到 /usr/local 下重命名为jdk1.6

[root@localhost ~]# mv jdk1.6.0_14/ /usr/local/jdk1.6
[root@localhost ~]# vim /etc/profile
export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin

[root@localhost jdk1.6]# source /etc/profile            #重新加载并执行
[root@localhost jdk1.6]# java -version            #查看版本,确认java安装成功
java version "1.6.0_14"
Java(TM) SE Runtime Environment (build 1.6.0_14-b08)
Java HotSpot(TM) 64-Bit Server VM (build 14.0-b16, mixed mode)
安装amoeba
解压amoeba安装包创建一个目录解压到一个目录下
[root@localhost ~]# mkdir /usr/local/amoeba
[root@localhost ~]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@localhost ~]# chmod -R 755 /usr/local/amoeba/
[root@localhost amoeba]# amoeba
amoeba start|stop             #说明可以正常使用
来到101分别在主、从服务器上授权
mysql> grant all on *.* to 'test'@'192.168.10.%' identified by '123.com';
Query OK, 0 rows affected, 1 warning (0.00 sec)
mysql> flush privileges;

配置amoeba配置文件
 [root@localhost conf]# vi amoeba.xml 
 <property name="user">amoeba</property>         #将用户名修改为amoeba给客户端使用 大概在30行

<property name="password">123456</property>
              #将密码修改为123456  #大概在32行 

<property name="defaultPool">master</property>       #改为master大概在115行

<property name="writePool">master</property>       #读的功能给master取消117行注释修改内容
<property name="readPool">slaves</property>           #写的功能给slaves
配置连接后台数据库的文件dbServers
 <!-- mysql schema -->
 <property name="schema">auth</property>           #修改成为你101所创建的库大概在23行
 
 <!-- mysql user -->
 <property name="user">test</property>         #修改为test 就是在101提权上你所设置的参数
 
 <property name="password">123.com</property>             #取消注释大该在28行修改为123.com 
                                                                                                                                                                                                                                                                                                                                                                                                                      
<dbServer name="master"  parent="abstractServer">                  #大概在45行修改成为master
                <factoryConfig>
                        <!-- mysql ip -->
                        <property name="ipAddress">192.168.10.101</property>                #修改端口号
                </factoryConfig>
        </dbServer>

        <dbServer name="slave1"  parent="abstractServer">                  #修改成为slave1
                <factoryConfig>
                        <!-- mysql ip -->
                        <property name="ipAddress">192.168.10.102</property>          #添加端口号
                </factoryConfig>
        </dbServer>
         <dbServer name="slave2"  parent="abstractServer">            #复制上一个修改成为slave2
                <factoryConfig>
                        <!-- mysql ip -->
                        <property name="ipAddress">192.168.10.103</property>           #添加端口号
                </factoryConfig>
        </dbServer>
<dbServer name="slaves" virtual="true">                    #修改成为slaves
                <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>                #修改成为slave1,slave2
                </poolConfig>
        </dbServer>
启动amoeba软件
[root@localhost ~]# amoeba start &    
#启动后按回车
[root@localhost ~]# netstat -anpt | grep java
tcp6       0      0 :::8066                 :::*                    LISTEN      11755/java          
tcp6       0      0 127.0.0.1:28683         :::*                    LISTEN      11755/java          
tcp6       0      0 192.168.10.104:39608    192.168.10.103:3306     ESTABLISHED 11755/java          
tcp6       0      0 192.168.10.104:38982    192.168.10.102:3306     ESTABLISHED 11755/java          
tcp6       0      0 192.168.10.104:55988    192.168.10.101:3306     ESTABLISHED 11755/java 
[root@localhost ~]# systemctl stop firewalld

测试

[root@localhost ~]# yum -y install mysql
mysql> use auth;
MySQL [auth]> create table users(name char(20),pass char(50));
MySQL [auth]> insert into users values('bbb','123456');
MySQL [auth]> select * from users;
+------+--------+
| name | pass   |
+------+--------+
| bbb  | 123456 |
+------+--------+
1 row in set (0.01 sec)

来到102主机上

mysql> insert into users values('1','123456');
mysql> select * from users;
+------+--------+
| name | pass   |
+------+--------+
| bbb  | 123456 |
| 1    | 123456 |
+------+--------+
2 rows in set (0.00 sec)

在来到105测试主机上,显示的数据一有一无

MySQL [auth]> select * from users;
+------+--------+
| name | pass   |
+------+--------+
| bbb  | 123456 |
+------+--------+
MySQL [auth]> select * from users;
+------+--------+
| name | pass   |
+------+--------+
| bbb  | 123456 |
| 1    | 123456 |
+------+--------+
2 rows in set (0.01 sec)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值