MySQL主从复制与读写分离

本文介绍了在企业环境中,通过MySQL主从复制和读写分离来提升数据库的安全性、可用性和并发性能。详细步骤包括:主从复制的配置,如在主服务器上设置日志,在从服务器上同步;读写分离的实现,如使用Amoeba作为中间代理层。同时,文中还提及了可能遇到的配置错误及解决方案,例如Amoeba启动失败的XML配置问题。
摘要由CSDN通过智能技术生成

案例概述

  • 在企业应用中,成熟的业务通常数据量都比较大
  • 单台MySQL在安全性、高可用性和高并发方面都无法满足实际的需求
  • 配置多台主从数据库服务器以实现读写分离

案例前置知识点

MySQL主从复制原理

  • MySQL的复制类型
    • 基于语句的复制
    • 基于行的复制
    • 混合类型的复制
  • MySQL主从复制的工作过程

MySQL读写分离原理

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

案例环境

在这里插入图片描述

案例实施(主从复制)

主服务器(master)

关闭防火墙和核心防护

[root@localhost ~]# systemctl stop firewalld.service 
[root@localhost ~]# setenforce 0

修改用户名

[root@localhost ~]# hostnamectl set-hostname master

同步阿里云服务器

[root@master ~]# ntpdate ntp1.aliyun.com
[root@master ~]#  date -R

安装MySQL数据库(5.7)

mysql主服务器配置

[root@master ~]# vi /etc/my.cnf
server-id = 11
log-bin = master-bin   ##主服务器日志文件
log-slave-updates   ##从服务器更新二进制日志

[root@master ~]# systemctl restart mysqld

[root@master ~]# ls /usr/local/mysql/data/   #检查是否产生日志文件


[root@master ~]# mysql -uroot -p

mysql> grant replication slave on *.* To 'myslave'@'20.0.0.%' identified by '123456';
mysql> select host,user from mysql.user;  #创建成功20.0.0.%
+-----------+---------------+
| host      | user          |
+-----------+---------------+
| 20.0.0.%  | myslave       |
| localhost | mysql.session |
| localhost | mysql.sys     |
| localhost | root          |
+-----------+---------------+
mysql> flush privileges;

mysql> show master status;    #主从复制是依赖日志和定位599
+-------------------+----------+--------------+------------------+-------------------+
| File              | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 |      599 |              |                  |                   |
+-------------------+----------+--------------+------------------+-------------------+

从服务器(slave1)

关闭防火墙和核心防护

[root@localhost ~]# systemctl stop firewalld.service 
[root@localhost ~]# setenforce 0

修改用户名

[root@localhost ~]# hostnamectl set-hostname slave1

同步阿里云服务器

[root@slave1 ~]# ntpdate ntp1.aliyun.com
[root@slave1 ~]#  date -R

安装MySQL数据库(5.7)

[root@slave1 ~]# vi /etc/my.cnf
server-id = 22
relay-log = relay-log-bin    #从主服务器上同步日志文件记录到本地
relay-log-index = slave-relay-bin.index   #定义relay-log的位置和名称

[root@slave1 ~]# systemctl restart mysqld

[root@slave1 ~]# mysql -uroot -p

mysql> change master to master_host='20.0.0.26',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=599;

mysql> start slave;   #开启
mysql> show slave status\G   #查看主从同步的状态 “\G”:将查询到的横向表格纵向输出,方便阅读
...
             Slave_IO_Running: Yes   		#IO和SQL是否是yes模式
            Slave_SQL_Running: Yes
...

从服务器(slave2)

关闭防火墙和核心防护

[root@localhost ~]# systemctl stop firewalld.service 
[root@localhost ~]# setenforce 0

修改用户名

[root@localhost ~]# hostnamectl set-hostname slave2

同步阿里云服务器

[root@slave2 ~]# ntpdate ntp1.aliyun.com
[root@slave2 ~]#  date -R

