MySQL读写分离--mysql-proxy和amoeba
静态分离:直接将服务器地址写入程序
动态分离:通过代理服务器对数据进行读写操作,由代理服务器判定读写操作,在主服务器上写数据,在
从服务器上读数据。
好处:只在一台服务器上进行读或写操作,可以减少服务器的工作量,提高效率和服务器性能
进行写操作时(在代理服务器上操作语句,写入master),slave利用主从复制同步数据
三台服务器:主服务器10.0.10.1、从服务器10.0.10.2、代理服务器10.0.10.3
两种方法实现:使用MySQL-proxy实现、使用amoeba实现
1、使用mysql-proxy实现读写分离
# ./mysql-proxy --proxy-backend-addresses=10.0.10.1:3306 --proxy-read-only-backend-addresses=10.0.10.2:3306 --proxy-lua-script=/usr/local/mysql-proxy/share/doc/mysql-proxy/rw-splitting.lua --daemon --user=mysql --log-level=warning --log-file=/var/log/mysql-proxy.log --max-open-files=2048 --event-threads=4 --proxy-address=10.0.10.3:3306
--proxy-backend-addresses 指定主服务器地址(写数据)
--proxy-read-only-backend-addresses 指定从服务器地址(读数据)
--proxy-lua-script 指定用于读写分离的脚本程序
--daemon 指定以守护进程的方式运行
--user=mysql 指定运行的用户
--log-level 指定日志记录级别
--log-file 指定日志文件位置
--max-open-files 指定最大可打开的文件数,受操作系统限制
--event-threads 设置工作线程数
--proxy-address 设置监听的本机地址和端口
获取mysql-proxy帮助
# ./mysql-proxy --help \\基本选项帮助
# ./mysql-proxy --help-proxy \\代理选项帮助
在主从服务器上分别对代理服务器进行授权,使代理服务器能够使用主从服务器上的此用户进行连接主从。
mysql> grant all on *.* to 'repuser'@'10.0.10.3' identified by '123123';
mysql> flush privileges;
2、使用amoeba实现读写分离
(1)安装jdk
# tar xf jdk-7u51-linux-x64.tar.gz -C /usr/local/
# mv jdk1.7.0_51 java
(2)编辑/etc/profile文件,设置java环境变量
# vim /etc/profile
放在export PATH USER LOGNAME MAIL HOSTNAME HISTSIZE HISTCONTROL之前
JAVA_HOME="/usr/local/java"
CLASS_PATH="/usr/local/java/jre:/usr/local/java/lib"
export JAVA_HOME CLASS_PATH
PATH="$PATH:/usr/local/amoeba/bin:/usr/local/java/bin"
# source /etc/profile
(3)查看和调整java的默认版本
# java -version
[root@hello local]# which java
/usr/bin/java \\本身有java 的路径填/usr/bin/java
# alternatives --install /usr/local/java/bin/java java /usr/local/java/bin/java 100 \\在系统中登记java版本和设置优先级
# alternatives --display java \\显示java信息
# alternatives --config java \\设置java的默认版本
(4)安装和配置amoeba实现读写分离
# unzip amoeba-mysql-3.0.5-RC-distribution.zip -d /usr/local/
# mv amoeba-mysql-3.0.5-RC amoeba
# vim dbServers.xml \\定义后端服务器信息 与主从服务器相连
<property name="sendBufferSize">256</property> \\设置发送缓冲区大小
<property name="receiveBufferSize">256</property> \\设置接收缓冲区大小
<property name="port">3306</property> \\设置后端服务器端口
<property name="schema">zz</property> \\设置代理默认连接的数据库
<property name="user">root</property>
<property name="password">123123</property> \\设置连接后端服务器的密码
===
<dbServer name="master1" parent="abstractServer"> \\定义后端服务器(主服务器)
<factoryConfig>
<property name="ipAddress">10.0.10.1</property>
</factoryConfig>
</dbServer>
<dbServer name="slave1" parent="abstractServer"> \\定义后端服务器 (从服务器)
<factoryConfig>
<property name="ipAddress">10.0.10.2</property>
</factoryConfig>
</dbServer>
===
<dbServer name="master" virtual="true"> \\定义服务器池
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<property name="loadbalance">1</property> \\定义负载均衡算法
<property name="poolNames">master1</property> \\添加服务器,多个用逗号隔开
</poolConfig>
</dbServer>
<dbServer name="slave" virtual="true"> \\定义服务器池
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<property name="loadbalance">1</property>
<property name="poolNames">slave1</property>
</poolConfig>
</dbServer>
======
# vim amoeba.xml \\定义代理信息
<property name="port">3306</property> \\设置代理服务器监听的端口
<property name="ipAddress">10.0.10.3</property> \\设置代理监听的地址
<property name="user">root</property> \\设置代理服务器使用的用户名
<property name="password">123123</property> \\设置代理服务器使用的密码
<property name="defaultPool">master</property> \\设置默认的服务器池,一般除
select,insert,update,delete等的其它操作都在默认的服务器进行
<property name="writePool">master</property> \\执行写操作的服务器池
<property name="readPool">slave</property> \\执行读操作的服务器池
<property name="needParse">true</property>
# vim jvm.properties \\设置java内存分配信息
JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss512k -XX:PermSize=32m -XX:MaxPermSize=128m"
# vim access_list.conf \\定义访问控制列表
10.0.10.100:no
10.0.*.*:yes
(5)启动amoeba
#cd /usr/local/amoeba/bin
#./launcher &
关闭amoeba
#./shutdowm
(6)实现数据分割
水平分割:将关键字段按特定的算法存放到不同的服务器
垂直分割:将数据按业务的不同分别保存到不同的服务器
水平分割
# vim rule.xml
<tableRule name="stu" schema="zz" defaultPools="master1,master2">
<rule name="rule1">
<parameters>id</parameters>
<expression><![CDATA[ id % 2 == 0 ]]></expression>
<defaultPools>master1</defaultPools>
<readPools>master1</readPools>
<writePools>master1</writePools>
</rule>
<rule name="rule2">
<parameters>id</parameters>
<expression><![CDATA[ id % 2 == 1 ]]></expression>
<defaultPools>master2</defaultPools>
<writePools>master2</writePools>
<readPools>master2</readPools>
</rule>
</tableRule>
====
在代理服务器上操作
[root@stu1024 ~]# mysql -u root -h 10.0.10.3 -paixocm -e "insert into zz.stu(id,name) values(1,'张三')"
[root@stu1024 ~]# mysql -u root -h 10.0.10.3 -paixocm -e "insert into zz.stu(id,name) values(2,'李四')"
[root@stu1024 ~]# mysql -u root -h 10.0.10.3 -paixocm -e "insert into zz.stu(id,name) values(3,'王五')"
[root@stu1024 ~]# mysql -u root -h 10.0.10.3 -paixocm -e "insert into zz.stu(id,name) values(4,'赵六')"
mysql> select * from stu;
+----+--------+
| id | name |
+----+--------+
| 2 | 李四 |
| 4 | 赵六 |
+----+--------+
mysql> select * from stu;
+----+--------+
| id | name |
+----+--------+
| 1 | 张三 |
| 3 | 王五 |
+----+--------+
=======
垂直分割
<tableRule name="user_info" schema="weblog" readPools="slave1" writePools="master1" />
<tableRule name="user_info" schema="webchat" readPools="slave2" writePools="master2"/>