设为首页 收藏本站
查看: 850|回复: 1

[经验分享] Mysql的主从复制的读写分离之Amoeba实现

[复制链接]
累计签到:1 天
连续签到:1 天
发表于 2015-12-30 14:12:34 | 显示全部楼层 |阅读模式
关于读写分离:
  读写分离(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(变形虫)项目,专注 分布式数据库 proxy 开发。座落与Client、DB Server(s)之间。对客户端透明。具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。
主要解决:
降低 数据切分带来的复杂多数据库结构
提供切分规则并降低 数据切分规则 给应用带来的影响
降低db 与客户端的连接数
读写分离

二、为什么要用Amoeba
目前要实现mysql的主从读写分离,主要有以下几种方案:
1、  通过程序实现,网上很多现成的代码,比较复杂,如果添加从服务器要更改多台服务器的代码。
2、  通过mysql-proxy来实现,由于mysql-proxy的主从读写分离是通过lua脚本来实现,目前lua的脚本的开发跟不上节奏,而写没有完美的现成的脚本,因此导致用于生产环境的话风险比较大,据网上很多人说mysql-proxy的性能不高。
3、  自己开发接口实现,这种方案门槛高,开发成本高,不是一般的小公司能承担得起。
4、  利用阿里巴巴的开源项目Amoeba来实现,具有负载均衡、高可用性、sql过滤、读写分离、可路由相关的query到目标数据库,并且安装配置非常简单。国产的开源软件,应该支持,目前正在使用,不发表太多结论,一切等测试完再发表结论吧,哈哈!

三、快速架设amoeba,实现mysql主从读写分离
假设amoeba的前提条件:
n         Java SE 1.5 或以上 Amoeba 框架是基于JDK1.5开发的,采用了JDK1.5的特性。
n         支持Mysql 协议版本10(mysql 4.1以后的版本)。
n         您的网络环境至少运行有一个mysql 4.1以上的服务
       1、首先介绍下我的实验环境。
              System:    CentOS release 6.7
              Master mysql:172.16.1.52
              Slave mysql:172.16.1.51
              Amoeba server:  10.0.0.5
QQ截图20151230141209.png
安装数据库主从环境实现主从同步:
1.数据库安装(略)
2.主从同步
主库操作:
1
2
3
4
5
6
7
8
9
mysql -uroot -p123456 -S /data/3306/mysql.sock#登录数据库
mysql> grant replication slave on *.* to 'rep'@'172.16.1.%' identified by '123456';  #授权
mysql> flush privileges; #刷新权限
mysql> select user,host from mysql.user; #查看用户
mysql> show grants for ; #查看授权
mysql>  flush table with read lock; #锁表
需要授权一个用户备用:
mysql> grant select,insert,update,delete on ABC.* to zy@'172.16.1.%' identified by '123456';
mysql> quit #退出




打包备份同步到从库:

1
2
3
mysqldump -uroot -p123456 -S /data/3306/mysql.sock -B -F -R -x --master-data=2 -A --events|gzip >/server/backup/rep3306_$(date +%F).sql.gz   #打包
gzip -d rep3308_2015-12-27.sql.gz  #解压
mysql -uroot -p123456 -h172.16.1.51 -P3306< rep3308_2015-12-27.sql#同步到从库



从库操作:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
mysql -uroot -p123456#登录
#执行
CHANGE MASTER TO
MASTER_HOST='172.16.1.52',
MASTER_PORT=3306,
MASTER_USER='root',
MASTER_PASSWORD='123456';
===================================
mysql> start slave;
mysql> show slave status\G
注意:如果出现不必要的错误可以跳过,执行命令:
mysql> stop slave;
mysql> set global sql_slave_skip_counter =1;
mysql> start slave;
mysql> show slave status\G




测试(略)
提示:任意创建数据库表插入数据查看主从是否同步,到此为止主从同步完成!
Amoeba_server操作:
1
2
3
4
5
6
mkdir /home/oldboy/tools -p
mkdir /application/amoeba/ -p
cd /home/oldboy/tools/
上传两个文件:
1.jdk-6u37-linux-i586-rpm
2.amoeba-mysql-3.0.5-RC-distribution



配置Java环境变量:
vim  /etc/profile 添加如下
1
2
3
4
5
6
7
vim  /etc/profile 添加如下####for java
export JAVA_HOME=/usr/java/jdk1.6.0_37
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
#####for amoeba
export AMOEBA_HOME=/application/amoeba/
export PATH=$PATH:$AMOEBA_HOME/bin



1
2
3
4
使配置文件生效
. /etc/profile
查看Java版本号
java -version




操作:
1.
1
2
chmod 755 jdk-6u37-linux-i586-rpm.bin
./jdk-6u37-linux-i586-rpm.bin



2.
1
2
3
4
5
6
7
8
9
解压:
unzip amoeba-mysql-3.0.5-RC-distribution.zip
cd amoeba-mysql-3.0.5-RC
cp -rf * /application/amoeba/
cd /application/amoeba/
授权:
find amoeba/*  -type f|xargs chmod 644
find bin/* -type f|xargs chmod 755
注意:最好用ls -la查看一下权限是否修改成功



3.修改配置文件
a.dbServers.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,
  • 每个dbServer需要配置一个pool,如果多台平等的mysql需要进行loadBalance,
  • 平台已经提供一个具有负载均衡能力的objectPool:
  • 简单的配置是属性加上virtual="true",该Pool不允许配置factoryConfig
  • 或者自己写一个ObjectPool

  •                          such as 'multiPool' dbServer   
  •                 -->

  •         <dbServer name="abstractServer" abstractive="true">
  •                 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
  •                         <property name="manager">${defaultManager}</property>
  •                         <property name="sendBufferSize">64</property>
  •                         <property name="receiveBufferSize">128</property>

  •                         <!-- mysql port -->
  •                         <property name="port">3306</property>
  •                                   \\这个是后端数据的端口
  •                         <!-- mysql schema -->
  •                         <property name="schema">test</property>
  •                                     \\这个是后端默认的数据库
  •                         <!-- mysql user -->
  •                         <property name="user">zy</property>

  •                         <!--  mysql password
  •                         <property name="password">123456</property>
  •                         -->
  •                 </factoryConfig>

  •                 <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
  •                         <property name="maxActive">500</property>
  •                         <property name="maxIdle">500</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"  parent="abstractServer">   \\定义一个主节点
  •                 <factoryConfig>
  •                         <!-- mysql ip -->
  •                         <property name="ipAddress">172.16.1.52</property>
  •                         <property name="user">root</property>   \\连接数据库的用户名
  •                         <property name="password">123456</property>  \\连接数据库的密码
  •                 </factoryConfig>
  •         </dbServer>
  •         <dbServer name="slave"  parent="abstractServer">  \\定义一个从节点
  •                 <factoryConfig>
  •                         <!-- mysql ip -->
  •                         <property name="ipAddress">172.16.1.51</property>
  •                         <property name="user">root</property>
  •                         <property name="password">123456</property>
  •                 </factoryConfig>
  •         </dbServer>
  •             \\定义池,把master和slave加入
  •         <dbServer name="pool" virtual="true">  \\server1是要把master节点加入
  •                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
  •                         <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->                              < !  -- 负载均衡参数1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
  •                         <property name="loadbalance">1</property>

  •                         <!-- Separated by commas,such as: server1,server2,server1 -->
  •                         <property name="poolNames">master</property>  <!--


b.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.net.ServerableConnectionManager">                        
<!-- port -->      
<property name="port">3306</property>                              
<!-- bind ipAddress -->                         <!--        
<property name="ipAddress">127.0.0.1</property>
\\                        -->          <property name="manager">${clientConnectioneManager}</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="authenticator">

                              
<bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">                                       
<property name="user">zy</property>                                                            
<property name="password">123456</property>                                                                                          
<property name="filter">                                                
<bean class="com.meidusa.amoeba.server.IPAccessController">                                                         
<property name="ipFile">${amoeba.home}/conf/access_list.conf</property>  

                                               </bean>                     
                  
</property>                                 
</bean>                        
</property>               
  </service>               
   <!-- server class must implements com.meidusa.amoeba.service.Service -->               
<service name="Amoeba Monitor Server" class="com.meidusa.amoeba.monitor.MonitorServer">                        
<!-- port -->                     
    <!--  default value: random number                     
   <property name="port">3306</property>                     
   -->                        
<!-- bind ipAddress -->                        
<property name="ipAddress">127.0.0.1</property>                       
  <property name="daemon">true</property>                        
<property name="manager">${clientConnectioneManager}</property>                        
<property name="connectionFactory">                              
   <bean class="com.meidusa.amoeba.monitor.net.MonitorClientConnectionFactory"></bean>                        
</property>                 
</service>               
  <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext">                       
  <!-- 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>                 <!-- per connection cache prepared statement size  -->                        
<property name="statementCacheSize">500</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="clientConnectioneManager" class="com.meidusa.amoeba.net.MultiConnectionManagerWrapper">                       
  <property name="subManagerClassName">com.meidusa.amoeba.net.ConnectionManager</property>                         <!--                           
default value is avaliable Processors                        
  <property name="processors">5</property>                          -->               
</connectionManager>               
<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>                  <!-- 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">pool</property>            
<property name="writePool">master</property>              
<property name="readPool">salve</property>                  
<property name="needParse">true</property>        
</queryRouter> </amoeba:configuration>

到此配置文件修改完成
启动服务:
1
2
3
/application/amoeba/bin/launcher start#启动
ss -lntup|grep java   #查看启动状态
注意防火墙/etc/iptables status



最后远程登录测试
1
2
3
4
5
6
mysql -uzy -p123456 -h10.0.0.5 -P3306

mysql> use zy
mysql> create table tset(id ,int(4),name ,varchar(12));
mysql> insert into test values(1,'oldboy');
mysql> select * from test;



主从同步完成后关掉从库线程
1
2
3
4
5
6
7
8
9
10
11
12
主从同步完成后关掉从库线程


mysql> stop slave sql_thread;
再插入一条数据
mysql> insert into test values(2,'oldboy');
mysql> select * from test;


此时在这里是看不到插入的数据,这时候数据已经到主库里面,
到此实现了主库的写,然后将从库线程打开就能够查到数据,
证明实现了从库的读!





运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.iyunv.com/thread-158473-1-1.html 上篇帖子: mysql生成随机数 下篇帖子: MySQL慢查询日志
累计签到:2 天
连续签到:1 天
发表于 2015-12-30 14:32:08 | 显示全部楼层
大赞!简洁明了,学习了。

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表