zoukankan      html  css  js  c++  java
  • Amoeba For MySQL入门:实现数据库水平切分

    http://docs.hexnova.com/amoeba/rw-splitting.html (在Master/Slave结构下的读写分离,负载均衡)

    当系统数据量发展到一定程度后,往往需要进行数据库的垂直切分和水平切分,以实现负载均衡和性能提升,而数据切分后随之会带来多数据源整合等等问题。如果仅仅从应用程序的角度去解决这类问题,无疑会加重应用程度的复杂度,因此需要一个成熟的第三方解决方案。

    Amoeba正是解决此类问题的一个开源方案,Amoeba位于应用程序和数据库服务器之间,相当于提供了一个代理,使得应用程序只要连接一个Amoeba,相当于只是在操作一个单独的数据库服务器,而实际上却是在操作多个数据库服务器,这中间的工作全部交由Amoeba去完成。

    本文针对基于MySQL的水平切分的实现机制,讲解Amoeba For MySQL的简单应用。

    一、背景介绍

    使用数据库:MySQL

    数据库节点1:127.0.0.1

    数据库节点2:10.167.157.176

    数据库名:yunzhu

    切分的表:用户表(user_info)

    切分的参数:用户ID(USERID)

    切分规则:

    用户ID小于等于100的数据存到数据库节点1,

    用户ID大于100的数据存到数据库节点2

    user_info表结构如下:

    Sql代码  收藏代码
    1. CREATE TABLE `user_info` (  
    2.     `USERID` INT(10) NOT NULL DEFAULT '0',  
    3.     `USERNAME` VARCHAR(50) NULL DEFAULT NULL,  
    4.     PRIMARY KEY (`USERID`)  
    5. )  

    数据库节点1中user_info表中的数据:

    +--------+-----------+
    | USERID | USERNAME  |
    +--------+-----------+
    |     73 | Chen Feng |
    |     88 | China     |
    +--------+-----------+

    数据库节点1中user_info表中的数据:

    +--------+----------+
    | USERID | USERNAME |
    +--------+----------+
    |    108 | Jiang Su |
    |    200 | NanJing  |
    +--------+----------+

    Amoeba版本:

    amoeba-mysql-binary-2.2.0

    下载地址:

    http://nchc.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/2.2.x/amoeba-mysql-binary-2.2.0.tar.gz

    下载后直接解压即可使用

    二、配置Amoeba

    配置文件全部位于conf目录下

    1、amoeba.xml

    配置连接Amoeba程序的用户名和密码:

    Xml代码  收藏代码
    1. <property name="user">root</property>  
    2. <property name="password">chenfeng123</property>  

    2、dbServers.xml

    先配置一个抽象的父节点,定义多个数据库节点的共通的信息,包括数据库节点的端口、schema、用户名和密码:

    Xml代码  收藏代码
    1. <dbServer name="abstractServer" abstractive="true">  
    2.     <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">  
    3.         ......  
    4.               
    5.         <!-- mysql port -->  
    6.         <property name="port">3306</property>  
    7.           
    8.         <!-- mysql schema -->  
    9.         <property name="schema">yunzhu</property>  
    10.           
    11.         <!-- mysql user -->  
    12.         <property name="user">root</property>  
    13.           
    14.         <!--  mysql password -->  
    15.         <property name="password">chenfeng</property>  
    16.     </factoryConfig>  
    17.       ......  
    18. </dbServer>  

      再配置两个数据库节点,继承上面的父节点,然后配置各自的IP地址即可:

    Xml代码  收藏代码
    1. <dbServer name="server1"  parent="abstractServer">  
    2.     <factoryConfig>  
    3.         <!-- mysql ip -->  
    4.         <property name="ipAddress">127.0.0.1</property>  
    5.     </factoryConfig>  
    6. </dbServer>  
    7.   
    8. <dbServer name="server2"  parent="abstractServer">  
    9.     <factoryConfig>  
    10.         <!-- mysql ip -->  
    11.         <property name="ipAddress">10.167.157.176</property>  
    12.     </factoryConfig>  
    13. </dbServer>  

    3、rule.xml

      配置切分规则:

         1、schema指定数据库名,name指定表名,defaultPools指定关联的数据库节点(指定哪几个节点就从哪几个节点里面查数据)

         2、切分规则:

             1)用户ID小于100的数据存到数据库节点1

             2)用户ID大于100的数据存到数据库节点2

    Xml代码  收藏代码
    1. <amoeba:rule xmlns:amoeba="http://amoeba.meidusa.com/">  
    2.     <tableRule name="user_info" schema="yunzhu" defaultPools="server1,server2">  
    3.         <rule name="rule1">  
    4.             <parameters>USERID</parameters>  
    5.             <expression><![CDATA[ USERID <= 100]]></expression>  
    6.             <defaultPools>server1</defaultPools>  
    7.             <readPools>server1</readPools>  
    8.             <writePools>server1</writePools>  
    9.         </rule>  
    10.         <rule name="rule2">  
    11.             <parameters>USERID</parameters>  
    12.             <expression><![CDATA[ USERID > 100 ]]></expression>  
    13.             <defaultPools>server2</defaultPools>  
    14.             <writePools>server2</writePools>  
    15.             <readPools>server2</readPools>  
    16.         </rule>  
    17.     </tableRule>        
    18. </amoeba:rule>  

    三、运行及验证

    1、启动Amoeba

    通过bin目录下的amoeba.bat启动:

    Dos代码  收藏代码
    1. amoeba start  

    启动后控制台打印如下信息,可以看到:

    Dos代码  收藏代码
    1. log4j:WARN log4j config load completed from file:D:JavaToolsamoeba-mysql-binar  
    2. y-2.2.0in..conflog4j.xml  
    3. 2013-01-08 09:32:27,765 INFO  context.MysqlRuntimeContext - Amoeba for Mysql cur  
    4. rent versoin=5.1.45-mysql-amoeba-proxy-2.2.0  
    5. log4j:WARN ip access config load completed from file:D:JavaToolsamoeba-mysql-b  
    6. inary-2.2.0in../conf/access_list.conf  
    7. 2013-01-08 09:32:27,921 INFO  net.ServerableConnectionManager - Amoeba for Mysql  
    8.  listening on 0.0.0.0/0.0.0.0:8066.  
    9. 2013-01-08 09:32:27,921 INFO  net.ServerableConnectionManager - Amoeba Monitor S  
    10. erver listening on /127.0.0.1:40170.  

    2、连接Amoeba

    通过mysql客户端连接Amoeba,端口指定为8066,然后还像以前操作MySQL一样进行操作:

    Dos代码  收藏代码
    1. D:>mysql -P8066 -uroot -pchenfeng123  
    2. Welcome to the MySQL monitor.  Commands end with ; or g.  
    3. Your MySQL connection id is 21616774 to server version: 5.1.45-mysql-amoeba-prox  
    4. y-2.2.0  
    5.   
    6. Type 'help;' or 'h' for help. Type 'c' to clear the buffer.  
    7.   
    8. mysql>  

    3、验证数据的查询

    查询yunzhu库下的user_info表的数据,如下:

    Sql代码  收藏代码
    1. mysql> select * from yunzhu.user_info;  
    2. +--------+-----------+  
    3. | USERID | USERNAME  |  
    4. +--------+-----------+  
    5. |    108 | Jiang Su  |  
    6. |    200 | NanJing   |  
    7. |     73 | Chen Feng |  
    8. |     88 | China     |  
    9. +--------+-----------+  
    10. rows in set (0.02 sec)  

    可以看到,现在查到了两个数据库节点中的user_info表中的所有记录。

     

    4、验证数据的插入

    这里插入两条数据,一条USERID为55,另一条USERID为155,如下:

    Dos代码  收藏代码
    1. mysql> insert into yunzhu.user_info(USERID,USERNAME) values(55,'test55');  
    2. Query OK, 1 row affected (0.13 sec)  
    3.   
    4. mysql> insert into yunzhu.user_info(USERID,USERNAME) values(155,'test155');  
    5. Query OK, 1 row affected (0.05 sec)  

    查询数据库节点1:

    Dos代码  收藏代码
    1. D:>mysql -uroot -pchenfeng  
    2. Welcome to the MySQL monitor.  Commands end with ; or g.  
    3. Your MySQL connection id is 33 to server version: 5.0.18-nt  
    4.   
    5. Type 'help;' or 'h' for help. Type 'c' to clear the buffer.  
    6.   
    7. mysql> select * from yunzhu.user_info;  
    8. +--------+-----------+  
    9. | USERID | USERNAME  |  
    10. +--------+-----------+  
    11. |     55 | test55    |  
    12. |     73 | Chen Feng |  
    13. |     88 | China     |  
    14. +--------+-----------+  
    15. 3 rows in set (0.00 sec)  

    查询数据库节点2:

    Dos代码  收藏代码
    1. D:>mysql -uroot -pchenfeng -h10.167.157.176  
    2. Welcome to the MySQL monitor.  Commands end with ; or g.  
    3. Your MySQL connection id is 34 to server version: 5.0.18-nt  
    4.   
    5. Type 'help;' or 'h' for help. Type 'c' to clear the buffer.  
    6.   
    7. mysql> select * from yunzhu.user_info;  
    8. +--------+----------+  
    9. | USERID | USERNAME |  
    10. +--------+----------+  
    11. |    108 | Jiang Su |  
    12. |    155 | test155  |  
    13. |    200 | NanJing  |  
    14. +--------+----------+  
    15. 3 rows in set (0.00 sec)  

    可以发现USERID为55的记录插入到了数据库节点1中,USERID为155的记录插入到了数据库节点2中。

    因为根据rule.xml中的切分规则,USERID小于等于100的的记录存在数据库节点1中,而大于100的则存在数据库节点2中。

    四、注意一些限制

    这是我在实践中发现的,刚开始不知道存在这样的限制,以致于浪费了很多时间,以为配置有问题,搞了很久才发现原来是因为这些限制才导致没有出现预期的结果,所以必须要注意:

    1、不管是查询和插入,每条都必须显式地指定数据库名(yunzhu),否则只会从一个数据库节点中查询数据,或者所有数据全部会插入一个数据库节点中。

    2、插入数据时,必须显式地指定列名,如“insert into yunzhu.user_info(USERID,USERNAME)”,否则切分规则不会生效,所有记录都会插入到一个数据库节点中。

    --------------------------------------------------------------------------------

    Mysql的主从复制的读写分离之Amoeba实现

    以前写过了一篇Mysql的主从复制,但没有实现Mysql的主从复制的读写分离。

    关于读写分离:

      读写分离(Read/Write Splitting),基本的原理是让主数据库处理事务性增、改、删、操作(INSERT、UPDATE、DELETE),而从数据库处理SELECT查询操作。数据库复制被用来把事务性操作导致的变更同步到集群中的从数据库。

    关于Mysql的读写分离实现大致有三种:

    1、 程序修改Mysql操作类

       就以程序来完成Mysql的读写操作,如以PHP程序、java程序等解决此需求。

    优点:直接和数据库通信,简单快捷的读写分离和随机的方式实现的负载均衡,权限独立分配

    缺点:自己维护更新,增减服务器上的代码处理。

    2、 mysql-proxy

      MySQL-Proxy是处在你的MySQL数据库客户和服务端之间的程序,它还支持嵌入性脚本语言Lua。这个代理可以用来分析、监控和变换(transform)通信数据,它支持非常广泛的使用场景:

    • 负载平衡和故障转移处理
    • 查询分析和日志
    • SQL宏(SQL macros)
    • 查询重写(quer rewriting)
    • 执行shell命令

    优点:直接实现读写分离和负载均衡,不用修改代码,master和slave用同一个账号

    缺点:字符集问题,lua语言编程,还只是alpha版本,时间消耗有点高

    3、 Amoeba

    参考官网:http://amoeba,meidusa.com/ 
    优点:直接实现读写分离和负载均衡,不用修改代码,有很灵活的数据解决方案
    缺点:自己分配账户,和后端数据库权限管理独立,权限处理不够灵活

    以上是三种常见的Mysql的读写分离方法。在这建议用第三种也就是amoeba来实现 

    关于Amoeba

    Amoeba(变形虫)项目,该开源框架于2008年开始发布一款Amoeba for Mysql软件。这个软件致力于Mysql的分布式数据库前端代理层,它主要在应用层访问Mysql的时候充当SQL路由功能,专注于分布式数据库代理层(Database Proxy)开发。位于Client、DB Server(s)之间,对客户透明。具有负载均衡、高可用性、SQL过滤、读写分离、可路由相关的到目标数据库、可并发请求多台数据库合并结果。通过Amoeba你能够完成多数据源的高可用、负载均衡、数据切片的功能,目前Amoeba已在很多企业的生产线上使用。

    下面就来把 Mysql的主从复制和读写分离完整的实现一下。

    先来做Mysql的主从复制。

    我实现的环境如下:

    System:Centos 5.4 32bit

    主:192.168.1.107

    从:192.168.1.139

    读写分离:192.168.1.183

    拓扑图如下:

    MySql的主从复制:

    对主MysqL服务器,主要是开启二进制日志,这个默认是开启的,在配置文件中:

    # vim /etc/my.cnf

    server-id = 1 (默认为1)

    log-bin = mysql-bin (这个也是默认开启的)

    下面连接到mysql数据库中创建一个用户并赋予复制权限。

    mysql> GRANT REPLICATION CLIENT,REPLICATION SLAVE ON *.* TO 'repl'@'192.168.1.139' IDENTIFIED BY "123456";

    这样在主服务器上操作暂时完成了。

    下面来在从服务器上操作:

    修改主配置文件:my.cnf

    1. # vim /etc/my.cnf 
    2. 定位到 server-id = 
    3. 修改为:server-id = 
    4. 添加如下内容: 
    5. relayrelay-log = relay-bin 
    6. relayrelay-log-index = relay-bin.index 
    7. 修改完成后,保存退出; 
    8. # service mysqld restart 

    因为在主mysql中已经有数据了,所以要把主服务器的数据导入到从服务器中,所以在主服务器上的操作:

    1. # mysqldump --all-databases --lock-all-tables --master-data=> /tmp/slave.sql  
    2. 导出后复制到从服务器上: 
    3. # scp /tmp/slave.sql 192.168.1.139:/tmp/ 
    4. 进入到从服务器上,导入数据。 
    5. # mysql < /tmp/slave.sql 

    以上操作完成后就可以做把主从连接在一起了。

    在从服务器上进入数据库中

    1. mysql> CHANGE MASTER TO MASTER_HOST='192.168.1.107',MASTER_USER='repl',MASTER_PASSWORD='123456'; 

    下面就可以在从服务器上开启复制了

    mysql> start slave;

    查看是否连接成功:

    1. mysql> show slave statusG 
    2. 如下两行出现则表明主从复制成功: 
    3.  
    4. Slave_IO_Running: Yes 
    5. Slave_SQL_Running: Yes 

    可在主服务器上创建一个数据库或表来在从服务器上来验证一下。

    下面来进行最为核心的内容——读写分离

    下面的操作要在读写分离的服务器上操作也就是:192.168.1.183

    Amoeba的安装:

    安装Amoeba前要先安装JDK,因为Amoeba是用java开发的所要有JDK支持。

    1. # java -version 
    2. java version "1.6.0_33" 
    3. Java(TM) SE Runtime Environment (build 1.6.0_33-b04) 
    4. Java HotSpot(TM) Server VM (build 20.8-b03, mixed mode) 

    如果没有安装JDK,要先安装,方法如下 :

    1. 去oracle官网下载jdk安装包后,安装jdk  
    2. # chmod 755 jdk-6u33-linux-i586.bin  
    3. # ./jdk-6u33-linux-i586.bin  
    4. 默认安装到/usr/java/jdk1.6.0_33 
    5. 下面来修改环境变量: 
    6. # vim /etc/profile 
    7. 添加如下行: 
    8. export JAVA_HOME=/usr/java/jdk1.6.0_33 
    9. export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar 
    10. export PATH=$PATH:$JAVA_HOME/bin 
    11. 保存退出! 
    12. # source /etc/profile \使之生效 
    13. 查看: 
    14. # java -version 
    15. java version "1.6.0_33" 
    16. Java(TM) SE Runtime Environment (build 1.6.0_33-b04) 
    17. Java HotSpot(TM) Server VM (build 20.8-b03, mixed mode) 

    安装完成后就可以安装Amoeba了

    下载:

    1. wget http://nchc.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz 

    安装:

    1. # mkdir /usr/local/amoeba 
    2. # mv amoeba-mysql-binary-2.1.0-RC5.tar.gz /usr/local/amoeba  
    3. # cd /usr/local/amoeba 
    4. # tar zxvf amoeba-mysql-binary-2.1.0-RC5.tar.gz 

    解压后就完成了。下面要做的就是配置。

    1. # cd /usr/local/amoeba  \主要是配置下面两个文件 
    2. dbServer.xml  \ 定义连接数据库的信息
    3. amoeba.xml  \ 定义读写分离的节点管理信息

    下面就来配置一下。

    # cd /usr/local/amoeba

    # vim dbServer.xml

    1. <?xml version="1.0" encoding="gbk"?> 
    2.  
    3. <!DOCTYPE amoeba:dbServers SYSTEM "dbserver.dtd"
    4. <amoeba:dbServers xmlns:amoeba="http://amoeba.meidusa.com/"
    5.  
    6.                 <!--  
    7.                         Each dbServer needs to be configured into a Pool, 
    8. 每个dbServer需要配置一个pool,如果多台平等的mysql需要进行loadBalance,
    9. 平台已经提供一个具有负载均衡能力的objectPool:
    10. 简单的配置是属性加上virtual="true",该Pool不允许配置factoryConfig
    11. 或者自己写一个ObjectPool
       
    12.                          such as 'multiPool' dbServer    
    13.                 --
    14.  
    15.         <dbServer name="abstractServer" abstractive="true"
    16.                 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory"
    17.                         <property name="manager">${defaultManager}</property
    18.                         <property name="sendBufferSize">64</property
    19.                         <property name="receiveBufferSize">128</property
    20.  
    21.                         <!-- mysql port --> 
    22.                         <property name="port">3306</property
    23.   \这个是后端数据的端口
    24.                         <!-- mysql schema --> 
    25.                         <property name="schema">test</property
    26.   \这个是后端默认的数据库
    27.                         <!-- mysql user --> 
    28.                         <property name="user">root</property
    29.  
    30.                         <!--  mysql password 
    31.                         <property name="password">password</property
    32.                         --
    33.                 </factoryConfig
    34.  
    35.                 <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool"
    36.                         <property name="maxActive">500</property
    37.                         <property name="maxIdle">500</property
    38.                         <property name="minIdle">10</property
    39.                         <property name="minEvictableIdleTimeMillis">600000</property
    40.                         <property name="timeBetweenEvictionRunsMillis">600000</property
    41.                         <property name="testOnBorrow">true</property
    42.                         <property name="testWhileIdle">true</property
    43.                 </poolConfig
    44.         </dbServer
    45.  \下面的配置是定义一个主节点和一个从节点。
    46.         <dbServer name="master"  parent="abstractServer">  \定义一个主节点
    47.                 <factoryConfig
    48.                         <!-- mysql ip --> 
    49.                         <property name="ipAddress">192.168.1.107</property
    50.                         <property name="user">root</property>  \连接数据库的用户名
    51.                         <property name="password">123456</property>  \连接数据库的密码
    52.                 </factoryConfig
    53.         </dbServer
    54.         <dbServer name="slave"  parent="abstractServer">  \定义一个从节点
    55.                 <factoryConfig
    56.                         <!-- mysql ip --> 
    57.                         <property name="ipAddress">192.168.1.139</property
    58.                         <property name="user">root</property
    59.                         <property name="password">123456</property
    60.                 </factoryConfig
    61.         </dbServer
    62.   \定义池,把master和slave加入
    63.         <dbServer name="server1" virtual="true">  \server1是要把master节点加入
    64.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"
    65.                         <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->   < !  -- 负载均衡参数1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
    66.                         <property name="loadbalance">1</property
    67.  
    68.                         <!-- Separated by commas,such as: server1,server2,server1 --> 
    69.                         <property name="poolNames">master</property>  <!--
    70. 参与该pool负载均衡的poolName列表以逗号分割 这里只一个主节点所以就一个
    71.  -->
    72.                 </poolConfig
    73.         </dbServer
    74.         <dbServer name="server2" virtual="true">  \server2是要把slave节点加入
    75.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool"
    76.                         <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA--> 
    77.                         <property name="loadbalance">1</property
    78.  
    79.                         <!-- Separated by commas,such as: server1,server2,server1 --> 
    80.                         <property name="poolNames">slave</property
    81.                 </poolConfig
    82.         </dbServer
    83.  
    84. </amoeba:dbServers

    下面来配置amoeba.xml文件

    1. <?xml version="1.0" encoding="gbk"?> 
    2.  
    3. <!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd"
    4. <amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/"
    5.  
    6.         <proxy
    7.  
    8.                 <!-- service class must implements com.meidusa.amoeba.service.Service --> 
    9.                 <service name="Amoeba for Mysql" class="com.meidusa.amoeba.net.ServerableConnectionManager"
    10.                         <!-- port --> 
    11.                         <property name="port">8066</property
    12.   \定义amoeba读写分离proxy对外代理的端口
    13.                         <!-- bind ipAddress --> 
    14.                         <!--  
    15.                         <property name="ipAddress">127.0.0.1</property> \这个是绑定端口的ip
    16. 如新注释掉了,说明8066端口绑定在0.0.0.0/0.0.0.0 上面
    17.                          --> 
    18.  
    19.                         <property name="manager">${clientConnectioneManager}</property
    20.  
    21.                         <property name="connectionFactory"
    22.                                 <bean class="com.meidusa.amoeba.mysql.net.MysqlClientConnectionFactory"
    23.                                         <property name="sendBufferSize">128</property
    24.                                         <property name="receiveBufferSize">64</property
    25.                                 </bean
    26.                         </property
    27.  
    28.                         <property name="authenticator"
    29.                                 <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator"
    30.  
    31.                                         <property name="user">root</property
    32.   \定义通过amoeba登录的用户名
    33.                                         <property name="password">123456</property
    34.   \相应的这个就是密码了。 定义proxy的管理帐号密码,客户端和程序只需要连接proxy的帐号密码即可,相当于中间接封装
    35.                                         <property name="filter"
    36.                                                 <bean class="com.meidusa.amoeba.server.IPAccessController"
    37.                                                         <property name="ipFile">${amoeba.home}/conf/access_list.conf</property
    38.                                                 </bean
    39.                                         </property
    40.                                 </bean
    41.                         </property
    42.  
    43.                 </service
    44.  
    45.                 <!-- server class must implements com.meidusa.amoeba.service.Service --> 
    46.                 <service name="Amoeba Monitor Server" class="com.meidusa.amoeba.monitor.MonitorServer"
    47.                         <!-- port --> 
    48.                         <!--  default value: random number 
    49.                         <property name="port">9066</property
    50.                         --
    51.                         <!-- bind ipAddress --> 
    52.                         <property name="ipAddress">127.0.0.1</property
    53.                         <property name="daemon">true</property
    54.                         <property name="manager">${clientConnectioneManager}</property
    55.                         <property name="connectionFactory"
    56.                                 <bean class="com.meidusa.amoeba.monitor.net.MonitorClientConnectionFactory"></bean
    57.                         </property
    58.  
    59.                 </service
    60.  
    61.                 <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext"
    62.                         <!-- proxy server net IO Read thread size --> 
    63.                         <property name="readThreadPoolSize">20</property
    64.  
    65.                         <!-- proxy server client process thread size --> 
    66.                         <property name="clientSideThreadPoolSize">30</property
    67.  
    68.                         <!-- mysql server data packet process thread size --> 
    69.                         <property name="serverSideThreadPoolSize">30</property
    70.  
    71.                         <!-- per connection cache prepared statement size  --> 
    72.                         <property name="statementCacheSize">500</property
    73.  
    74.                         <!-- query timeout( default: 60 second , TimeUnit:second) --> 
    75.                         <property name="queryTimeout">60</property
    76.                 </runtime
    77.  
    78.         </proxy
    79.  
    80.         <!--  
    81.                 Each ConnectionManager will start as thread 
    82.                 manager responsible for the Connection IO read , Death Detection 
    83. \每个ConnectionManager 都做为一个线程启动
    84. \manager 负责Connection IO读写/死亡检测
    85.         --
    86.         <connectionManagerList
    87.                 <connectionManager name="clientConnectioneManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper"
    88.                         <property name="subManagerClassName">com.meidusa.amoeba.net.ConnectionManager</property
    89.                         <!--  
    90.                           default value is avaliable Processors  
    91.                         <property name="processors">5</property
    92.                          --
    93.                 </connectionManager
    94.                 <connectionManager name="defaultManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper"
    95.                         <property name="subManagerClassName">com.meidusa.amoeba.net.AuthingableConnectionManager</property
    96.  
    97.                         <!--  
    98.                           default value is avaliable Processors  
    99.                         <property name="processors">5</property
    100.                          --
    101.                 </connectionManager
    102.         </connectionManagerList
    103.  
    104.                 <!-- default using file loader --> 
    105.         <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader"
    106.                 <property name="configFile">${amoeba.home}/conf/dbServers.xml</property
    107.         </dbServerLoader
    108.  
    109.         <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter"
    110.                 <property name="ruleLoader"
    111.                         <bean class="com.meidusa.amoeba.route.TableRuleFileLoader"
    112.                                 <property name="ruleFile">${amoeba.home}/conf/rule.xml</property
    113.                                 <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property
    114.                         </bean
    115.                 </property
    116.                 <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property
    117.                 <property name="LRUMapSize">1500</property
    118.                 <property name="defaultPool">server1</property
    119.  \定义默认的池,一些除了SELECTUPDATEINSERTDELETE的语句都会在defaultPool执行
    120.  
    121.                 <property name="writePool">server1</property>
    122. \定义写的池,这里的server1就是在dbServer.xml中的server1
    123.                 <property name="readPool">server2</property
    124.   \定义读的池,这里的server2就是在dbserver.xml中的server2
    125.                 <property name="needParse">true</property
    126.         </queryRouter
    127. </amoeba:configuration

    配置完成后就可以启动amoeba了。

    1. # cd /usr/local/amoeba/bin 
    2. # ./amoeba  
    3. amoeba start|stop 
    4. # ./amoeba start &  \会输出下面的信息 
    5. [1] 6789 
    6. log4j:WARN log4j config load completed from file:/usr/local/amoeba/conf/log4j.xml 
    7. 2012-09-06 17:56:01,619 INFO  context.MysqlRuntimeContext - Amoeba for Mysql current versoin=5.1.45-mysql-amoeba-proxy-2.1.0-RC5 
    8. log4j:WARN ip access config load completed from file:/usr/local/amoeba/conf/access_list.conf 
    9. 2012-09-06 17:56:01,987 INFO  net.ServerableConnectionManager - Amoeba for Mysql listening on 0.0.0.0/0.0.0.0:8066.  
    10. 2012-09-06 17:56:01,992 INFO  net.ServerableConnectionManager - Amoeba Monitor Server listening on /127.0.0.1:6376. 
    11. 从上面的信息中可以看到8066端口打开了。可查看进程: 
    12. # ps aux | grep amoeba 
    13. root   6789  4.1  1.5 408940 31908 pts/1    Sl   17:56   0:00 /usr/java/jdk1.6.0_33/bin/java -server -Xms256m -Xmx256m -Xss12sworlds.conf=/usr/local/amoeba/bin/amoeba.classworlds -classpath /usr/local/amoeba/lib/classworlds-1.0.jar org.co 
    14. root   6820  0.0  0.0   5112   680 pts/1    S+   17:56   0:00 grep amoeba 
    15. # netstat -tlnp 
    16. Proto Recv-Q Send-Q Local Address               Foreign Address             State       PID/Program name    
    17. tcp        0      0 0.0.0.0:111                 0.0.0.0:*                   LISTEN      -                    
    18. tcp        0      0 0.0.0.0:688                 0.0.0.0:*                   LISTEN      -                    
    19. tcp        0      0 127.0.0.1:631               0.0.0.0:*                   LISTEN      -                    
    20. tcp        0      0 127.0.0.1:25                0.0.0.0:*                   LISTEN      -                    
    21. tcp        0      0 :::8066                     :::*                        LISTEN      6789/java            
    22. tcp        0      0 ::ffff:127.0.0.1:6376       :::*                        LISTEN      6789/java            
    23. tcp        0      0 :::22                       :::*                        LISTEN      -              

    从上面的一些信息可以看到amoeba已经启动,下面就可以测试一下了。

    下面来做一测试:

    为了更好的看到测试结果,要做以下这些步骤:

    测试之前要先保证amoeba-server有访问两个主从服务器test库的权限,在主mysql上执行:

    1. mysql> grant all privileges on *.* to 'root'@'192.168.1.183' identified by "123456"; 
    2. mysql> flush privileges; 
    3. 用户创建完成后就可以登录了 
    4. # mysql -uroot -p123456 -h192.168.1.183 -P8066 

    下面开始测试:

    先让主从开始复制,即在从服务器上执行:

    mysql> slave start;

    再从读写分离的服务器上登录:

    # mysql -uroot -p123456 -h192.168.1.183 -P8066

    进入之后,先来创建一个数据库zhou,然后在这个数据库中创建一个表test 

    mysql> create database zhou;

    mysql> use zhou;

    mysql> create table test (id int(10), name varchar(20),adress varchar(30));

    做完这些,回到从服务器上执行:

    mysql> slave stop;

    接着在主从服务器上各加入一条不同的数据。

    在主上:

    mysql> use zhou;

    mysql> insert into test ('1','zhou','this_is_master');

    在从上:

    mysql> use zhou;

    mysql> insert into test ('2','zhou','this_is_slave');

    完成后就可以在读写分离服务器上测试读写了

    在读写分离服务器上:

    mysql> use zhou;

    mysql> select * from test;

    +------+------+---------------+

    | id   | name | address       |

    +------+------+---------------+

    |    2 | zhou | this_is_slave | 

    +------+------+---------------+

    1 row in set (0.01 sec)

    从结果可以看出数据是读的从服务器上的数据,然后我们直接插入数据,再来测试

    mysql> insert into test values('3','hhh','test_write');

    Query OK, 1 row affected (0.01 sec)

    mysql> select * from test;

    +------+------+---------------+

    | id   | name | address       |

    +------+------+---------------+

    |    2 | zhou | this_is_slave | 

    +------+------+---------------+

    1 row in set (0.00 sec)

    结果显示出的数据没有改变,因为我们把主从复制停了,所以数据没有同步,从查询的结果可以看到,数据还是来自从服务器。

    然后们再在主服务器上查询可以看到:

    mysql> select * from test;

    +------+------+--------------- +

    | id   | name | address        |

    +------+------+--------------- +

    |    1 | zhou | this_is_master | 

    +------+------+--------------- +

    |    3 | hhh  |  test_write    | 

    +------+------+--------------- +

    从上面的结果可以看出,数据的读写分离成功了。

    以上就是mysql数据库的主从复制以及读写分离的整个过程。文中可能还存在不完整或者出错的地方,还请大家指出来,谢谢了。

  • 相关阅读:
    Angular $http解析通过接口获得的json数据
    Python基础(十四)—装饰器 wrapper
    Python基础(十二)—面向对象拾遗(__slots__、@property、枚举类、元类)
    Python基础(十三)—切片、yield、生成器、序列化JSON
    Python基础(十一)—魔法方法(构造析构、属性魔法、算数魔法、类型魔法等)
    Python基础(十)—面向对象的深入讲解(继承、Mixin编程机制等)
    Python基础(九)—异常except、else&with、异常的名称层次
    Python基础(八)—编码详解(ASCII、GBK、Unicode、UTF-8等)、decode&encode
    Python基础(七)—输入输出(open、os、pickle)
    Python基础(六)—函数式编程(内部函数、闭包、lambda、filter/map/reduce/sorce、偏函数)
  • 原文地址:https://www.cnblogs.com/fx2008/p/4092748.html
Copyright © 2011-2022 走看看