Mysql代理软件Amoeba Amoeba的作用是在于Mysql之上,用于代理应用与Mysql的连接,可以理解为中间件,他的作用是将连接细化,如:将读写进行分离,分别指向不同的数据库,也可用根据不同的数据进行指向不同的数据库,还可以做读或写的负载均衡
mysql 代理层有mysqlproxy, amoeba, cobar等
Mysqlproxy:数据量很小的时候用的还不错,可数据量一但大起来,这个软件就会暴露出很多BUG问题,Mysql官方给出的建议是适应轻量级的应用
Amoeba:适用中大型数据量的应用负载,可做读写分离,数据切分,负载均衡等技术,是目前企业中用的最广的数据库代理
Cobar:Cobar的分布式主要是通过将表放入不同的库来实现。是阿里巴巴开发的软件,本地的软件和Amoeba一样
Amoeba代理Mysql读写分离 Amoeba代理Mysql读写分离,架构图:
1 2 3 4 5 6 7 8 9 10 11 12 客户 | | web应用程序,游戏程序(c,php,java.......)客户端 | | 代理层 (mysqlproxy,amoeba) 读写分离/数据切分 | | mysql主 <----> mysql从
准备4台服务器(3台也行,amoeba当代理又当客户端)
192.168.224.10 客户端
192.168.224.11 amoeba
192.168.224.12 mysql主
192.168.224.13 mysql从
1 2 3 4 5 6 -u 指定用户名 -p 指定用户密码 -h 指定服务器IP -S 指定socket文件路径 -P 指定mysql服务器的端口号 -e 不登录MySQL,进行操作。
架构前所有节点准备:
1,主机名三步,互相绑定
2,时间同步
3,关闭iptables,selinux
4, 配置好yum
5, 静态ip地址
6,安装好mysql
第一步:安装amoeba服务器 在amoeba服务器上操作。
因为是java开发的,需要java运行环境,需要先安装JDK
1、安装jdk1.8版本,
tar包二进制包,解压即能用。 本地上传
1 tar xf jdk-8u45-linux-x64.tar.gz -C /usr/local/
把刚解压的JDK改名为java
1 mv /usr/local/jdk1.8.0_45 /usr/local/java
验证一下刚解压安装的的jdk版本
1 2 3 4 5 /usr/local/java/bin/java -version java version "1.8.0_45" Java(TM) SE Runtime Environment (build 1.8.0_45-b14) Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
到此为止JDK已经好了,下面amoeba要用到这个jdk目录
2、安装amoeba软件
官网
1 https://sourceforge.net/projects/amoeba/
下载amoeba
1 2 3 4 wget https://nchc.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/3.x/amoeba-mysql-3.0.5-RC-distribution.zip unzip amoeba-mysql-3.0.5-RC-distribution.zip -d /usr/local/ mv /usr/local/amoeba-mysql-3.0.5-RC/ /usr/local/amoeba
使用ls查看解压的目录
1 2 3 ls /usr/local/amoeba/ benchmark bin conf jvm.properties lib
关注下面二个目录
bin 是启动脚本目录
conf 是配置文件目录
配置文件目录里我们要关注有三个文件:
amoeba.xml #配置amoeba的全局配置文件
dbServers.xml #配置amoeba连接mysql数据库的文件
rule.xml #配置我们数据切分的文件
3.开始配置amoeba连接mysql数据库
Amoeba-dbServers配置
dbServers.xml:读写分离配置文件
access_list.conf:IP访问列表控制配置文件 默认禁止所有ip连接
1 2 3 4 5 vim /usr/local/amoeba/conf/access_list.conf 0.0.0.0:no #表示允许所有连接 192.168.224.12:yes #表示禁止连接的ip.
修改 ./conf/dbServers.xml
1 vim /usr/local/amoeba/conf/dbServers.xml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 20 <property name="port">3306</property> #修改端口,默认是3306,可以不修改 23 <property name="schema">aaa</property> #指定访问数据库 26 <property name="user">mysql</property> #登陆数据库的用户名 29 <property name="password">123.Shui!!@#</property> #设置登陆密码 把注释打开,或者复制这行 45 <dbServer name="server1" parent="abstractServer"> #服务器1,mysql主服务器,45-50行是一段 #设置一个后端可写的dbServer,这里定义为server1,这个名字可以任意命名,后面还会用到。 46 <factoryConfig> 47 <!-- mysql ip --> 48 <property name="ipAddress">192.168.224.12</property> #mysql主服务器IP 49 </factoryConfig> 50 </dbServer> 51 52 <dbServer name="server2" parent="abstractServer"> #服务器2,mysql从服务器,52-57行是一段 53 <factoryConfig> 54 <!-- mysql ip --> 55 <property name="ipAddress">192.168.224.13</property> #mysql从服务器IP 56 </factoryConfig> 57 </dbServer>
如果要再定义一台从服务器,可以再这里增加内容,(45-50行)6yy复制6行 p粘贴,把name=”server2”改成”server3”再修改对应IP就可以了
再修改 ./conf/amoeba.xml 文件
1 vim /usr/local/amoeba/conf/amoeba.xml
设置amoeba监听的端口,默认是8066
1 2 3 4 5 6 7 8 9 10 11 12 11 <property name="port">8066</property> #修改端口(可以改可以不改) 15 <property name="ipAddress">127.0.0.1</property> #配置监听接口,不设置默认监听所有IP 30 <property name="user">amoeba</property> #客户端访问amoeba时的用户名 32 <property name="password">123</property> #客户端访问amoeba时的密码 117 <!-- #删除该行,去掉注释 118 <property name="writePool">server1</property> #这里指定写走server1 119 <property name="readPool">server2</property> #把server1改成server2,指定读 120 --> #删除该行,去掉注释
注意:
以上配置客户端连接amoeba时需要使用这里设定的账号;
此处账号密码和amoeba连接后端数据库服务器的密码无关;
前端应用程序连接数据库的地址就是Amoeba服务器的值,连接用户名和密码即为此处配置的用户名和密码。
4、修改amoeba启动文件
启动文件/usr/local/amoeba/bin/amoeba 是需要jdk的支持才能启动,下面我们配置启动文件指定访问jdk
在第1步时我们解压了jdk,这里要配置amoeba访问jdk
1 2 3 4 vim /usr/local/amoeba/bin/amoeba vim /usr/local/amoeba/bin/launcher #新的amoeba改为这个文件名了。启动文件 vim /usr/local/amoeba/bin/shutdown #停止服务, 都需要设置jdk的环境变量。
在10行下面,加上以下代码
1 2 3 JAVA_HOME=/usr/local/java PATH=$PATH:$JAVA_HOME/bin export JAVA_HOME PATH
修改-Xss196k的大小
1 vim /usr/local/amoeba/jvm.properties
把 Xss196k 改成228k,因启动时要求最低内存是228k,我这里改成512k,物理内存1024m
1 2 JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss512k -XX:PermSize=16m -XX:MaxPermSize=96m"
注:-Xms256m #分配256m物理内存给amoeba软件用,连接数据库时初始化内存就要256m
-Xmx256m #这个是amoeba软件最大可用的物理内存,(32位的JDK最大只能是2G,64位的JDK无限制但不能大于本机的物理内存大小)
-Xss128k #默认是128k,但amoeba软件要求是228k,这个启动amoeba软件就要228k的内存
再使用nohup方法启动amoeba服务
nohup ./bin/amoeba start & –这个启动方法把启动的信息写进nohup.out文件里,并在后台运行。建议用这种方法,方便我们排错。
绝对路径: nohup /usr/local/amoeba/bin/amoeba start &
启动的另外二个方法:建议不使用
./bin/amoeba start & –这个启动的方法是把启动的信息打印在终端窗口。
./bin/amoeba start >/dev/null & –把启动的信息输出到/dev/null 空洞里面。
查看是否启动
1 netstat -putnal |grep java
第二大步:在mysql主从服务器上授权并验证 为了方便验证,把两台mysql复制关闭,然后两台mysql都新建下面的测试表
下面的步骤,两台数据库都要操作执行。
1 2 3 4 5 6 7 8 9 10 11 mysql> create database aaa; Query OK, 1 row affected (0.00 sec) mysql> use aaa; Database changed mysql> create table emp (id int,ename varchar(20)); Query OK, 0 rows affected (0.01 sec) mysql> insert into emp values(1,"master"); #主服务器插入这一条 mysql> insert into emp values(1,"slave"); #从服务器插入这一条
并对mysql进行授权,授权的IP为amoeba的IP
创建用户
1 create user 'mysql'@'%' identified with mysql_native_password by '123.Shui!!@#';
授权
1 2 grant all on aaa.* to 'mysql'@'%'; flush privileges;
授权后,可以去amoeba(192.168.224.11)这台去连接一下这两个mysql,需要能连才行,如果不能连则把上面再做一遍
在amoeba服务器测试连接两台mysql
1 2 mysql -umysql -h192.168.224.12 -P3306 -p'123.Shui!!@#' mysql -umysql -h192.168.224.13 -P3306 -p'123.Shui!!@#'
如果防火墙清空后还是连不上192.168.224.13的话, 可以把13这台mysql重启
或者在mysql服务器上执行命令
1 mysqladmin flush-hosts -p'123.Shui!!'
第三大步:在客户端进行测试 客户端使用mysql命令连接 amoeba服务器登陆测试
1 mysql -uamoeba -p123 -h192.168.224.11 -P8066
注意开放对应的端口
1 iptables -A INPUT -p tcp -m multiport --dport 8066 -j ACCEPT
登录后测试
1 2 3 4 5 6 7 8 mysql> use aaa; Database changed mysql> mysql> mysql> insert into emp values(3,'test'); #这里往数据库插入了一条数据,插入的动作是指定到了mysql主,只能去master主才可以查到数据。 Query OK, 1 row affected (0.01 sec) mysql> select * from emp; #这里再查时,看不到刚插入的数据,是因为读我们指定到了mysql从
真实环境就要把主从复制打开
Amoeba集群 之 读集群 集群的好处是,可以让服务器平均负载我们连接请求
Amoeba集群分发算法有三种:
1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA
ROUNDROBIN #代表轮询,1台访问一次
WEIGHTBASED #代表加权轮询,是以哪一台性能好就承载多一点连接
HA #代表高可用
把读写分离改成读集群的条件是至少2台服务器做读,
第一步:配置dbServers.xml文件:
dbServer.xml文件里的 59行~67行 是设置集群的段
我们关注的行有59,62,65行
59行的 name=”multiPool”,这个是设置服务器集群名称,在amoeba.xml文件里设备读服务器时要用到
62行是设置集群的算法,默认是1轮询
65行是设置服务器列表。
以下是配置代码:
1 vim /usr/local/amoeba/conf/dbServers.xml
#设置定义一个虚拟的dbserver,实际上相当于一个dbserver组,这里将可读的数据库ip统一放到一个组中,将这个组的名字命名为myslave 。
1 2 3 4 5 6 7 8 9 10 59 <dbServer name="myslave" virtual="true"> 60 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> 61 <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> 62 <property name="loadbalance">1</property> 63 #选择调度算法,1表示负载均衡,2表示权重,3表示HA, 这里选择1 64 <!-- Separated by commas,such as: server1,server2,server1 --> 65 <property name="poolNames">server1,server2</property> #组成员 66 </poolConfig> 67 </dbServer>
第二步:配置amoeba.xml文件:
amoeba.xml文件里我们要修改以下行。
1 2 3 4 5 6 7 vim /usr/local/amoeba/conf/amoeba.xml #修改配置文件 <property name="defaultPool">myslave</property> #设置amoeba默认的池,这里设置为myslave <property name="writePool">server1</property> #设置写的服务器, <property name="readPool">myslave</property> #设置读的服务器。将原来的server2改成myslave。myslave就是第一步设置的集群服务器名称
第三步:重启amoeba代理软件。
1 2 nohup /usr/local/amoeba/bin/launcher & 启动 /usr/local/amoeba/bin/shutdown 停止
第四步:在客户机上测试读集群是否生效。
先在sql服务器上创建emp表
1 mysql> create table emp (id int, ename varchar(20));
在客户机上使用mysql命令登陆amoeba服务器
1 mysql -uamoeba -p123 -h192.168.224.11 -P8066
往emp表里插入两条数据
1 2 3 mysql> insert into emp values(10,"test1"); mysql> insert into emp values(11,"test11");
注:配置文件定义的是客户端写入数据是进入server1服务器上,server2服务器上就没有数据,
客户端也可以读server1服务器上的数据。
再查询emp表的数据
1 mysql> select * from emp;
查询的时候一次查询mysql 1上面的数据,再查询一次又跳到另外一台mysql服务器上了
真实环境需要把集群搭建好,数据需要同步。这里是测试,所以才分别建的不同表,
到此mysql读集群配置完毕。
Mysql 数据切分 是按照不同的数据访问不同的数据库
第一步:搭建前,先关闭读写分离和主从复制
vim /usr/local/amoeba/conf/amoeba.xml
#把下面的内容注释,读写分离成功关闭。
1 2 3 4 <!-- 86 <property name="writePool">server1</property> 87 <property name="readPool">server2</property> 89 -->
第二步:配置数据切片
面我是按aaa.emp表里的emp_id这一列来切分,当它为奇数就给server2,为偶数就给server1
修改第三个配置文件,定义数据切分的规则
1 vim /usr/local/amoeba/conf/rule.xml
参数解释
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="gbk"?> <!DOCTYPE amoeba:rule SYSTEM "rule.dtd"> <amoeba:rule xmlns:amoeba="http://amoeba.meidusa.com/"> <tableRule name="emp" schema="aaa" defaultPools="server1,server2"> #name代表 表名称,schema代表数据库名,defaultPools代表可支持的服务器 <rule name="rule1" ruleResult="POOLNAME"> #name 代表切片动作的名称 <parameters>id</parameters> #代表aaa.emp表里哪个字段要做切片的判断 <expression><![CDATA[ #切片开始 var division = id % 2; #定义division变量,值为 id % 2 ,也就是取余 case division when 1 then 'server1'; #变量值不能被2整除的转到server1 when 0 then 'server2'; #变量值能被2整除的转到server2 end case; ]]> #切片结束 </expression> </rule> </tableRule> </amoeba:rule>
先拷贝一份默认文件
1 cp /usr/local/amoeba/conf/rule.xml /usr/local/amoeba/conf/rule.xml.bak
直接复制粘贴上去,格式空格之类的太多;可以先在vim里:set paste再insert模式粘贴上去就可以了
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 <?xml version="1.0" encoding="gbk"?> <!DOCTYPE amoeba:rule SYSTEM "rule.dtd"> <amoeba:rule xmlns:amoeba="http://amoeba.meidusa.com/"> <tableRule name="emp" schema="aaa" defaultPools="server1,server2"> <rule name="rule1" ruleResult="POOLNAME"> <parameters>id</parameters> <expression><![CDATA[ var division = id % 2; case division when 1 then 'server1'; when 0 then 'server2'; end case; ]]> </expression> </rule> </tableRule> </amoeba:rule>
备:复制到rule.xml文件后,要把后面的中文注释删除,光标移到需要删除的地方。使用命令d$
第三步:重启amoeba
如果配置文件出错会启动不了:
1 2 nohup /usr/local/amoeba/bin/launcher & 启动 /usr/local/amoeba/bin/shutdown 停止
第四步:客户端测试
在客户端连接进行测试,连接的IP为amoeba的IP,端口为8066
1 mysql -h192.168.224.11 -uamoeba -p123 -P8066
意:amoeba是根据sql解析来进行数据切分的,所以需要把切分的关键字段(这里是emp表的id字段)加入到sql中.否则切分规则无效。无效后,会在 server1,server2 均都插入数据。
1 insert into aaa.emp values (1,'aaa'); #这样做是错误的,会在两个后台数据库里都插入数据
正确的插入方法
1 2 3 4 mysql> insert into aaa.emp(id,ename) values (1,'aaa'); mysql> insert into aaa.emp(id,ename) values (2,'bbb'); mysql> insert into aaa.emp(id,ename) values (3,'ccc'); mysql> insert into aaa.emp(id,ename) values (4,'ddd');
然后去server1(192.168.224.12)上查看,只有1,3两条数据
去server2(192.168.224.13)上查看,只有2,4两条数据
数据切分成功
delete和update操作也是同理
数据水平切分
按照上面的配置文件,只修改rule.xml规则文件如下,做成以emp_id值的范围来进行水平切分
下面实现的是id小于等于100的任何操作都在server1,大于100的任何操作都是在server2
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 <?xml version="1.0" encoding="gbk"?> <!DOCTYPE amoeba:rule SYSTEM "rule.dtd"> <amoeba:rule xmlns:amoeba="http://amoeba.meidusa.com/"> <tableRule name="emp" schema="aaa" defaultPools="server1,server2"> <rule name="rule1"> # 注意: (ruleResult="POOLNAME") 这句不要添加, 否则客户端插入数据会报错 <parameters>id</parameters> <expression><![CDATA[ id <= 100]]></expression> <defaultPools>server1</defaultPools> <readPools>server1</readPools> <writePools>server1</writePools> </rule> <rule name="rule2"> <parameters>id</parameters> <expression><![CDATA[ id > 100]]></expression> <defaultPools>server2</defaultPools> <readPools>server2</readPools> <writePools>server2</writePools> </rule> </tableRule> </amoeba:rule>
重启amoeba
1 2 nohup /usr/local/amoeba/bin/launcher & 启动 /usr/local/amoeba/bin/shutdown 停止
客户端测试
1 mysql -h192.168.224.11 -uamoeba -p123 -P8066
id分别输入大于100和小于100测试
1 2 3 4 mysql> insert into aaa.emp(id,ename) values (99,'aaa'); mysql> insert into aaa.emp(id,ename) values (100,'bbb'); mysql> insert into aaa.emp(id,ename) values (101,'ccc'); mysql> insert into aaa.emp(id,ename) values (102,'ddd');
数据水平切分成功
Amoeba数据切分 之 垂直切分:
架构图
1 2 3 4 5 6 7 8 9 10 11 client 192.168.224.10 | | amoeba 192.168.224.11 | | |------------------| mysqlA mysqlB 192.168.224.12 192.168.224.13 aaa.aaa表 aaa.bbb表
第一步:准备测试环境
1、先把两个mysql(不做AB复制的)以前的数据删掉,新建两个表来做测试
192.168.224.12上
1 2 3 mysql> create database aaa; mysql> use aaa; mysql> create table aaa.aaa (id int);
192.168.224.13上
1 2 3 mysql> create database aaa; mysql> use aaa; mysql> create table aaa.bbb (id int);
第二步:修改rule.xml配置文件
1 vim /usr/local/amoeba/conf/rule.xml #清空文件内容,加上下面一段
1 2 3 4 5 6 <?xml version="1.0" encoding="gbk"?> <!DOCTYPE amoeba:rule SYSTEM "rule.dtd"> <amoeba:rule xmlns:amoeba="http://amoeba.meidusa.com/"> <tableRule name="aaa" schema="aaa" defaultPools="server1"/> <tableRule name="bbb" schema="aaa" defaultPools="server2"/> </amoeba:rule>
第三步:重启amoeba
1 2 nohup /usr/local/amoeba/bin/launcher & /usr/local/amoeba/bin/shutdown
第四步:在客户端测试
1 mysql -uamoeba -p123 -h192.168.224.11 -P8066
1 2 3 4 5 6 7 8 mysql> use aaa; mysql> insert into aaa values (1); #这一条被插入到192.168.224.12上的aaa.aaa表 mysql> insert into bbb values (2); #这一条被插入到192.168.224.13上的aaa.bbb表 服务器分别查询 select * from aaa.aaa; select * from aaa.bbb;
未找到相关的 Issues 进行评论
请联系 @zhi666 初始化创建