安装MySQL数据库(5.7)

[root@slave2 ~]# vi /etc/my.cnf
server-id = 33
relay-log = relay-log-bin    #从主服务器上同步日志文件记录到本地
relay-log-index = slave-relay-bin.index   #定义relay-log的位置和名称

[root@slave2 ~]# systemctl restart mysqld

[root@slave2 ~]# mysql -uroot -p
mysql> change master to master_host='20.0.0.26',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=599;

mysql> start slave;   #开启
mysql> show slave status\G   #查看主从同步的状态 “\G”:将查询到的横向表格纵向输出,方便阅读
...
             Slave_IO_Running: Yes   #IO和SQL是否是yes模式
            Slave_SQL_Running: Yes
...

验证主从复制效果

登录20.0.0.26(master)

[root@localhost ~]# mysql -uroot -p
mysql> create database school;
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| school             |
| sys                |
+--------------------+

登录20.0.0.25(slave1)

[root@localhost ~]# mysql -uroot -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| school             |
| sys                |
+--------------------+

登录20.0.0.29(slave2)

[root@localhost ~]# mysql -uroot -p
mysql> show databases;
+--------------------+
| Database           |
+--------------------+
| information_schema |
| mysql              |
| performance_schema |
| school             |
| sys                |
+--------------------+

上述说明新建的school数据库同步成功

案例实施(读写分离)

服务器(amoeba)

关闭防火墙和核心防护

[root@localhost ~]# systemctl stop firewalld.service 
[root@localhost ~]# setenforce 0

修改用户名

[root@localhost ~]# hostnamectl set-hostname amoeba 
  1. 导入jdk-6u14-linux-x64.bin文件
  2. 授予执行权限:chmod +x jdk-6u14-linux-x64.bin
  3. 执行二进制文件:./jdk-6u14-linux-x64.bin
    (一路按回车就行、yes、回车)
[root@amoeba ~]# mv jdk1.6.0_14/ /usr/local/jdk1.6   #移到/usr/local/jdk1.6目录下

[root@amoeba ~]# vi /etc/profile

export JAVA_HOME=/usr/local/jdk1.6
export CLASSPATH=$CLASSPATH:$JAVA_HOME/lib:$JAVA_HOME/jre/lib
export PATH=$JAVA_HOME/lib:$JAVA_HOME/jre/bin/:$PATH:$HOME/bin
export AMOEBA_HOME=/usr/local/amoeba
export PATH=$PATH:$AMOEBA_HOME/bin

[root@amoeba ~]# source /etc/profile    #执行
[root@amoeba ~]# mkdir /usr/local/amoeba

[root@amoeba ~]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/

[root@amoeba ~]# chmod -R 755 /usr/local/amoeba  #授予权限

检验amoeba是否能执行

[root@amoeba ~]# ls /usr/local/amoeba/bin/
amoeba      amoeba.classworlds  benchmark.bat
amoeba.bat  benchmark           benchmark.classworlds
[root@amoeba ~]# /usr/local/amoeba/bin/amoeba
显示amoeba start|stop说明安装成功

在三台MySQL上添加权限开发给amoeba访问

mysql> grant all on *.* to test@'20.0.0.%' identified by '123.com'; 			#20.0.0网段授予权
mysql> flush privileges;			#刷新

回到amoeba服务器

[root@amoeba ~]# cd /usr/local/amoeba/conf/
[root@amoeba conf]# vi amoeba.xml

----30行----(账号)
<property name="user">amoeba</property>

----32行----(密码)
<property name="password">123456</property>

----115行----(只是定义一个名称)
<property name="defaultPool">master</property>

----117行去掉注释----(只是定义一个名称)
<property name="writePool">master</property>(写)
<property name="readPool">slaves</property>(读取)
<property name="needParse">true</property>

