读写分离就是只在主服务器上写,只在从服务器上读
主数据库处理事务性査询,而从数据库处理 select査询
数据库复制被用来把事务性査询导致的变更同步到集群中的从数据库
最最重要的一点是mysql的存储引擎的问题,当前两大火热的存储引擎,mysam和innodb,进行写入都是锁定的,mysam是锁定表的,innodb是锁定列的,正是这样,才会出现读写分离的技术。
生产环境中,服务器不可能只有一台,而多台服务器的存在必然要用到主从复制同步。
在企业网站中,后端MySQL数据库只有一台时,会有以下问题:
遇到单点故障,服务不可用
无法处理大量的并发数据请求
数据丢失将会造成很大损失
增加MySQL数据库服务器,对数据进行备份,形成主备
确保主备MySQL数据库服务器数据是一样的
主服务器宕机了,备份服务器继续工作,数据有保障
MySQL主从复制与读写分离是密切相关的
通过主从复制的方式来同步数据,再通过读写分离来提升数据库的并发负载能力
Amoeba:是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy,外号变形虫
读取请求发送给从服务器时,采用轮询调度算法
主服务器挂掉,我们会采用MHA解决(此实验用不到)
此实验涉及到的账号权限
主从同步账号
节点服务器开放调度账号
Amoeba代理账号
基于语句的复制(默认)
在主服务器上执行的语句,从服务器执行同样的语句
基于行的复制
把改变的内容复制到从服务器
混合类型的复制
一旦发现基于语句无法精确复制时,就会采用基于行的复制
当你更新数据库数据的时候 ,首先 将日志文件写入二进制日志文件,然后通过io线程,将binarylog日志文件同步到中继日志,然后sql线程读取中继线程 将数据复制到从服务器这里来
需要注意的点 权限,要让slave服务器有权限复制 ,不能让所有人都可以复制,所以需要创建一个账号来解决。
三台centos7服务器 同一安装mysql5.7版本的
一台做master
两台做slave
主 :192.168.110.134 server-id 10
从 :192.168.110.135 server-id 30
从 :192.168.110.136 server-id 20
具体编译可参展小编之前的博客
修改/etc/my.cnf配置文件,增加服务器id,配置二进制日志选项
[root@master ~]# vim /etc/my.cnf
...省略内容
'//mysqld字段下面修改'
server-id = 10 '//修改为10'
log-bin=master-bin '//设置二进制日志名'
log-slave-updates=true '//从服务器更新二进制日志'
[root@master ~]# systemctl restart mysqld.service '//重启mysql服务'
[root@master ~]# mysql -u root -p
Enter password:
'//192.168.110.0段的从服务器拥有复制权限,可以使用myslave身份123456密码复制所有的库和表'
GRANT REPLICATION SLAVE ON *.* TO 'myslave'@'192.168.110.%' IDENTIFIED BY 'Abc123';
mysql> flush privileges; '//刷新'
Query OK, 0 rows affected (0.00 sec)
mysql> show master status; '//查看位置id'
+-------------------+----------+--------------+------------------+-------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB | Executed_Gtid_Set |
+-------------------+----------+--------------+------------------+-------------------+
| master-bin.000001 | 603 | | | |
+-------------------+----------+--------------+------------------+-------------------+
1 row in set (0.00 sec)
修改/etc/my.cnf配置文件,增加服务器id,配置二进制日志选项
[root@slave1 ~]# vim /etc/my.cnf
...省略内容
'//mysqld字段下面修改'
server-id = 20 '//修改为20,另一台从服务器的id设为30,三个id不可相同'
relay-log=relay-log-bin '//设置二进制日志名'
relay-log-index=slave-relay-bin.index '//从服务器更新二进制日志'
[root@master ~]# systemctl restart mysqld.service '//重启mysql服务'
登陆mysql服务,配置组从同步
[root@slave1 ~]# mysql -uroot -p
Enter password:
mysql> change master to master_host='192.168.110.134',master_user='myslave',master_password='123456',master_log_file='master-bin.000001',master_log_pos=603;
mysql> start slave;
Query OK, 0 rows affected (0.01 sec)
mysql> show slave status\G;
...省略内容
Slave_IO_Running: Yes '//发现IO是正常的'
Slave_SQL_Running: Yes '//SQL是正常的'
...省略内容
这里克隆的虚拟机有坑,具体解决方案可查看我排障集锦
[root@master ~]# mysql -uroot -p
Enter password:
mysql> create database schoo;
Query OK, 1 row affected (0.00 sec)
两台从服务器查看是否同步
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| school | '//成功同步'
| mysql |
| performance_schema |
| sys |
+--------------------+
5 rows in set (0.00 sec)
VMware软件
一台centos7服务器当做client
一台centos7服务器作为Amoeba服务器
三台centos7服务器作为mysql数据库服务器,一主二从 (主从复制在上面已经搭建好了 直接拿来使用)
具体拓扑图如下
通过向mysql主服务器和从服务器写东西,验证:
客户机通过amoeba服务器写入是写入mysql主服务器
客户机通过amoeba服务器读取数据是从两个slave从服务器上轮询读取数据的
安装jdk(因为amoeba是Java写的,所以我们需要安装jdk)
我已经下载好了,直接挂在宿主机复制到服务器就行
[root@amoeba mnt]# cd /usr/local
chmod +x jdk1.6
[root@amoeba local]# ./jdk-6u14-linux-x64.bin
...期间一直空格,直到要输入yes
Do you agree to the above license terms? [yes or no]
yes '//输入yes'
'//遇到它,按回车'
Press Enter to continue.....
Done.
[root@amoeba local]# mv jdk1.6.0_14/ jdk1.6 '//重命名一下,因为后边还要设置环境变量'
[root@amoeba local]# echo '//设置环境变量'
> 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' >> /etc/profile
[root@amoeba local]# source /etc/profile
[root@amoeba mnt]# mkdir /usr/local/amoeba
[root@amoeba mnt]# tar zxvf amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba/
[root@amoeba mnt]# chmod -R 755 /usr/local/amoeba '//设置权限'
[root@amoeba mnt]# /usr/local/amoeba/bin/amoeba '//查看是否安装成功'
amoeba start|stop
三台mysql服务器添加权限和用户开放给amoeba访问
mysql> grant all on *.* to test@'192.168.110.%' identified by 'Abc123';
Query OK, 0 rows affected, 1 warning (0.00 sec)
'//通过192.168.110.0段的test用户拥有所有权限对于所有的库和表都可以使用123.com来访问'
'//三台mysql服务器都要设置'
配置amoeba服务器
amoeba.xml amoeba主配置文件
dbServers.xml 数据库配置文件
[root@amoeba mnt]# cd /usr/local/amoeba/conf/
[root@amoeba conf]# vim amoeba.xml '//编辑amoeba主配置文件'
'//此段设置的是客户端通过amoeba用户和123456密码访问amoeba服务器'
<property name="user">amoeba</property> '//第30行开始修改用户名'
<property name="password">Abc123</property> '//使用Abc123密码访问amoeba服务器'
'//移动到117行,开启读写功能池设定'
<property name="defaultPool">master</property> '//115行修改'
<!-- --> '//117行取消注释'
<property name="writePool">master</property> '//118行修改'
<property name="readPool">slaves</property> '//119行修改'
'//120行删除-->注释符号'
[root@amoeba conf]# vim dbServers.xml '//编辑数据库配置文件'
<property name="schema">mysql</property> '//23行test修改为mysql'
'//设置amoeba访问mysql数据库的用户和密码'
<property name="user">test</property> '//26行修改用户名'
<!-- mysql password--> '//28行-30行取消注释'
<property name="password">Abc123</property> '//29行修改密码'
<dbServer name="master" parent="abstractServer"> '//45行主mysql服务器名称修改为master'
<property name="ipAddress">192.168.110.134</property> '48行//修改主服务器IP'
<dbServer name="slave1" parent="abstractServer"> '//52行修改从服务器名称'
<property name="ipAddress">192.168.110.135</property> '//55行修改从服务器IP'
'//第一个从服务器段后插入第二个从服务器配置'
<dbServer name="slave2" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<propertyname="ipAddress">192.168.110.136</property>
</factoryConfig>
</dbServer>
'//修改数据库从服务器池'
<dbServer name="slaves" virtual="true"> '//66行修改服务器吃名称为slaves'
<property name="poolNames">slave1,slave2</property> '//72行添加两个从服务器名称slave1,slave2'
开启amoeba软件,放到后台运行
[root@amoeba conf]# /usr/local/amoeba/bin/amoeba start &
[1] 63847
[root@amoeba conf]# log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml
2020-01-08 23:38:40,817 INFO context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.2.0
log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf
2020-01-08 23:38:41,113 INFO net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066.
2020-01-08 23:38:41,122 INFO net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:23097.
'//此时处于持续监控状态,无法输入命令'
客户端安装mysql
由于是用来验证,所以可以直接用yum安装
'//先关闭防火墙,且确认所有服务器的防火墙都已关闭'
[root@client ~]# systemctl stop firewalld.service
[root@client ~]# setenforce 0
[root@client ~]# yum install mysql -y
[root@client ~]# mysql -u amoeba -pAbc123 -h 192.168.110.132 -P8066
MySQL [(none)]> create database qqqq; '//创建一个库'
'//进入主从服务器查看,发现mysql主从服务器都已经自动同步'
测试读写分离,关闭主从复制功能
两台从服务器关闭slave功能
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)
mysql> show slave status\G;
...省略内容
Slave_IO_Running: No '//发现功能已被关闭'
Slave_SQL_Running: No
...省略内容
从服务器配置数据,验证读写分离
'slave1设置'
mysql> select * from gousheng;
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
+----+----------+
1 row in set (0.00 sec)
'slave2设置'
mysql> select * from gousheng;
+----+------+
| id | name |
+----+------+
| 2 | lisi |
+----+------+
1 row in set (0.00 sec)
MySQL [dog]> select * from gousheng;
ERROR 2006 (HY000): MySQL server has gone away
No connection. Trying to reconnect...
Connection id: 383905448
Current database: dog
'client验证'
MySQL [dog]> select * from gousheng;
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
+----+----------+
1 row in set (0.01 sec)
MySQL [dog]> select * from gousheng; 'slave1验证'
+----+------+
| id | name |
+----+------+
| 2 | lisi |
+----+------+
1 row in set (0.01 sec)
MySQL [dog]> select * from gousheng; 'slave2验证'
+----+----------+
| id | name |
+----+----------+
| 1 | zhangsan |
+----+----------+
1 row in set (0.01 sec)