简介:
Amoeba是一个以MySQL为底层数据存储,并对应用提供MySQL协议接口的proxy。它集中地响应应用的请求,依据用户事先设置的规则,将SQL请求发送到特定的数据库上执行。基于此可以实现负载均衡、读写分离、高可用性等需求。
拓扑图:
搭建mysql的主从复制环境:
ip地址为192.168.150.135作为MASTER
修改my.cnf [root@centos-server ~]# vim/etc/my.cnf [mysqld] port = 3306 binlog-do-db=dragon #同步的数据库 replicate-ignore-db=mysql #不同步的数据库 replicate-ignore-db=information_schema server-id= 1 #server-id要唯一 log-bin=mysql-bin mysql> show variables like "server_id"; +---------------+-------+ | Variable_name | Value | +---------------+-------+ | server_id | 1 | +---------------+-------+ 1 row in set (0.01 sec) mysql> create database dragon; Query OK, 1 row affected (0.08 sec) mysql> grant replication slave on *.* to 'back'@'192.168.150.%' identified by '123456'; 1 row in set (0.01 sec) #添加用户"back",SLAVE用于登录本机复制数据库日志文件 mysql> show master status; #查看MASTER上dragon库的日志的状态信息 +------------------+----------+--------------+------------------+ | File | Position | Binlog_Do_DB | Binlog_Ignore_DB | +------------------+----------+--------------+------------------+ | mysql-bin.000025 | 560 | dragon | | +------------------+----------+--------------+------------------+ 1 row in set (0.00 sec) exit [root@centos-server ~]# cd /usr/local/mysql/var/ [root@centos-server var]# tar zcf dragon.tar.gz dragon/ scp dragon.tar.gz root@192.168.150.137:/usr/local/mysql/var/ #把数据库复制到SLAVE上
ip192.168.150.137做为SLAVE
修改my.cnf的server-id为2 [root@centos-server ~]# cd /usr/local/mysql/var/ [root@centos-server ~]#tar xf dragon.tar.gz #先解压缩复制过来的数据库文件 [root@centos-server ~]#mysql -uroot -pqwe123 mysql> slave stop; Query OK, 0 rows affected, 1 warning (0.00 sec) mysql> change master to master_host='192.168.150.135',master_user='back',master_password='123456',master_log_file='mysql-bin.000025',master_log_pos=560; #使用用户"back"复制MASTER的"mysql-bin.000025"日志 Query OK, 0 rows affected (0.03 sec) mysql> slave start; Query OK, 0 rows affected (0.01 sec) mysql> exit Bye [root@centos-server ~]# service mysqld restart #重启SLAVE的mysql [root@drbd2 ~]# mysql -uroot -pqwe123 mysql> show slave status\G #查看SLAVE是否正常同步,主要看"Slave_IO_Running"和"Slave_SQL_Running"是否为yes *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 192.168.150.135 Master_User: back Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin.000025 Read_Master_Log_Pos: 560 Relay_Log_File: centos-server-relay-bin.000004 Relay_Log_Pos: 251 Relay_Master_Log_File: mysql-bin.000025 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 560 Relay_Log_Space: 414 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: 1 row in set (0.00 sec)
部署amoeba:
amoeba是基于jdk环境运行的,所以要先安装jdk [root@drbd1 ~]# mv jdk1.6.0_31/ /usr/local/ [root@drbd1 ~]# cat >/etc/profile.d/jdk.sh<<end JAVA_HOME=/usr/local/jdk1.6.0_31 PATH=\$JAVA_HOME/bin:\$PATH CLASSPATH=.:\$JAVA_HOME/lib/dt.jar:\$JAVA_HOME/lib/tools.jar export JAVA_HOME PATH CLASSPATH end [root@centos-server ~]# java -version #测试jdk安装成功 java version "1.6.0_31" Java(TM) SE Runtime Environment (build 1.6.0_31-b04) Java HotSpot(TM) 64-Bit Server VM (build 20.6-b01, mixed mode) [root@centos-server ~]# unzip amoeba-mysql-3.0.5-RC-distribution.zip [root@centos-server ~]# mv amoeba-mysql-3.0.5-RC /usr/local/amoeba [root@centos-server amoeba]# vim jvm.properties #做如下修改,不然启动amoeba会报错 #JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss196k -XX:PermSize=16m -XX:MaxPermSize=96m" JVM_OPTIONS="-server -Xms256m -Xmx1024m -Xss256k -XX:PermSize=16m -XX:MaxPermSize=96m"
配置amoeba:
主要通过"conf"目录下的dbServer.xml和amoeba.xml设置amoeba调度mysql请求: [root@centos-server conf]#vim dbServer.xml <?xml version="1.0" encoding="gbk"?> <!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd"> <amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/"> <!-- Each dbServer needs to be configured into a Pool, If you need to configure multiple dbServer with load balancing that can be simplified by the following configuration: add attribute with name virtual = "true" in dbServer, but the configuration does not allow the element with name factoryConfig such as 'multiPool' dbServer --> <dbServer name="abstractServer" abstractive="true"> <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory"> <property name="connectionManager">${defaultManager}</property> <property name="sendBufferSize">64</property> <property name="receiveBufferSize">128</property> <!-- mysql port --> <property name="port">3306</property> #连接mysql的默认端口 <!-- mysql schema --> <property name="schema">dragon</property> #设置amoeba默认连接的数据库名 <!-- mysql user --> <property name="user">amoba</property> #amoeba连接后端mysql的帐号和密码,后端mysql必须创建 <property name="password">qwe123</property> </factoryConfig> <poolConfig class="com.meidusa.toolkit.common.poolable.PoolableObjectPool"> <property name="maxActive">500</property> #设置最大连接数,默认是500 <property name="maxIdle">500</property> #配置最大空闲连接数 <property name="minIdle">1</property> #配置最少空闲连接数 <property name="minEvictableIdleTimeMillis">600000</property> <property name="timeBetweenEvictionRunsMillis">600000</property> <property name="testOnBorrow">true</property> <property name="testOnReturn">true</property> <property name="testWhileIdle">true</property> </poolConfig> </dbServer> <dbServer name="writedb" parent="abstractServer">#定义一个dbserver,名字自定义,后面会用到 <factoryConfig> <!-- mysql ip --> <property name="ipAddress">192.168.150.135</property> #dbserver的IP address </factoryConfig> </dbServer> <dbServer name="slave1" parent="abstractServer"> <factoryConfig> <property name="ipAddress">192.168.150.137</property> </factoryConfig> </dbServer> <dbServer name="slavepool" virtual="true"> #定义一个dbserver组 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"> <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> #调度算法:1.复制均衡,2.表示权重,3.表示HA。 <property name="loadbalance">2</property> <!-- Separated by commas,such as: server1,server2,server1 --> <property name="poolNames">slave1</property> #设置dbserver成员,根据需要可加多个 </poolConfig> </dbServer> </amoeba:dbServers> [root@centos-server conf]#vim amoeba.xml <?xml version="1.0" encoding="gbk"?> <!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd"> <amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/"> <proxy> <!-- service class must implements com.meidusa.amoeba.service.Service --> <service name="Amoeba for Mysql" class="com.meidusa.amoeba.mysql.server.MySQLService"> <property name="port">8066</property> #amoeba负责接受请求侦听的端口 <!-- <property name="ipAddress">127.0.0.1</property> --> <property name="connectionFactory"> <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory"> <property name="sendBufferSize">128</property> <property name="receiveBufferSize">64</property> </bean> </property> <property name="authenticateProvider"> <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator"> <property name="user">root</property> #客户机连接ameba使用的帐号和密码 <property name="password">qwe123</property> <property name="filter"> <bean class="com.meidusa.toolkit.net.authenticate.server.IPAccessController"> <property name="ipFile">${amoeba.home}/conf/access_list.conf</property> </bean> </property> </bean> </property> </service> <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext"> <!-- proxy server client process thread size --> <property name="executeThreadSize">128</property> <!-- per connection cache prepared statement size --> <property name="statementCacheSize">500</property> <!-- default charset --> <property name="serverCharset">utf8</property> <!-- query timeout( default: 60 second , TimeUnit:second) --> <property name="queryTimeout">60</property> </runtime> </proxy> <!-- Each ConnectionManager will start as thread manager responsible for the Connection IO read , Death Detection --> <connectionManagerList> <connectionManager name="defaultManager" class="com.meidusa.toolkit.net.MultiConnectionManagerWrapper"> <property name="subManagerClassName">com.meidusa.toolkit.net.AuthingableConnectionManager</property> </connectionManager> </connectionManagerList> <!-- default using file loader --> <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader"> <property name="configFile">${amoeba.home}/conf/dbServers.xml</property> </dbServerLoader> <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter"> <property name="ruleLoader"> <bean class="com.meidusa.amoeba.route.TableRuleFileLoader"> <property name="ruleFile">${amoeba.home}/conf/rule.xml</property> <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property> </bean> </property> <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property> <property name="LRUMapSize">1500</property> <property name="defaultPool">writedb</property> <property name="writePool">writedb</property> #在dbServer定义的 writedb响应写操作 <property name="readPool">slave1</property> #在dbServer定义的 slave1响应读操作 <property name="needParse">true</property> </queryRouter> </amoeba:configuration>
在后端mysql添加amobe帐号:
mysql> grant ALL ON *.* TO 'amoba'@'192.168.150.128' identified by 'qwe123'; Query OK, 0 rows affected (0.00 sec) mysql> flush privileges; Query OK, 0 rows affected (0.00 sec)
启动amoeba:
[root@centos-server ]# /usr/local/amoeba/bin/./launcer
测试读写:
[root@drbd2 conf]# mysql -uroot -pqwe123 -h192.168.150.128 -P8066
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 714931905
Server version: 5.1.45-mysql-amoeba-proxy-3.0.4-BETA Source distribution
Copyright (c) 2000, 2010, Oracle and/or its affiliates. All rights reserved.
This software comes with ABSOLUTELY NO WARRANTY. This is free software,
and you are welcome to modify and redistribute it under the GPL v2 license
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
mysql>
mysql> use dragon;
Database changed
mysql> create table user(ID INT NOT NULL PRIMARY KEY AUTO_INCREMENT,
-> name VARCHAR(20) NOT nULL,
-> sex BOOLEAN);
Query OK, 0 rows affected (0.05 sec)
mysql> insert into user(name,sex) VALUES ('dragon',1);
Query OK, 1 row affected (0.05 sec)
mysql> insert into user(name,sex) VALUES ('dragon',1),('bbq',1);
Query OK, 2 rows affected (0.01 sec)
Records: 2 Duplicates: 0 Warnings: 0
mysql> select * from user;
+----+--------+------+
| ID | name | sex |
+----+--------+------+
| 1 | dragon | 1 |
| 2 | dragon | 1 |
| 3 | bbq | 1 |
+----+--------+------+
3 rows in set (0.03 sec)