Amoeba在Master/Slave结构下的读写分离
MySQL主从复制原理图
MySQL使用3个线程来执行复制功能(其中1个在主服务器上,另两个在从服务器上。
当发出START SLAVE时,从服务器创建一个I/O线程,以连接主服务器并让它发送记录在其二进制日志中的语句。
主服务器创建一个线程将二进制日志中的内容发送到从服务器。该线程可以识别为主服务器上SHOW PROCESSLIST的输出中的Binlog Dump线程。
从服务器I/O线程读取主服务器Binlog Dump线程发送的内容并将该数据拷贝到从服务器数据目录中的本地文件中,即中继日志。第3个线程是SQL线程,是从服务器创建用于读取中继日志并执行日志中包含的更新。
有多个从服务器的主服务器创建为每个当前连接的从服务器创建
一个线程;每个从服务器有自己的I/O和SQL线程
配置MySQL主从复制
MASTER:
#启用Mysql-bin log (记录mysql内部增删改查等对MySQL数据库更新的操作,不记录select)
#vi /etc/my.cnf
server-id = 1 #server id不能相同
log-bin=mysql-bin
#为从库创建同步账号
mysql> grant replication slave on *.* to ‘rep‘@‘172.16.1.%‘ identified by ‘mirror-0‘;
mysql> flush privileges;
#同步开启主从复制之前的数据(新创建且没有上线的数据库服务器忽略此步骤)
#mysqldump -uroot -pmirror-0 -A -B -x --master-data=1 --single-transaction --events >/opt/4.sql
#mysql -uroot -pmirror-0 -S /data/3307/mysql.sock < /opt/4.sql
SLAVE:
#检查server id
#vi /etc/my.cnf
server-id = 1 #server id不能相同
#创建同步文件
mysql> CHANGE MASTER TO MASTER_HOST=‘172.16.1.8‘,MASTER_PORT=3306,MASTER_USER=‘rep‘,MASTER_PASSWORD=‘mirror-0‘;(MASTER_LOG_FILE=‘mysql-bin.000002‘,MASTER_LOG_POS=2495)#--master-data=2时需要添加后两句
mysql> strat slave;
#查看是否同步成功
mysql> show slave status\G;
Slave_IO_Running: Yes
Slave_SQL_Running: Yes
Amoba原理图
软件版本:
JAVA:jdk-6u45-linux-x64-rpm.bin
Amoeba:amoeba-mysql-binary-2.2.0.tar.gz
Amoeba框架是基于Java SE1.5开发的,建议使用Java SE 1.5版本
安装JAVA环境
#添加执行权限
# chmod +x jdk-6u45-linux-x64-rpm.bin
#安装JDK
#./jdk-6u45-linux-x64-rpm.bin
#方便起见,添加一个软链接
#ln -s /usr/java/jdk1.6.0_45/ /usr/java/jdk1.6
#添加环境变量
#vi /etc/profile
export JAVA_HOME=/usr/java/jdk1.6
export PATH=$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$PATH
#验证JAVA安装
# java -version
java version "1.6.0_45"
Java(TM) SE Runtime Environment (build 1.6.0_45-b06)
Java HotSpot(TM) 64-Bit Server VM (build 20.45-b01, mixed mode)
#在Master上为Amoeba创建用户(之前做了主从,且没有忽略mysql数据库)
mysql> grant all on *.* to [email protected]‘172.16.1.%‘ identified by ‘mirror-0‘;
mkdir /application/amoeba
mv amoeba-mysql-binary-2.2.0.tar.gz /application/amoeba/
#cd /application/amoeba/
#tar xf amoeba-mysql-binary-2.2.0.tar.gz
#编辑配置dbServers.xml
#vi /application/amoeba/conf/dbServers.xml
<dbServer name="abstractServer" abstractive="true">
#此处是一个抽象定义,可以通过其他定义来拓展
<!-- mysql port -->
<property name="port">3306</property>
<!-- mysql schema -->
<property name="schema">test</property>
<!-- mysql user -->
<property name="user">amoeba</property>
<property name="password">mirror-0</property>
#分别定义MySQL(真实的数据库服务器)的端口号、数据库名、用户名以及密码
<dbServer name="server1" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">172.16.1.8</property>
</factoryConfig>
</dbServer>
<dbServer name="server2" parent="abstractServer">
<factoryConfig>
<!-- mysql ip -->
<property name="ipAddress">172.16.1.7</property>
</factoryConfig>
</dbServer>
#此处定义你的数据库IP(多说两句,此处的数据库是真实的数据库,即你做主从的数据库)
<dbServer name="master" 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">server1</property> #该数据库池包含的是server1
</poolConfig>
</dbServer>
#引用官方手册的描述:multiPool(我修改成了master)是一个虚拟的数据库节点,可以将这个节点配置成好几台数据库组成的数据库池。比如上面这个配置中仅配置了一台server1,负载均衡策略为ROUNDROBIN(轮询)。
<dbServer name="slave" 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</property> #该数据库池包含的是server2,你也可以添加server3,server4.....
</poolConfig>
</dbServer>
#这一节是复制上面我自己定义的数据库池。
#vi /application/amoeba/conf/amoeba.xml
#amoeba.xml主要是配置MySQL对外访问的端口,服务地址以及读写规则,我这里主要列出需要修改的地方
<!-- port -->
<property name="port">3306</property> #为了简便使用修改为3306
<!-- bind ipAddress -->
<property name="ipAddress">172.16.1.4</property> #对外访问的地址,跟nginx proxy一样的理解就好了
<property name="user">root</property>
<property name="password">mirror-0</property>
<property name="defaultPool">master</property>
<property name="writePool">master</property>
<property name="readPool">slave</property> #读写规则
#需要注意,有些参数是注释了的,请注意去掉注释
#/application/amoeba/bin/amoeba start #启动amoeba
#登录MySQL proxy
$ mysql -uroot -p -h 172.16.1.4
Server version: 5.1.45-mysql-amoeba-proxy-2.2.0 #看到此显示登录成功
测试读写分离
#在master上建表
mysql> create table student( id int(4) not null AUTO_INCREMENT, name char(20) not null, age tinyint(2) NOT NULL default ‘0‘, dept varchar(16) default NULL, primary key(id), KEY index_name (name) );
#在slave上停止主从同步并插入数据
mysql> stop slave;
mysql> insert into test.student(id,name) values(2,‘slave‘);
#确定插入数据
mysql> select * from test.student;
+----+-------+-----+------+
| id | name | age | dept |
+----+-------+-----+------+
| 2 | slave | 0 | NULL |
+----+-------+-----+------+
#在msater插入数据
mysql> insert into student(id,name) values(1,‘Master‘);
#确定插入数据
mysql> select * from test.student;
+----+--------+-----+------+
| id | name | age | dept |
+----+--------+-----+------+
| 1 | Master | 0 | NULL |
+----+--------+-----+------+
#登录MySQL proxy(amoeba)
# mysql -uroot -p -h 172.16.1.4
#查询
mysql> select * from test.student;
+----+-------+-----+------+
| id | name | age | dept |
+----+-------+-----+------+
| 2 | slave | 0 | NULL |
+----+-------+-----+------+
#插入一条数据
mysql> insert into student(id,name) values(3,‘yuyang‘);
#再次查看返回值
mysql> select * from test.student;
+----+-------+-----+------+
| id | name | age | dept |
+----+-------+-----+------+
| 2 | slave | 0 | NULL |
+----+-------+-----+------+
#在slave上启用主从复制
mysql> start slave;
#查询
mysql> select * from test.student;
+----+--------+-----+------+
| id | name | age | dept |
+----+--------+-----+------+
| 1 | Master | 0 | NULL |
| 2 | slave | 0 | NULL |
| 3 | yuyang | 0 | NULL |
+----+--------+-----+------+