前言:
而今朋友们对“amoebaformysql源码”大概比较着重,我们都想要分析一些“amoebaformysql源码”的相关资讯。那么小编同时在网络上汇集了一些有关“amoebaformysql源码””的相关文章,希望我们能喜欢,我们一起来了解一下吧!下面继续分享没有生气了数据库1-6节课,之05
mysql 代理层
(mysqlproxy, amoeba, cobar)
客户
|
|
web程序,游戏程序(c,php,java.......)
|
|
代理层 (mysqlproxy,amoeba)
|
|
mysql主 <----> mysql从
amoeba 变形虫
参考网址:
基于Amoeba的数据水平切分:
client 192.168.0.x
|
|
|
amoeba 192.168.0.3
|
|
|
|------------------------|
mysql mysql
192.168.0.1 192.168.0.2
架构前所有节点准备:
1,主机名三步,互相绑定
2,时间同步
3,关闭iptables,selinux
4, 配置好yum
5, 静态ip地址
第一步:在192.168.0.3安装amoeba
1,因为是java开发的,需要java运行环境,也就是jdk;我们这里自己下载安装jdk
/share/soft/amoeba/jdk-6u18-ea-bin-b02-linux-i586-09_sep_2009.bin
./jdk-6u18-ea-bin-b02-linux-i586-09_sep_2009.bin --直接./执行它,就可以安装,会自动解压成一个目录在当前目录下
敲空格,yes
--如果是在64位系统版本上安装这个jdk,可能会报缺少ld-linux.so.2的库,是因为这个jdk是32位的
--解决方法:在64位系统上安装32位的glibc,或者用下面的命令,直接yum安装库就可以了
# yum install ld-linux.so.2 -y
# mv jdk1.6.0_18/ /usr/local/java --把jdk的目录移到/usr/local下叫java
2,解压安装amoeba,软件包路径在下面
/share/soft/amoeba/amoeba-mysql-binary-2.2.0.tar.gz
因为这个软件打包的习惯不好,解压后,不会给你建立一个目录
所以:
# mkdir /usr/local/amoeba
# tar xf /share/soft/amoeba/amoeba-mysql-binary-2.2.0.tar.gz -C /usr/local/amoeba
# ls /usr/local/amoeba/ --amoeba的所有文件在此目录下
benchmark changelogs.txt lib README.html
bin conf LICENSE.txt
# cd /usr/local/amoeba/
# ./bin/amoeba --直接用此命令启动,会报找不到java_home
Error: JAVA_HOME environment variable is not set.
#vim /usr/local/amoeba/bin/amoeba
--加上下面两行(把这两句加到最上面,不要加到最下面,因为这个脚本要用到这个变量的),让这个命令在启动时,就会去找/usr/local/java的jdk
export JAVA_HOME=/usr/local/java
export PATH=$PATH:$JAVA_HOME/bin
# /usr/local/amoeba/bin/amoeba start & --尝试启动,可以启动,但是我们并没有做任何配置,所以在这里ctrl+c取消掉
第二大步:
把两台mysql,关闭AB复制,把先前所有的内容都清空,然后两台mysql都新建下面的测试表
mysql> create database aaa;
Query OK, 1 row affected (0.00 sec)
mysql> use aaa;
Database changed
mysql> create table emp (emp_id int,ename varchar(20));
Query OK, 0 rows affected (0.01 sec)
--并对mysql进行授权,授权的IP为amoeba的IP
mysql> grant all on aaa.* to 'amoeba'@'192.168.0.%' identified by '123';
Query OK, 0 rows affected (0.04 sec)
mysql> flush privileges;
Query OK, 0 rows affected (0.00 sec)
授权后,可以去amoeba(192.168.0.3)这台去连接一下这两个mysql,需要能连才行
第三大步:
# vim /usr/local/amoeba/conf/dbServers.xml --修改此配置文件,定义代理哪些后台数据库
--下面我做了修改的行有23行(写上要操作的后台数据库的schema);26行和29行(授权的用户名和密码);48行和55行(写上后台数据库的IP)
19 <!-- mysql port -->
20 <property name="port">3306</property>
21
22 <!-- mysql schema -->
23 <property name="schema">aaa</property>
24
25 <!-- mysql user -->
26 <property name="user">amoeba</property>
27
28 <!-- mysql password -->
29 <property name="password">123</property>
45 <dbServer name="server1" parent="abstractServer">
46 <factoryConfig>
47 <!-- mysql ip -->
48 <property name="ipAddress">192.168.0.1</property>
49 </factoryConfig>
50 </dbServer>
51
52 <dbServer name="server2" parent="abstractServer">
53 <factoryConfig>
54 <!-- mysql ip -->
55 <property name="ipAddress">192.168.0.2</property>
56 </factoryConfig>
57 </dbServer>
# vim /usr/local/amoeba/conf/amoeba.xml --再修改这个文件,修改了30行和32行(授权的用户和密码),注意这里的用户名和密码跟数据库授权的用户名和密码无关,可以写成不一样的用户和密码来测试
--上一个配置文件里配置的用户名和密码是数据库授权给amoeba连接的用户名和密码,而这个用户名和密码是amoeba给客户端(php,java,web程序等)连接的
30 <property name="user">amoeba</property>
31
32 <property name="password">123</property>
# vim /usr/local/amoeba/conf/rule.xml --修改第三个配置文件,定义数据切分的规则
--下面我是按aaa.emp表里的emp_id这一列来切分,当它为奇数就给server2,为偶数就给server1
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:rule SYSTEM "rule.dtd">
<amoeba:rule xmlns:amoeba="">
<tableRule name="emp" schema="aaa" defaultPools="server1,server2">
<rule name="rule1" ruleResult="POOLNAME">
<parameters>emp_id</parameters>
<expression><![CDATA[
var division = emp_id % 2;
case division when 1 then 'server1';
when 0 then 'server2';
end case;
]]></expression>
</rule>mysql>
</tableRule>
</amoeba:rule>
--直接复制粘贴上去,格式空格之类的太多;可以先在vim里:set paste再insert模式粘贴上去就可以了
第四大步:
在amoeba的代理服务器上启动amoeba服务
# /usr/local/amoeba/bin/amoeba start &
第五大步:
客户端测试
在客户端连接进行测试,连接的IP为amoeba的IP,端口为8066
# mysql -h 192.168.0.3 -u amoeba -p123 -P 8066
注意:amoeba是根据sql解析来进行数据切分的,所以需要把切分的关键字段(这里是emp_id),加入到sql中.否则切分规则无效。无效后,会在 server1,server2 均都插入数据。
mysql> insert into aaa.emp values (1,'aaa'); --这样做是错误的,会在两个后台数据库里都插入数据
--正确的插入方法
mysql> insert into aaa.emp(emp_id,ename) values (1,'aaa');
mysql> insert into aaa.emp(emp_id,ename) values (2,'bbb');
mysql> insert into aaa.emp(emp_id,ename) values (3,'ccc');
mysql> insert into aaa.emp(emp_id,ename) values (4,'ddd');
然后去server1(192.168.0.1)上查看,只有1,3两条数据
去server2(192.168.0.2)上查看,只有2,4两条数据
数据切分成功
在客户端select去查这张表,得到的是两个数据库数据的综合
mysql> select * from aaa.emp;
mysql> select * from emp;
delete和update操作经测试也都OK
==================================
--按照上面的配置文件,只修改rule.xml规则文件如下,做成以emp_id值的范围来进行水平切分
--下面实现的是emp_id小于等于100的任何操作都在server1,大于100的任何操作都是在server2
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:rule SYSTEM "rule.dtd">
<amoeba:rule xmlns:amoeba="">
<tableRule name="emp" schema="aaa" defaultPools="server1,server2">
<rule name="rule1">
<parameters>emp_id</parameters>
<expression><![CDATA[ emp_id <= 100]]></expression>
<defaultPools>server1</defaultPools>
<readPools>server1</readPools>
<writePools>server1</writePools>
</rule>
<rule name="rule2">
<parameters>emp_id</parameters>
<expression><![CDATA[ emp_id > 100]]></expression>
<defaultPools>server2</defaultPools>
<readPools>server2</readPools>
<writePools>server2</writePools>
</rule>
</tableRule>
</amoeba:rule>
=========================================================================
基于Amoeba的数据垂直切分:
架构图和上面的一样
client 192.168.0.x
|
|
amoeba 192.168.0.3
|
|
|------------------------|
mysql mysql
192.168.0.1 192.168.0.2
aaa表 bbb表
第一大步:
1,先把两个mysql(不做AB复制的)以前的数据删掉,新建两个表来做测试
192.168.0.1上
mysql> create databases aaa;
mysql> use aaa;
mysql> create table aaa (id int);
mysql> grant all on aaa.* to 'amoeba'@'192.168.0.%' identified by '123';
mysql> flush privileges;
192.168.0.2上
mysql> create databases aaa;
mysql> use aaa;
mysql> create table bbb (id int);
mysql> grant all on aaa.* to 'amoeba'@'192.168.0.%' identified by '123';
mysql> flush privileges;
第二大步:
# vim /usr/local/amoeba/conf/rule.xml --清空配置,加上下面一段
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:rule SYSTEM "rule.dtd">
<amoeba:rule xmlns:amoeba="">
<tableRule name="aaa" schema="aaa" defaultPools="server1"/>
<tableRule name="bbb" schema="aaa" defaultPools="server2"/>
</amoeba:rule>
第三大步:
重启amoeba
# /usr/local/amoeba/bin/amoeba stop
# /usr/local/amoeba/bin/amoeba start &
第四大步:
在客户端测试
# mysql -h 192.168.0.3 -u amoeba -p123 -P8066
mysql> use aaa;
mysql> insert into aaa values (1); --这一条被插入到192.168.0.1上的aaa.aaa表
mysql> insert into bbb values (2); --这一条被插入到192.168.0.2上的aaa.bbb表
mysql> select * from aaa;
+------+
| id |
+------+
| 1 |
+------+
1 row in set (0.01 sec)
mysql> select * from bbb;
+------+
| id |
+------+
| 2 |
+------+
1 row in set (0.00 sec)
===============================================================
使用amoeba实现读写分离功能(queryrouter)
参考网址:
在上面的基础上,把垂直切分,改成读写分离的架构
client 192.168.0.x
|
|
amoeba 192.168.0.3
|
|------------------------|------------|
mysql mysql mysql
192.168.0.1 192.168.0.2 192.168.0.4
1 2 3
写 读 读
master slave slave
第一大步:
1,先把三个mysql(读写分离应该要做AB复制,但我们在这里不做AB复制,是为了方便测试)
把以前的数据删掉,新建三个相同的表来做测试,插入三条不同的数据
192.168.0.1上
mysql> create databases aaa;
mysql> use aaa;
mysql> create table aaa (id int);
mysql> insert into aaa values (1);
192.168.0.2上
mysql> create databases aaa;
mysql> use aaa;
mysql> create table aaa (id int);
mysql> insert into aaa values (2);
192.168.0.4上
mysql> create databases aaa;
mysql> use aaa;
mysql> create table aaa (id int);
mysql> insert into aaa values (3);
第二大步:
# vim /usr/local/amoeba/conf/dbServers.xml --在原来配置的两个dbserver的情况下,再增加一段server3,对应的IP为192.168.0.4
--然后把两个从(server2,server3)加入到一个pool,我这里poolname为slavepool
<dbServer name="server3" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">192.168.0.4</property>
</factoryConfig>
</dbServer>
<dbServer name="slavepool" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
<property name="loadbalance">1</property>
<!-- Separated by commas,such as: server1,server2,server1 -->
<property name="poolNames">server2,server3</property>
</poolConfig>
</dbServer>
--1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA,算法:1,轮循(一人一次做循环) 2,加权 3,高可用
# vim /usr/local/amoeba/conf/amoeba.xml
--打开amoeba.xml文件,在原来的基础上修改,把117行和120行的注释去掉,修改115行和118行为server1(也就是mysql主,默认池和写池)
--改119行为server(也就是mysql从,读池)
114 <property name="LRUMapSize">1500</property>
115 <property name="defaultPool">server1</property>
116
117
118 <property name="writePool">server1</property>
119 <property name="readPool">slavepool</property>
120
121 <property name="needParse">true</property>
--注意:如果只读写分离的话,不做数据切分,那么rule.xml文件就不要配置,保持刚装完amoeba时的原始配置文件就好了(如果清空rule.xml,启动时会报错)
第三大步:
重启amoeba
# /usr/local/amoeba/bin/amoeba stop
# /usr/local/amoeba/bin/amoeba start &
第四大步:
在客户端测试
# mysql -h 192.168.0.3 -u amoeba -p123 -P8066
mysql> use aaa;
mysql> insert into aaa values (3); --写入的数据只会被插入到server1(这里是没有做复制的,如果做复制会被复制到server2和server2)
--读的测试,一次读server2的数据,一次读server3的数据,读时,不要执行use aaa这条语句
mysql> select * from aaa;
+------+
| id |
+------+
| 2 |
+------+
mysql> select * from aaa;
+------+
| id |
+------+
| 3 |
+------+
读写分离成功
扩展讨论:
把dbServer.xml配置文件池的配置修改一下,把server2写两个,server3写一个,算法还是rr
<property name="poolNames">server2,server2,server3</property>
--测试的结果是select查询时,两次得到server2的结果,一次得到server3的结果
==========================================================
数据切分加读写分离综合讨论
client 192.168.0.x
|
|
amoeba 192.168.0.3
|
|
|------------------|------------------|--------------|
mysqlA mysqlB mysqlC mysqlD
192.168.0.1 192.168.0.2 192.168.0.4 192.168.0.5
读写分离: 写 读 写 读
数据切分: 奇数 奇数 偶数 偶数
135246 135 135246 246
mysqlA(master) <-----> mysqlC(master) 双主
| |
| |
mysqlB(slave) mysqlD(slave)
99 100 199 200
--上图中:
对数据进行水平切分,并做读写分离
我们这里测试是用aaa.aaa表的id列来进行水平切分
id为奇数的查询路由mysqlA和mysqlB(mysqlA写,mysqlB读)
id为偶数的查询路由mysqlC和mysqld(mysqlC写,mysqlD读)
第一大步:
四台mysql都建立aaa.aaa表,这里不做AB复制(实际环境应该做)
mysql> create database aaa;
mysql> use aaa;
mysql> create table aaa (id int);
--四个mysql都要对amoeba服务器授权
mysql> grant all on aaa.* to 'amoeba'@'192.168.0.3' identified by '123';
mysql> flush privileges;
第二大步:
# vim /usr/local/amoeba/conf/dbServers.xml
--下面四段是配置四台mysql服务器,名字分别为mysqla,mysqlb,mysqlc,mysqld;对应的ip分别为4,5,6,7
<dbServer name="mysqla" parent="abstractServer">
<factoryConfig>
<property name="ipAddress">192.168.0.1</property>
</factoryConfig>
</dbServer>
<dbServer name="mysqlb" parent="abstractServer">
<factoryConfig>
<property name="ipAddress">192.168.0.2</property>
</factoryConfig>
</dbServer>
<dbServer name="mysqlc" parent="abstractServer">
<factoryConfig>
<property name="ipAddress">192.168.0.4</property>
</factoryConfig>
</dbServer>
<dbServer name="mysqld" parent="abstractServer">
<factoryConfig>
<property name="ipAddress">192.168.0.5</property>
</factoryConfig>
</dbServer>
--下面两段定义了1个pool叫ddlpool(也就是说除了DML操作外的其它操作大部分为ddl操作,如create表或库等操作就给这个池),用的是1算法,所以一次给mysqla,一次给mysqlc;如果其中一个挂了,它会把DDL操作全给另一个
<dbServer name="ddlpool" virtual="true">
<poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
<property name="loadbalance">1</property>
<property name="poolNames">mysqla,mysqlc</property>
</poolConfig>
</dbServer>
# vim /usr/local/amoeba/conf/amoeba.xml --定义DML的读写之外的所有操作给ddlpool(由上面的dbServer.xml定义),DML的读写操作在这里不定义(所以下面把wirtePool和readPool这两句给注释掉不用),因为我们要定义到rule.xml里
114 <property name="LRUMapSize">1500</property>
115 <property name="defaultPool">ddlpool</property>
116
117 <!--
118 <property name="writePool">server1</property>
119 <property name="readPool">server1</property>
120 -->
读写注释掉
# vim /usr/local/amoeba/conf/rule.xml --定义DML的读写操作的规则文件如下
<?xml version="1.0" encoding="gbk"?>
<!DOCTYPE amoeba:rule SYSTEM "rule.dtd">
<amoeba:rule xmlns:amoeba="">
<tableRule name="aaa" schema="aaa" >
<rule name="rule1" ruleResult="POOLNAME">
<parameters>id</parameters>
<expression><![CDATA[
var division = id % 2;
case division when 0 then (isReadStatement?'mysqld':'mysqlc');
when 1 then (isReadStatement?'mysqlb':'mysqla');
end case;
]]></expression>
</rule>
</tableRule>
</amoeba:rule>
第三大步:
启动amoeba
# /usr/local/amoeba/bin/amoeba stop
# /usr/local/amoeba/bin/amoeba start &
第四大步:
在客户端测试
# mysql -h 192.168.0.3 -u amoeba -p123 -P8066
测试1:
测试DDL写操作
mysql > create table bbb(id int);
mysql > create table ccc(id int);
mysql > create table ddd(id int);
mysql > create table eee(id int);
......
测试结果为:一次在mysqla,一次在mysqlc轮循操作;如果mysqla挂掉,则只会在mysqlc上操作,如果mysqla再启起来,则又会回到1算法的轮循
测试2:
测试DML写操作时,最好奇偶和大小顺序搞乱来测
mysql> insert into aaa(id) values (2);
mysql> insert into aaa(id) values (4);
mysql> insert into aaa(id) values (1);
mysql> insert into aaa(id) values (6);
mysql> insert into aaa(id) values (3);
mysql> insert into aaa(id) values (5);
测试结果为:奇写在mysqla,偶写在mysqlc
测试3;
测试DML读操作
在mysqlb上插入一条奇数据,一条偶数据(不是在客户端操作)
mysql> insert into aaa(id) values (99);
mysql> insert into aaa(id) values (100);
同理在mysqld上也插入一条奇数据,一条偶数据(不是在客户端操作)
mysql> insert into aaa(id) values (199);
mysql> insert into aaa(id) values (200);
在客户端连上amoeba,测试
mysql > use aaa
mysql > select * from aaa where id=99; --结果可以查出来
mysql > select * from aaa where id=100; --结果查不出来,因为你这是偶读操作,会给mysqld,但mysqld上没有这条记录
mysql > select * from aaa where id=199; --结果查不出来,因为你这是奇读操作,会给mysqlb,但mysqlb上没有这条记录
mysql > select * from aaa where id=200; --结果可以查出来
测试结果:从上面这样的验证,可以确认奇读给mysqlb,偶读给mysqld,一切OK
标签: #amoebaformysql源码