• mysqlmmm+amoeba+keepalived实现mysql高可用和读写分离(二)


    一、利用amoeba实现高可用下的读写分离

    1、  关于amoeba的介绍和安装我这里不做介绍了,请查看:http://blog.chinaunix.net/u3/93755/showart.php?id=2363202,有什么问题我们再一起讨论。

    2、  Amoebamysql-mmm架构下的配置

    配置的除了amoeba的监听IP外其他的均采用上面mmm分配的浮动IP,因为当出现故障后,浮动IP会自动分配到正常的server上。amoeba.xml的配置如下:

    <?xml version="1.0" encoding="gbk"?>

     

    <!DOCTYPE amoeba:configuration SYSTEM "amoeba.dtd">

    <amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/">

     

           <server>

                  <!-- proxy server绑定的端口 -->

                    <property name="port">8066</property>

                   

                    <!-- proxy server绑定的IP -->

                    <property name="ipAddress">192.168.1.163</property>

                    <!-- proxy server net IO Read thread size -->

                    <property name="readThreadPoolSize">20</property>

                   

                    <!-- proxy server client process thread size -->

                    <property name="clientSideThreadPoolSize">30</property>

                   

                    <!-- mysql server data packet process thread size -->

                    <property name="serverSideThreadPoolSize">30</property>

                   

                    <!-- socket Send and receive BufferSize(unit:K)  -->

                    <property name="netBufferSize">128</property>

                   

                    <!-- Enable/disable TCP_NODELAY (disable/enable Nagle's algorithm). -->

                    <property name="tcpNoDelay">true</property>

                   

                    <property name="user">root</property>

                    <property name="password">password</property>

                   

                    <!-- query timeout( default: 60 second , TimeUnit:second) -->

                    <property name="queryTimeout">60</property>

            </server>

           

            <!--

                    每个ConnectionManager都将作为一个线程启动。

                    manager负责Connection IO读写/死亡检测

            -->

            <connectionManagerList>

                    <connectionManager name="defaultManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">

                             <property name="subManagerClassName">com.meidusa.amoeba.net.AuthingableConnectionManager</property>

                            

                             <!--

                               default value is avaliable Processors

                             <property name="processors">5</property>

                              -->

                    </connectionManager>

            </connectionManagerList>

           

            <dbServerList>

                    <!--

                             一台mysqlServer 需要配置一个pool,

                             如果多台 平等的mysql需要进行loadBalance,

                             平台已经提供一个具有负载均衡能力的objectPool:com.meidusa.amoeba.mysql.server.MultipleServerPool

                             简单的配置是属性加上 virtual="true",该Pool 不允许配置factoryConfig

                             或者自己写一个ObjectPool。

                    -->

                    <dbServer name="server1">

                            

                             <!-- PoolableObjectFactory实现类 -->

                             <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">

                                     <property name="manager">defaultManager</property>

                                    

                                     <!-- 真实mysql数据库端口 -->

                                     <property name="port">3306</property>

                                    

                                     <!-- 真实mysql数据库IP -->

                                     <property name="ipAddress">192.168.1.113</property>

                                     <property name="schema">test</property>

                                    

                                     <!-- 用于登陆mysql的用户名 -->

                                     <property name="user">zhang</property>

                                    

                                     <!-- 用于登陆mysql的密码 -->

                                     <property name="password">zhang123</property>

                                    

                             </factoryConfig>

                            

                             <!-- ObjectPool实现类 -->

                             <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">

                                     <property name="maxActive">200</property>

                                     <property name="maxIdle">200</property>

                                     <property name="minIdle">10</property>

                                     <property name="minEvictableIdleTimeMillis">600000</property>

                                     <property name="timeBetweenEvictionRunsMillis">600000</property>

                                     <property name="testOnBorrow">true</property>

                                     <property name="testWhileIdle">true</property>

                             </poolConfig>

                    </dbServer>

                   

     

                    <dbServer name="server2">

                            

                             <!-- PoolableObjectFactory实现类 -->

                             <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">

                                     <property name="manager">defaultManager</property>

                                    

                                     <!-- 真实mysql数据库端口 -->

                                     <property name="port">3306</property>

                                    

                                     <!-- 真实mysql数据库IP -->

                                     <property name="ipAddress">192.168.1.111</property>

                                     <property name="schema">test</property>

                                    

                                     <!-- 用于登陆mysql的用户名 -->

                                     <property name="user">zhang</property>

                                    

                                     <!-- 用于登陆mysql的密码 -->

                                     <property name="password">zhang123</property>

                                    

                             </factoryConfig>

                            

                             <!-- ObjectPool实现类 -->

                             <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">

                                     <property name="maxActive">200</property>

                                     <property name="maxIdle">200</property>

                                     <property name="minIdle">10</property>

                                     <property name="minEvictableIdleTimeMillis">600000</property>

                                     <property name="timeBetweenEvictionRunsMillis">600000</property>

                                     <property name="testOnBorrow">true</property>

                                     <property name="testWhileIdle">true</property>

                             </poolConfig>

                    </dbServer>

     

     

                    <dbServer name="server3">

                            

                             <!-- PoolableObjectFactory实现类 -->

                             <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">

                                    <property name="manager">defaultManager</property>

                                    

                                     <!-- 真实mysql数据库端口 -->

                                     <property name="port">3306</property>

                                    

                                     <!-- 真实mysql数据库IP -->

                                     <property name="ipAddress">192.168.1.112</property>

                                     <property name="schema">test</property>

                                    

                                     <!-- 用于登陆mysql的用户名 -->

                                     <property name="user">zhang</property>

                                    

                                     <!-- 用于登陆mysql的密码 -->

                                     <property name="password">zhang123</property>

                                    

                             </factoryConfig>

                            

                             <!-- ObjectPool实现类 -->

                             <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">

                                     <property name="maxActive">200</property>

                                     <property name="maxIdle">200</property>

                                     <property name="minIdle">10</property>

                                     <property name="minEvictableIdleTimeMillis">600000</property>

                                     <property name="timeBetweenEvictionRunsMillis">600000</property>

                                     <property name="testOnBorrow">true</property>

                                     <property name="testWhileIdle">true</property>

                             </poolConfig>

                    </dbServer>

     

     

                    <dbServer name="server4">

                            

                             <!-- PoolableObjectFactory实现类 -->

                             <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">

                                     <property name="manager">defaultManager</property>

                                    

                                     <!-- 真实mysql数据库端口 -->

                                     <property name="port">3306</property>

                                    

                                     <!-- 真实mysql数据库IP -->

                                     <property name="ipAddress">192.168.1.114</property>

                                     <property name="schema">test</property>

                                    

                                     <!-- 用于登陆mysql的用户名 -->

                                     <property name="user">zhang</property>

                                    

                                     <!-- 用于登陆mysql的密码 -->

                                     <property name="password">zhang123</property>

                                    

                             </factoryConfig>

                            

                             <!-- ObjectPool实现类 -->

                             <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">

                                     <property name="maxActive">200</property>

                                     <property name="maxIdle">200</property>

                                     <property name="minIdle">10</property>

                                     <property name="minEvictableIdleTimeMillis">600000</property>

                                     <property name="timeBetweenEvictionRunsMillis">600000</property>

                                     <property name="testOnBorrow">true</property>

                                     <property name="testWhileIdle">true</property>

                             </poolConfig>

                    </dbServer>

     

     

                    <dbServer name="server5">

                            

                             <!-- PoolableObjectFactory实现类 -->

                             <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">

                                     <property name="manager">defaultManager</property>

                                    

                                     <!-- 真实mysql数据库端口 -->

                                     <property name="port">3306</property>

                                    

                                     <!-- 真实mysql数据库IP -->

                                     <property name="ipAddress">192.168.1.115</property>

                                     <property name="schema">test</property>

                                    

                                     <!-- 用于登陆mysql的用户名 -->

                                     <property name="user">zhang</property>

                                    

                                     <!-- 用于登陆mysql的密码 -->

                                     <property name="password">zhang123</property>

                                    

                             </factoryConfig>

                            

                             <!-- ObjectPool实现类 -->

                             <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">

                                     <property name="maxActive">200</property>

                                     <property name="maxIdle">200</property>

                                     <property name="minIdle">10</property>

                                     <property name="minEvictableIdleTimeMillis">600000</property>

                                     <property name="timeBetweenEvictionRunsMillis">600000</property>

                                     <property name="testOnBorrow">true</property>

                                     <property name="testWhileIdle">true</property>

                             </poolConfig>

                    </dbServer>

     

     

     

                   

                    <dbServer name="master" virtual="true">

                             <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">

                                     <!-- 负载均衡参数 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->

                                     <property name="loadbalance">1</property>

                                    

                                     <!-- 参与该pool负载均衡的poolName列表以逗号分割 -->

                                     <property name="poolNames">server1</property>

                             </poolConfig>

                    </dbServer>

     

                    <dbServer name="slave" virtual="true">

                             <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">

                                     <!-- 负载均衡参数 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->

                                     <property name="loadbalance">1</property>

                                    

                                     <!-- 参与该pool负载均衡的poolName列表以逗号分割 -->

                                     <property name="poolNames">server2,server3,server4,server5</property>

                             </poolConfig>

                    </dbServer>

                   

            </dbServerList>

           

            <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter">

                    <property name="ruleConfig">${amoeba.home}/conf/rule.xml</property>

                    <property name="functionConfig">${amoeba.home}/conf/functionMap.xml</property>

                    <property name="ruleFunctionConfig">${amoeba.home}/conf/ruleFunctionMap.xml</property>

                    <property name="LRUMapSize">1500</property>

                    <property name="defaultPool">master</property>

                    <property name="writePool">master</property>

                    <property name="readPool">slave</property>

                    <property name="needParse">true</property>

            </queryRouter>

    </amoeba:configuration>

     

    3、  启动amoeba

           /usr/local/amoeba/bin/amoeba &  

    检验启动是否成功(使用的是默认的8066端口):

    [root@server3 ~]# ps aux | grep amoeba

    root     15390  0.2 21.7 411800 55684 pts/0    Sl   Nov09   0:13 /usr/java/jdk1.6/bin/java -server -Xms256m -Xmx256m -Xss128k -Damoeba.home=/usr/local/amoeba -Dclassworlds.conf=/usr/local/amoeba/bin/amoeba.classworlds -classpath /usr/local/amoeba/lib/classworlds-1.0.jar org.codehaus.classworlds.Launcher

     

    4、  测试

    为了有权限,请在所有mysql-server上添加上面配置的用户名和密码,比如:

    grant all on test.* to zhang@'192.168.1.%' identified by 'zhang123';

    flush privileges;

    测试的时候比较麻烦,因为如果把主从停掉来看效果的话,mmm会将该同步状态有问题的服务器设置成REPLICATION_FAIL并将该主机上的浮动IP移动到正常服务器,比如:我将server4停掉后,就出出现如下现象:

    [root@server3 ~]#  mmm_control show

      db1(192.168.1.161) master/ONLINE. Roles: reader(192.168.1.114), reader(192.168.1.115)

      db2(192.168.1.162) master/ONLINE. Roles: reader(192.168.1.112), writer(192.168.1.113)

      db3(192.168.1.164) slave/REPLICATION_FAIL. Roles:

      db4(192.168.1.165) slave/ONLINE. Roles: reader(192.168.1.111)

    暂时没想到很好的测试办法。读写分离测试没有问题。

    最近手头没有空闲的机器来做压力测试。等有了机器了再对这个架构做下压力测试!

     

     

    二、利用keepalived实现amoeba高可用

    Keepalived简介:KeepalivedLinux下面实现VRRP 备份路由的高可靠性运行件。基于Keepalived设计的服务模式能够真正做到主服务器和备份服务器故障时IP瞬间无缝交接。从而提高系统的可用性

    1、  keepalived的安装(server6server7上都要安装):

    wget http://www.keepalived.org/software/keepalived-1.1.19.tar.gz
    tar zxvf keepalived-1.1.19.tar.gz
    cd keepalived-1.1.19
    ./configure --prefix=/usr/local/keepalived
    make
    make install
    cp /usr/local/keepalived/sbin/keepalived /usr/sbin/
    cp /usr/local/keepalived/etc/sysconfig/keepalived /etc/sysconfig/
    cp /usr/local/keepalived/etc/rc.d/init.d/keepalived /etc/init.d/
    mkdir /etc/keepalived
    cd /etc/keepalived/

     

    2、  keepalived的配置

    配置server6keepalived配置文件/etc/keepalived/keepalived.conf,内容如下:

    bal_defs {

            notification_email {

                   jimo291@gmail.com

            }

            notification_email_from jimo291@gmail.com

            smtp_server 127.0.0.1

            smtp_connect_timeout 30

            router_id test1

    }

     

     

    vrrp_instance VI_1 {

            state MASTER

            interface eth0

            virtual_router_id 51

            priority 100

            advert_int 1

            smtp_alert

            authentication {

                    auth_type PASS

                    auth_pass 123

            }

     

            virtual_ipaddress {

                    192.168.1.170

            }

    }

     

    配置server6keepalived配置文件/etc/keepalived/keepalived.conf,内容如下:

    bal_defs {

            notification_email {

                    jimo291@gmail.com

            }

            notification_email_from jimo291@gmail.com

            smtp_server 127.0.0.1

            smtp_connect_timeout 30

            router_id test2

    }

     

    vrrp_instance VI_1 {

            state BACKUP

            interface eth0

            virtual_router_id 51

            priority 80

            advert_int 1

            smtp_alert

            authentication {

                    auth_type PASS

                    auth_pass 123

            }

            virtual_ipaddress {

                    192.168.1.170

            }

    }

     

    3、  keepalived的启动:

    server6server7上执行如下命令启动:

    /etc/rc.d/init.d/keepalived start

    看看server6上是否绑定了虚拟IP192.168.1.170

    [root@server6 ~]# ip add | grep 192.168.1.170

    inet 192.168.1.170/32 scope global eth0

           可以看到已经成功绑定了192.168.1.170

    4、  测试

    停掉server6,看看虚拟IP192.168.1.170会不会自动切换到server7上。以及测试mysql -uroot -ppassword -h192.168.1.170登录,看看能否实现读写操作是否正常等等!

     

    备注:最后记得将所有的启动命令都写到/etc/rc.local文件中去,实现开机启动!

  • 相关阅读:
    一套C#语言的日志控制系统
    unity自义定摇杆
    2014 西安邀请赛小结
    Poj 1112 Team Them Up!
    Poj 1112 Rebuilding Roads(树形DP+背包)
    USACO Cow Pedigrees
    Poj 2284 That Nice Euler Circuit
    LA 3942 Remember the Word
    HDU 3065 病毒侵袭持续中
    HDU 2896 病毒侵袭
  • 原文地址:https://www.cnblogs.com/feihongwuhen/p/7170366.html
Copyright © 2020-2023  润新知