amoeba代理

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;

评论


:D 一言句子获取中...

加载中,最新评论有1分钟缓存...