之前说到了主从复制,这次要在此基础上再搭建一个服务,那就是读写分离,内容是将读的权限放到从数据库中,将写的权限放到主数据库中,因为有主从复制的环境下,所以任何在主数据库中写入的数据都可以在从数据库中查看到,这样可以大大降低数据库的负载压力。
环境要求
主从数据库,调度服务器,测试机一共四台
系统为centOS6.5
数据库版本为Mysql5.7
调度服务器进行服务的时候需要java的编译,所以我们需要先安装java
去官网下载http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
完成之后java -version查看
我们这次使用的是Amoeba程序实现读写分离,同样的MySQL-Proxy和Spring都可以实现,
首先调度服务器将Amoeba安装至/usr/local/amoeba
Amoeba一共有7个配置文件,虽然数量少,但是功能很强大
Amoeba主配置文件($AMOEBA_HOME/conf/amoeba.xml),用来配置Amoeba服务的基本参数,如Amoeba主机地址、端口、认证方式、用于连接的用户名、密码、线程数、超时时间、其他配置文件的位置等。
数据库服务器配置文件($AMOEBA_HOME/conf/dbServers.xml),用来存储和配置Amoeba所代理的数据库服务器的信息,如:主机IP、端口、用户名、密码等。
切分规则配置文件($AMOEBA_HOME/conf/rule.xml),用来配置切分规则。
数据库函数配置文件($AMOEBA_HOME/conf/functionMap.xml),用来配置数据库函数的处理方法,Amoeba将使用该配置文件中的方法解析数据库函数。
切分规则函数配置文件($AMOEBA_HOME/conf/ruleFunctionMap.xml),用来配置切分规则中使用的用户自定义函数的处理方法。
访问规则配置文件($AMOEBA_HOME/conf/access_list.conf),用来授权或禁止某些服务器IP访问Amoeba。
日志规格配置文件($AMOEBA_HOME/conf/log4j.xml),用来配置Amoeba输出日志的级别和方式。
这次我们需要编写的配置文件是dbServers.xml和amoeba.xml
首先dbServers.xml的配置
13 <dbServer name="abstractServer" abstractive="true">
14 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
15 <property name="connectionManager">${defaultManager}</property>
16 <property name="sendBufferSize">64</property>
17 <property name="receiveBufferSize">128</property>
18
19 <!-- mysql port -->
20 <property name="port">3306</property> ##设置Amoeba连接数据库的端口
21
22 <!-- mysql schema -->
23 <property name="schema">zjj</property> ##Amoeba连接的数据库
24
25 <!-- mysql user -->
26 <property name="user">test</property> ##Amoeba以这个身份连接数据库,因此主从数据库都要有这个用户的授权(这里着重提示一下,经测试:5.7版本的用户授权和创建,用户名中不可以添加数字)
27
28 <property name="password">*A19970530a</property> ##Amoeba用户登陆的密码
29 </factoryConfig>
43 <dbServer name="writedb" parent="abstractServer"> ##Amoeba进行写操作的组
44 <factoryConfig>
45 <!-- mysql ip -->
46 <property name="ipAddress">172.25.54.2</property> ##IP为主数据库的IP
47 </factoryConfig>
48 </dbServer>
49
50 <dbServer name="slave" parent="abstractServer"> ##同理,进行读操作的组
51 <factoryConfig>
52 <!-- mysql ip -->
53 <property name="ipAddress">172.25.54.3</property> ##读操作数据库的IP
54 </factoryConfig>
55 </dbServer>
56
57 <dbServer name="myslave" virtual="true"> ##创建一个虚拟的dbserver组,将可读的数据库IP放进这个组中
58 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
59 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
60 <property name="loadbalance">1</property> ##调度算法,1表示复制均衡,2表示权重,3表示HA, 这里选择1 61
62 <!-- Separated by commas,such as: server1,server2,server1 -->
63 <property name="poolNames">slave</property>
64 </poolConfig>
65 </dbServer>
amoeba.xml的配置
11 <property name="port">8066</property> ##Amoeba使用的端口
28 <property name="user">root</property>
29
30 <property name="password">123456</property> ##测试机以这个身份和这个密码登陆调度服务器
83 <property name="defaultPool">writedb</property> ##默认进入的池为写入的数据库的池
84
85 <property name="writePool">writedb</property> ##调度服务器进行写操作的时候会进入写的数据库(在dbServers.xml中会标示出来)
86 <property name="readPool">myslave</property> ##同理,读操作的时候进入的数据库
执行amoeba/bin/launcher脚本打开这个调度器的服务(启动服务在授权之后)
主从数据库进行用户授权
GRANT ALL ON zjj.* TO 'test'@'172.25.54.4' IDENTIFIED BY '111111'; ##IP为调度服务器的
flush privileges;
这个配置文件修改启动环境amoeba/jvm.properties
32 JVM_OPTIONS="-server -Xms1024m -Xmx1024m -Xss256k -XX:PermSize=16m -XX:MaxPermSize=96m"
查看端口 netstat -antlp | grep 8066
由此可知启动正常
现在开始测试
在测试机上输入
mysql -h 172.25.54.4 -u root -p -P8066
密码为amoeba.xml的内容
首先进行读操作
之后进行写操作
表明测试成功,之后关闭写操作的服务器,验证读操作能否顺利进行
成功!
use mysql
select * from user
mysql-proxy方法
首先安装
完成之后修改配置文件
mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
38 if not proxy.global.config.rwsplit then
39 proxy.global.config.rwsplit = {
40 min_idle_connections = 1, ##设定最小连接数
41 max_idle_connections = 2, ##设定最大连接数
编写
mysql-proxy/etc/mysql-proxy.conf
1 [mysql-proxy]
2 proxy-address=172.25.36.1:3306
3 proxy-read-only-backend-addresses=172.25.36.2:3306
4 proxy-backend-addresses=172.25.36.3:3306
5 proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua
6 daemon=true
7 user=root
8 log-level=debug
9 log-file=/usr/local/mysql-proxy/logs/mysql-proxy.log
10 keepalive=true
11 proxy-plugins=admin
12 admin-username=admin
13 admin-password=westos
14 admin-lua-script=/usr/local/mysql-proxy/lib/mysql-proxy/lua/admin.lua
创建etc和log目录
在主从数据库对登陆用户进行授权
grant select, update, insert on *.* to proxy@'172.25.36.%' identified by '*A19970530a';
之后就可以运行启动脚本了
./mysql-proxy --plugins=admin --plugins=proxy --defaults-file=/usr/local/mysql-proxy/etc/mysql-proxy.conf
测试集连接的时候登陆的用户和密码 (这里要用数据库授权过的用户才可以)
mysql -h 172.25.36.1 -uproxy -p*A19970530a
调度服务器登陆的用户和密码(登陆调度服务器的控制界面)
mysql -uadmin -pwestos -P 4041 -h 172.25.36.1
之后使用SQL语句测试,查看(select)插入(insert)
binlog dump gtid 这个线程会不断的和IO连接,如果出现修改就会第一时间向从库的sql线程发送信息,并让他来读取更新
从库的两个线程SQL,IO
SQL有多线程并发性,可以实现,使用多并发的原因是因为主从复制的时候会有延迟,那么这个延迟如何解决?
方法为5.7版本更新的AFTER_SYNC 主要的修改就是将主数据库DUMP线程的串行性修改为并行性,从原来的只有一个发送的线程,改为了发送线程与接收线程并行,同步修改为了异步,所以主数据库可以在slave的ACK还没有返回的时候去做另外的工作,
Engine commit 写入到数据库
而IO线程发生在SQL之前,所以他对主从复制的正常运行更加重要
这次说AFTER_SYNC的使用
主库
install plugin rpl_semi_sync_master soname 'semisync_master.so';
安装半同步的主插件
查看主插件的状态
+------------------------------------------------------------+------------+
| Variable_name | Value |
+------------------------------------------------------------+------------+
| rpl_semi_sync_master_enabled | OFF |
| rpl_semi_sync_master_timeout | 10000 |
| rpl_semi_sync_master_trace_level | 32 |
| rpl_semi_sync_master_wait_for_slave_count | 1 |
| rpl_semi_sync_master_wait_no_slave | ON |
| rpl_semi_sync_master_wait_point | AFTER_SYNC |
| rpl_stop_slave_timeout | 31536000 |
+------------------------------------------------------------+------------+
set global rpl_semi_sync_master_enabled
将主插件的状态设置为on
查看主插件的服务状态
show status like 'rpl_semi_sync%';
+-----------------------------------------------------------------+-------+
| Variable_name | Value |
+-----------------------------------------------------------------+-------+
| Rpl_semi_sync_master_clients | 0 |
| Rpl_semi_sync_master_net_avg_wait_time | 0 |
| Rpl_semi_sync_master_net_wait_time | 0 |
| Rpl_semi_sync_master_net_waits | 0 |
| Rpl_semi_sync_master_no_times | 0 |
| Rpl_semi_sync_master_no_tx | 0 |
| Rpl_semi_sync_master_status | ON |
| Rpl_semi_sync_master_timefunc_failures | 0 |
| Rpl_semi_sync_master_tx_avg_wait_time | 0 |
| Rpl_semi_sync_master_tx_wait_time | 0 |
| Rpl_semi_sync_master_tx_waits | 0 |
| Rpl_semi_sync_master_wait_pos_backtraverse | 0 |
| Rpl_semi_sync_master_wait_sessions | 0 |
| Rpl_semi_sync_master_yes_tx | 0 |
+------------------------------------------------------------------+-------+之后执行sql语句测试,之后关闭从数据库再开始测试
从库
安装半同步的从库插件
install plugin rpl_semi_sync_slave soname 'semisync_slave.so';
查看插件信息
show variables like '%rpl%';
设置为从库开启
set global rpl_semi_sync_slave_enabled = on;
mysql的高可用用MHA