[root@amoeba conf]# vi dbServers.xml
----23行----(注意!!mysql5.7,默认没有test数据库所以需要修改为mysql数据库) - (mysql5.5、5.6直接忽略,因为有test数据库)
<property name="schema">mysql</property>

----26-29行----
<property name="user">test</property>
<!--  mysql password -->
<property name="password">123.com</property>

----45-50行主服务器----
<dbServer name="master"  parent="abstractServer">  #主服务器主机名
	 <factoryConfig>
		 <!-- mysql ip -->
		 <property name="ipAddress"20.0.0.26></property>  #主服务器地址
 	</factoryConfig>
</dbServer>

----52-57行从服务器(1)----
<dbServer name="slave1"  parent="abstractServer">
        <factoryConfig>
                <!-- mysql ip -->
                <property name="ipAddress">20.0.0.25</property>
         </factoryConfig>
</dbServer>

----69-64行从服务器(2)----(源文件没有,复制服务器1的)
<dbServer name="slave2"  parent="abstractServer">
        <factoryConfig>
                <!-- mysql ip -->
                <property name="ipAddress">20.0.0.29</property>
         </factoryConfig>
</dbServer>

----65-73行--与amoeba.xml相匹配
<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>

[root@amoeba conf]# /usr/local/amoeba/bin/amoeba start&   开启amoeba
jobs  查看SQL 中JOB 的运行状态
[12]   Running                 /usr/local/amoeba/bin/amoeba start &   成功

测试客户端

[root@amoeba conf]# yum install -y mariadb*
[root@amoeba conf]# systemctl start mariadb.service 
[root@amoeba conf]# mysql_secure_installation    #自定义部署

Set root password? [Y/n]y    设置密码
Remove anonymous users? [Y/n]n   删除匿名用户 ... skipping跳过
Disallow root login remotely? [Y/n]n   禁用远程登录
Remove test database and access to it? [Y/n]n  删除测试数据库
Reload privilege tables now? [Y/n] y   重新加载privilege数据库

[root@amoeba conf]# mysql -uamoeba -p -h 127.0.0.1 -P8066   123456
MySQL [school]> show tables;   #查看之前的表
MySQL [school]> create table test (id int(4) not null primary key,name varchar(10));  #创建一个新的表
MySQL [school]> insert into test values ('1','T1');
MySQL [school]> select * from test;   #查看不了数据,因为从服务器关闭了
Empty set (0.04 sec)

master (20.0.0.26)

[root@master ~]# mysql -uroot -p
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| test             |
+------------------+

mysql> select * from test;   #主服务器可以看到
+----+------+
| id | name |
+----+------+
|  1 | T1   |
+----+------+

MySQL [school]> select * from test;  #读的slave2服务器
+----+------+
| id | name |
+----+------+
|  3 | T3   |
+----+------+
MySQL [school]> select * from test;  #读的slave1服务器
+----+------+
| id | name |
+----+------+
|  2 | T2   |
+----+------+
在slave1、slave2服务器中轮询读取数据。

slave1(20.0.0.25)

[root@slave1 ~]# mysql -uroot -p
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| test             |
+------------------+

mysql> stop slave;

mysql> select * from test;
Empty set (0.00 sec)

mysql> insert into test values ('2','T2');
mysql> select * from test;
+----+------+
| id | name |
+----+------+
|  2 | T2   |
+----+------+

slave2(20.0.0.29)

[root@slave2 ~]# mysql -uroot -p
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| test             |
+------------------+

mysql> stop slave;
mysql> insert into test values ('3','T3');
mysql> select * from test;
+----+------+
| id | name |
+----+------+
|  3 | T3   |
+----+------+

可能遇到的问题:

/usr/local/amoeba/bin/amoeba start&开启失败

org.xml.sax.SAXParseException: Element type "property" must be followed by either attribute specifications, ">" or "/>".

解决:
property附加语句不规范,缺少">" or “/>”,需要自己在修改过的配置文件(dbServers.xml和amoeba.xml)中找咯!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值