mysql (主从复制)(proxy , Amoeba)

原址以下:

http://heylinux.com/archives/1004.htmlhtml

 

Mysql做为目前世界上使用最普遍的免费数据库,相信全部从事系统运维的工程师都必定接触过。但在实际的生产环境中,由单台Mysql做为独立的数据库是彻底不能知足实际需求的,不管是在安全性,高可用性以及高并发等各个方面。前端

所以,通常来讲都是经过 主从复制(Master-Slave)的方式来同步数据,再经过读写分离(MySQL-Proxy)来提高数据库的并发负载能力 这样的方案来进行部署与实施的。java

以下图所示:
mysql

下面是我在实际工做过程当中所整理的笔记,在此分享出来,以供你们参考。linux

1、MySQL的安装与配置
具体的安装过程,建议参考个人这一篇文章:http://heylinux.com/archives/993.html
值得一提的是,个人安装过程都是源码包编译安装的,而且全部的配置与数据等都统一规划到了/opt/mysql目录中,所以在一台服务器上安装完成之后,能够将整个mysql目录打包,而后传到其它服务器上解包,即可当即使用。c++

2、MySQL主从复制
场景描述:
主数据库服务器:192.168.10.130,MySQL已经安装,而且无应用数据。
从数据库服务器:192.168.10.131,MySQL已经安装,而且无应用数据。sql

2.1 主服务器上进行的操做
启动mysql服务
/opt/mysql/init.d/mysql start数据库

经过命令行登陆管理MySQL服务器
/opt/mysql/bin/mysql -uroot -p'new-password'编程

受权给从数据库服务器192.168.10.131
mysql> GRANT REPLICATION SLAVE ON *.* to 'rep1'@'192.168.10.131' identified by ‘password’;vim

查询主数据库状态
Mysql> show master status;
+------------------+----------+--------------+------------------+
| File | Position | Binlog_Do_DB | Binlog_Ignore_DB |
+------------------+----------+--------------+------------------+
| mysql-bin.000005 | 261 | | |
+------------------+----------+--------------+------------------+

记录下 FILE 及 Position 的值,在后面进行从服务器操做的时候须要用到。

2.2 配置从服务器
修改从服务器的配置文件/opt/mysql/etc/my.cnf
将 server-id = 1修改成 server-id = 10,并确保这个ID没有被别的MySQL服务所使用。

启动mysql服务
/opt/mysql/init.d/mysql start

经过命令行登陆管理MySQL服务器
/opt/mysql/bin/mysql -uroot -p'new-password'

执行同步SQL语句
mysql> change master to
master_host=’192.168.10.130’,
master_user=’rep1’,
master_password=’password’,
master_log_file=’mysql-bin.000005’,
master_log_pos=261;

正确执行后启动Slave同步进程
mysql> start slave;

主从同步检查
mysql> show slave status\G
==============================================
**************** 1. row *******************
Slave_IO_State:
Master_Host: 192.168.10.130
Master_User: rep1
Master_Port: 3306
Connect_Retry: 60
Master_Log_File: mysql-bin.000005
Read_Master_Log_Pos: 415
Relay_Log_File: localhost-relay-bin.000008
Relay_Log_Pos: 561
Relay_Master_Log_File: mysql-bin.000005
Slave_IO_Running: YES
Slave_SQL_Running: YES
Replicate_Do_DB:
……………省略若干……………
Master_Server_Id: 1
1 row in set (0.01 sec)
==============================================

其中Slave_IO_Running 与 Slave_SQL_Running 的值都必须为YES,才代表状态正常。

若是主服务器已经存在应用数据,则在进行主从复制时,须要作如下处理:
(1)主数据库进行锁表操做,不让数据再进行写入动做
mysql> FLUSH TABLES WITH READ LOCK;

(2)查看主数据库状态
mysql> show master status;

(3)记录下 FILE 及 Position 的值。
将主服务器的数据文件(整个/opt/mysql/data目录)复制到从服务器,建议经过tar归档压缩后再传到从服务器解压。

(4)取消主数据库锁定
mysql> UNLOCK TABLES;

2.3 验证主从复制效果

主服务器上的操做
在主服务器上建立数据库first_db
mysql> create database first_db;
Query Ok, 1 row affected (0.01 sec)

在主服务器上建立表first_tb
mysql> create table first_tb(id int(3),name char(10));
Query Ok, 1 row affected (0.00 sec)

在主服务器上的表first_tb中插入记录
mysql> insert into first_tb values (001,’myself’);
Query Ok, 1 row affected (0.00 sec)

在从服务器上查看
mysql> show databases;
=============================
+--------------------+
| Database |
+--------------------+
| information_schema |
| first_db |
| mysql |
| performance_schema |
| test |
+--------------------+
5 rows in set (0.01 sec)
=============================
数据库first_db已经自动生成

mysql> use first_db
Database chaged

mysql> show tables;
=============================
+--------------------+
| Tables_in_first_db |
+--------------------+
| first_tb |
+--------------------+
1 row in set (0.02 sec)
=============================
数据库表first_tb也已经自动建立

mysql> select * from first_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
1 rows in set (0.00 sec)
=============================
记录也已经存在

由此,整个MySQL主从复制的过程就完成了,接下来,咱们进行MySQL读写分离的安装与配置。

3、MySQL读写分离
场景描述:
数据库Master主服务器:192.168.10.130
数据库Slave从服务器:192.168.10.131
MySQL-Proxy调度服务器:192.168.10.132

如下操做,均是在192.168.10.132即MySQL-Proxy调度服务器 上进行的。

3.1 MySQL的安装与配置
具体的安装过程与上文相同。

3.2 检查系统所需软件包
经过 rpm -qa | grep name 的方式验证如下软件包是否已所有安装。
gcc* gcc-c++* autoconf* automake* zlib* libxml* ncurses-devel* libmcrypt* libtool* flex* pkgconfig*
libevent* glib*

若缺乏相关的软件包,可经过yum -y install方式在线安装,或直接从系统安装光盘中找到并经过rpm -ivh方式安装。

3.3 编译安装lua
MySQL-Proxy的读写分离主要是经过rw-splitting.lua脚本实现的,所以须要安装lua。

lua可经过如下方式得到
从http://www.lua.org/download.html下载源码包

从rpm.pbone.NET搜索相关的rpm包
download.fedora.redhat.com/pub/fedora/epel/5/i386/lua-5.1.4-4.el5.i386.rpm
download.fedora.redhat.com/pub/fedora/epel/5/x86_64/lua-5.1.4-4.el5.x86_64.rpm

这里咱们建议采用源码包进行安装
cd /opt/install
wget http://www.lua.org/ftp/lua-5.1.4.tar.gz
tar zvfx lua-5.1.4.tar.gz
cd lua-5.1.4

vi src/Makefile
在 CFLAGS= -O2 -Wall $(MYCFLAGS) 这一行记录里加上-fPIC,更改成 CFLAGS= -O2 -Wall -fPIC $(MYCFLAGS) 来避免编译过程当中出现错误。

make Linux
make install

cp etc/lua.pc /usr/lib/pkgconfig/
export PKG_CONFIG_PATH=$PKG_CONFIG_PATH:/usr/lib/pkgconfig

3.4 安装配置MySQL-Proxy
MySQL-Proxy可经过如下网址得到:
http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/

推荐采用已经编译好的二进制版本,由于采用源码包进行编译时,最新版的MySQL-Proxy对automake,glib以及libevent的版本都有很高的要求,而这些软件包都是系统的基础套件,不建议强行进行更新。
而且这些已经编译好的二进制版本在解压后都在统一的目录内,所以建议选择如下版本:
32位RHEL5平台:
http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.8.1-linux-rhel5-x86-32bit.tar.gz
64位RHEL5平台:
http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.8.1-linux-rhel5-x86-64bit.tar.gz

测试平台为RHEL5 32位,所以选择32位的软件包
wget http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.8.1-linux-rhel5-x86-32bit.tar.gz

tar xzvf mysql-proxy-0.8.1-linux-rhel5-x86-32bit.tar.gz
mv mysql-proxy-0.8.1-linux-rhel5-x86-32bit /opt/mysql-proxy

建立mysql-proxy服务管理脚本
mkdir /opt/mysql-proxy/init.d/

vim mysql-proxy

01 #!/bin/sh
02 #
03 # mysql-proxy This script starts and stops the mysql-proxy daemon
04 #
05 # chkconfig: - 78 30
06 # processname: mysql-proxy
07 # description: mysql-proxy is a proxy daemon to mysql
08  
09 # Source function library.
10 . /etc/rc.d/init.d/functions
11  
12 #PROXY_PATH=/usr/local/bin
13 PROXY_PATH=/opt/mysql-proxy/bin
14  
15 prog="mysql-proxy"
16  
17 # Source networking configuration.
18 . /etc/sysconfig/network
19  
20 # Check that networking is up.
21 [ ${NETWORKING} = "no" ] && exit 0
22  
23 # Set default mysql-proxy configuration.
24 #PROXY_OPTIONS="--daemon"
25 PROXY_OPTIONS="--admin-username=root --admin-password=password --proxy-read-only-backend-addresses=192.168.10.131:3306 --proxy-backend-addresses=192.168.10.130:3306  --admin-lua-script=/opt/mysql-proxy/lib/mysql-proxy/lua/admin.lua --proxy-lua-script=/opt/mysql-proxy/scripts/rw-splitting.lua"
26 PROXY_PID=/opt/mysql-proxy/run/mysql-proxy.pid
27  
28 # Source mysql-proxy configuration.
29 if [ -f /etc/sysconfig/mysql-proxy ]; then
30         . /etc/sysconfig/mysql-proxy
31 fi
32  
33 PATH=$PATH:/usr/bin:/usr/local/bin:$PROXY_PATH
34  
35 # By default it's all good
36 RETVAL=0
37  
38 # See how we were called.
39 case "$1" in
40   start)
41         # Start daemon.
42         echo -n $"Starting $prog: "
43         $NICELEVEL $PROXY_PATH/mysql-proxy $PROXY_OPTIONS --daemon --pid-file=$PROXY_PID --user=mysql --log-level=warning --log-file=/opt/mysql-proxy/log/mysql-proxy.log
44         RETVAL=$?
45         echo
46         if [ $RETVAL = 0 ]; then
47                 touch /var/lock/subsys/mysql-proxy
48         fi
49        ;;
50   stop)
51         # Stop daemons.
52         echo -n $"Stopping $prog: "
53         killproc $prog
54         RETVAL=$?
55         echo
56         if [ $RETVAL = 0 ]; then
57                 rm -f /var/lock/subsys/mysql-proxy
58                 rm -f $PROXY_PID
59         fi
60        ;;
61   restart)
62         $0 stop
63         sleep 3
64         $0 start
65        ;;
66   condrestart)
67        [ -e /var/lock/subsys/mysql-proxy ] && $0 restart
68       ;;
69   status)
70         status mysql-proxy
71         RETVAL=$?
72        ;;
73   *)
74         echo "Usage: $0 {start|stop|restart|status|condrestart}"
75         RETVAL=1
76        ;;
77 esac
78  
79 exit $RETVAL

脚本参数详解:
==============================================
PROXY_PATH=/opt/mysql-proxy/bin //定义mysql-proxy服务二进制文件路径

PROXY_OPTIONS="--admin-username=root \ //定义内部管理服务器帐号
--admin-password=password \ //定义内部管理服务器密码
--proxy-read-only-backend-addresses=192.168.10.131:3306 \ //定义后端只读从服务器地址
--proxy-backend-addresses=192.168.10.130:3306 \ //定义后端主服务器地址
--admin-lua-script=/opt/mysql-proxy/lib/mysql-proxy/lua/admin.lua \ //定义lua管理脚本路径
--proxy-lua-script=/opt/mysql-proxy/scripts/rw-splitting.lua" \ //定义lua读写分离脚本路径

PROXY_PID=/opt/mysql-proxy/run/mysql-proxy.pid //定义mysql-proxy PID文件路径

$NICELEVEL $PROXY_PATH/mysql-proxy $PROXY_OPTIONS \
--daemon \ //定义以守护进程模式启动
--keepalive \ //使进程在异常关闭后可以自动恢复
--pid-file=$PROXY_PID \ //定义mysql-proxy PID文件路径
--user=mysql \ //以mysql用户身份启动服务
--log-level=warning \ //定义log日志级别,由高到低分别有(error|warning|info|message|debug)
--log-file=/opt/mysql-proxy/log/mysql-proxy.log //定义log日志文件路径
==============================================

cp mysql-proxy /opt/mysql-proxy/init.d/
chmod +x /opt/mysql-proxy/init.d/mysql-proxy

mkdir /opt/mysql-proxy/run
mkdir /opt/mysql-proxy/log

mkdir /opt/mysql-proxy/scripts

配置并使用rw-splitting.lua读写分离脚本
最新的脚本咱们能够从最新的mysql-proxy源码包中获取
cd /opt/install

wget http://mysql.cdpa.nsysu.edu.tw/Downloads/MySQL-Proxy/mysql-proxy-0.8.1.tar.gz

tar xzvf mysql-proxy-0.8.1.tar.gz
cd mysql-proxy-0.8.1
cp lib/rw-splitting.lua /opt/mysql-proxy/scripts

修改读写分离脚本rw-splitting.lua
修改默认链接,进行快速测试,不修改的话要达到链接数为4时才启用读写分离
vim /opt/mysql-proxy/scripts/rw-splitting.lua
=============================
-- connection pool
if not proxy.global.config.rwsplit then
proxy.global.config.rwsplit = {
min_idle_connections = 1, //默认为4
max_idle_connections = 1, //默认为8
is_debug = false
}
end
=============================

修改完成后,启动mysql-proxy
/opt/mysql-proxy/init.d/mysql-proxy start

3.5 测试读写分离效果
建立用于读写分离的数据库链接用户
登录主数据库服务器192.168.10.130,经过命令行登陆管理MySQL服务器
/opt/mysql/bin/mysql -uroot -p'new-password'
mysql> GRANT ALL ON *.* TO 'proxy1'@'192.168.10.132' IDENTIFIED BY 'password';
因为咱们配置了主从复制功能,所以从数据库服务器192.168.10.131上已经同步了此操做。

为了清晰的看到读写分离的效果,须要暂时关闭MySQL主从复制功能
登录从数据库服务器192.168.10.131,经过命令行登陆管理MySQL服务器
/opt/mysql/bin/mysql -uroot -p'new-password'

关闭Slave同步进程
mysql> stop slave;
Query OK, 0 rows affected (0.00 sec)

链接MySQL-Proxy
/opt/mysql/bin/mysql -uproxy1 -p'password' -P4040 -h192.168.10.132

登录成功后,在first_db数据的first_tb表中插入两条记录
mysql> use first_db;
Database changed
mysql> insert into first_tb values (007,’first’);
Query Ok, 1 row affected (0.00 sec)
mysql> insert into first_tb values (110,’second’);
Query Ok, 1 row affected (0.00 sec)

查询记录
mysql> select * from first_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
1 rows in set (0.00 sec)
=============================
经过读操做并无看到新记录

mysql> quit
退出MySQL-Proxy

下面,分别登录到主从数据库服务器,对比记录信息
首先,检查主数据库服务器
mysql> select * from first_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
| 007 | first |
+------+------+
| 110 | second |
+------+------+
3 rows in set (0.00 sec)
=============================
两条新记录都已经存在

而后,检查从数据库服务器
mysql> select * from first_tb;
=============================
+------+------+
| id | name |
+------+------+
| 1 | myself |
+------+------+
1 rows in set (0.00 sec)
=============================
没有新记录存在

由此验证,咱们已经实现了MySQL读写分离,目前全部的写操做都所有在Master主服务器上,用来避免数据的不一样步;
另外,全部的读操做都分摊给了其它各个Slave从服务器上,用来分担数据库压力。

经验分享:
1.当MySQL主从复制在 show slave status\G 时出现Slave_IO_Running或Slave_SQL_Running 的值不为YES时,须要首先经过 stop slave 来中止从服务器,而后再执行一次本文 2.1与2.2 章节中的步骤便可恢复,但若是想尽量的同步更多的数据,能够在Slave上将master_log_pos节点的值在以前同步失效的值的基础上增大一些,而后反复测试,直到同步OK。由于MySQL主从复制的原理其实就是从服务器读取主服务器的binlog,而后根据binlog的记录来更新数据库。

2.MySQL-Proxy的rw-splitting.lua脚本在网上有不少版本,可是最准确无误的版本仍然是源码包中所附带的lib/rw-splitting.lua脚本,若是有lua脚本编程基础的话,能够在这个脚本的基础上再进行优化;

3.MySQL-Proxy实际上很是不稳定,在高并发或有错误链接的状况下,进程很容易自动关闭,所以打开--keepalive参数让进程自动恢复是个比较好的办法,但仍是不能从根本上解决问题,所以一般最稳妥的作法是在每一个从服务器上安装一个MySQL-Proxy供自身使用,虽然比较低效但却能保证稳定性;

4.一主多从的架构并非最好的架构,一般比较优的作法是经过程序代码和中间件等方面,来规划,好比设置对表数据的自增id值差别增加等方式来实现两个或多个主服务器,但必定要注意保证好这些主服务器数据的完整性,不然效果会比多个一主多从的架构还要差;

5.MySQL-Cluster 的稳定性也不是太好;

6.Amoeba for MySQL 是一款优秀的中间件软件,一样能够实现读写分离,负载均衡等功能,而且稳定性要大大超过MySQL-Proxy,建议你们用来替代MySQL-Proxy,甚至MySQL-Cluster。

 

详解Mysql Proxy Lua读写分离设置

 

原址以下:

http://mobile.51cto.com/iphone-287937.htm

Mysql Proxy Lua读写分离设置是本文要介绍的内容,主要是来了解Mysql ProxyMysql 分离设置,为了将来MySQL读写分离的须要, 先行对MySQL官方的Mysql Proxy产品进行了初步测试. 如下是测试过程,二进制版Mysql Proxy能够去下载。

一、设置说明

  1. Master服务器: 192.168.41.196  
  2. Slave服务器: 192.168.41.197  
  3. Proxy服务器: 192.168.41.203 

二、安装Mysql Proxy

在Proxy服务器上安装便可. 若是源码方式安装, 需提早安装pkg-config,libevent,glibc,lua等依赖包, 很是麻烦, 建议直接使用二进制版.

  1. # cd /u01/software/mysql  
  2. # tar -zxvf Mysql Proxy-0.8.1-linux-rhel5-x86-32bit.tar.gz -C /usr/local  
  3. # cd /usr/local  
  4. # ln -s Mysql Proxy-0.8.1-linux-rhel5-x86-32bit Mysql Proxy  
  5. # vi + ~/.bash_profile  
  6. export PATH=$PATH:/usr/local/Mysql Proxy/bin/  
  7. # . ~/.bash_profile 

三、Mysql Proxy选项说明

  1. # Mysql Proxy help-all 

管理功能选项:

  1. admin-address=host:port 指定一个mysqo-proxy的管理端口, 缺省是4041;  
  2. admin-username=<string> username to allow to log in  
  3. admin-password=<string> password to allow to log in  
  4. admin-lua-script=<filename> script to execute by the admin plugin 

代理功能选项:

  1. -P, proxy-address=<host:port> 是Mysql Proxy 服务器端的监听端口, 缺省是4040;  
  2. -r, proxy-read-only-backend-addresses=<host:port> 只读Slave的地址和端口, 缺省为不设置;  
  3. -b, proxy-backend-addresses=<host:port> 远程Master地址和端口, 可设置多个作failover和load balance, 缺省是127.0.0.1:3306;  
  4. proxy-skip-profiling 关闭查询分析功能, 缺省是打开的;  
  5. proxy-fix-bug-25371 修正 mysql的libmysql版本大于5.1.12的一个#25371号bug;  
  6. -s, proxy-lua-script=<file> 指定一个Lua脚原本控制Mysql Proxy的运行和设置, 这个脚本在每次新建链接和脚本发生修改的的时候将从新调用; 

其余选项:

  1. defaults-file=<file>配置文件, 能够把Mysql Proxy的参数信息置入一个配置文件里;  
  2. daemon Mysql Proxy以守护进程方式运行  
  3. pid-file=file 设置Mysql Proxy的存储PID文件的路径  
  4. keepalive try to restart the proxy if it crashed, 保持链接启动进程会有2个, 一号进程用来监视二号进程, 若是二号进程死掉自动重启proxy. 

四、数据库准备工做

(1)安装半同步补丁(建议)

读写分离不能回避的问题之一就是延迟, 能够考虑Google提供的SemiSyncReplication补丁.

(2)给用户受权

在Master/Slave创建一个测试用户, 由于之后客户端发送的SQL都是经过Mysql Proxy服务器来转发, 因此要确保能够从Mysql Proxy服务器上登陆MySQL主从库.

  1. mysql> grant all privileges on *.* to 'u_test'@'192.168.41.203' identified by 'xxx' with grant option; 

(3)在Master创建测试表

  1. mysql> create table db_test.t_test (col varchar(10));  
  2. mysql> insert into db_test.t_test values ('testA');  
  3. mysql> select * from db_test.t_test;  
  4. +-+  
  5. | col   |  
  6. +-+  
  7. | testA |  
  8. +-+ 

五、Mysql Proxy启动

(1)修改读写分离lua脚本

默认最小4个最大8个以上的客户端链接才会实现读写分离, 现改成最小1个最大2个:

  1. # vi +40 /usr/local/Mysql Proxy/share/doc/Mysql Proxy/rw-splitting.lua  
  2.  connection pool  
  3. if not proxy.global.config.rwsplit then  
  4.         proxy.global.config.rwsplit = {  
  5.                 min_idle_connections = 1,  
  6.                 max_idle_connections = 2,  
  7.                 is_debug = true   
  8.         }         
  9. end 

这是由于Mysql Proxy会检测客户端链接, 当链接没有超过min_idle_connections预设值时, 不会进行读写分离, 即查询操做会发生到Master上.

(2)启动Mysql Proxy

建议使用配置文件的形式启动, 注意配置文件必须是660权限, 不然没法启动. 若是有多个Slave的话, proxy-read-only-backend-addresses参数能够配置多个以逗号分隔的IP:Port从库列表.

  1. # killall Mysql Proxy   
  2. # vi /etc/Mysql Proxy.cnf  
  3. [Mysql Proxy]  
  4. admin-username=wangnc 
  5. admin-password=iamwangnc 
  6. admin-lua-script=/usr/local/Mysql Proxy/lib/Mysql Proxy/lua/admin.lua  
  7. proxy-backend-addresses=192.168.41.196:3351  
  8. proxy-read-only-backend-addresses=192.168.41.197:3351  
  9. proxy-lua-script=/usr/local/Mysql Proxy/share/doc/Mysql Proxy/rw-splitting.lua  
  10. log-file=/var/tmp/Mysql Proxy.log  
  11. log-level=debug 
  12. daemon=true 
  13. keepalive=true 
  14. # chmod 660 /etc/Mysql Proxy.cnf  
  15. # Mysql Proxy defaults-file=/etc/Mysql Proxy.cnf  
  16. # ps -ef | grep Mysql Proxy | grep -v grep  
  17. root      1869     1  0 18:16 ?        00:00:00 /usr/local/Mysql Proxy/libexec/Mysql Proxy defaults-file=/etc/Mysql Proxy.cnf  
  18. root      1870  1869  0 18:16 ?        00:00:00 /usr/local/Mysql Proxy/libexec/Mysql Proxy defaults-file=/etc/Mysql Proxy.cnf  
  19. # tail -50f /var/tmp/Mysql Proxy.log 

六、客户端链接测试

(1)先中止Slave的复制进程

  1. mysql> stop slave; 

(2)链接Proxy端口, 插入数据

  1. # mysql -uu_test -pxxx -h192.168.41.203 -P4040 -Ddb_test  
  2. mysql> insert into db_test.t_test values ('testB');  
  3. mysql> select * from db_test.t_test;  
  4. +-+  
  5. | col   |  
  6. +-+  
  7. | testA |  
  8. | testB |  
  9. +-+ 

(3)多开几个客户端, 链接Proxy端口, 查询数据

  1. # mysql -uu_test -pxxx -h192.168.41.203 -P4040 -Ddb_test  
  2. mysql> select * from db_test.t_test;  
  3. +-+  
  4. | col   |  
  5. +-+  
  6. | testA |  
  7. +-+ 

若是查询不到上步新插入的数据, 说明链接到了Slave, 读写分离成功. 在同一线程再插入数据并验证:

  1. mysql> insert into db_test.t_test values ('testC');  
  2. mysql> select * from db_test.t_test;  
  3. +-+  
  4. | col   |  
  5. +-+  
  6. | testA |  
  7. +-+ 

发现insert操做成功, 可是select不出刚插入的数据, 说明同一线程也读写分离成功. 从日志中能够验证:

  1. # tail -50f /var/tmp/Mysql Proxy.log  
  2. ...  
  3. [read_query] 192.168.41.203:45481  
  4.   current backend   = 
  5.   client default db = db_test 
  6.   client username   = u_test 
  7.   query             = select * from db_test.t_test  
  8.   sending to backend : 192.168.41.197:3351  
  9.     is_slave         : true  
  10.     server default db: db_test  
  11.     server username  : u_test  
  12.     in_trans        : false  
  13.     in_calc_found   : false  
  14.     COM_QUERY       : true  
  15. [read_query] 192.168.41.203:45481  
  16.   current backend   = 
  17.   client default db = db_test 
  18.   client username   = u_test 
  19.   query             = insert into db_test.t_test values ('testC')  
  20.   sending to backend : 192.168.41.196:3351  
  21.     is_slave         : false  
  22.     server default db: db_test  
  23.     server username  : u_test  
  24.     in_trans        : false  
  25.     in_calc_found   : false  
  26.     COM_QUERY       : true 

(4)测试完毕后, 启动Slave的复制进程

  1. mysql> start slave; 

七、正式环境说明

一、Mysql Proxy当前还只是个测试版, MySQL官方还不建议用到生产环境中;

二、Mysql Proxy的rw-splitting.lua脚本在网上有不少版本, 可是最准确无误的版本仍然是源码包中所附带的rw-splitting.lua脚本, 若是有lua脚本编程基础的话, 能够在这个脚本的基础上再进行优化;

三、Mysql Proxy实际上很是不稳定, 在高并发或有错误链接的状况下, 进程很容易自动关闭, 所以打开keepalive参数让进程自动恢复是个比较好的办法, 但仍是不能从根本上解决问题, 所以一般最稳妥的作法是在每一个从服务器上安装一个Mysql Proxy供自身使用, 虽然比较低效但却能保证稳定性;

四、Amoeba for MySQL是一款优秀的中间件软件, 一样能够实现读写分离, 负载均衡等功能, 而且稳定性要大大超过Mysql Proxy, 建议你们用来替代Mysql Proxy, 甚至MySQL-Cluster.

 

mysql的读写分离amoeba

原址以下:

http://freeze.blog.51cto.com/1846439/860111

 

此文凝聚笔者很多心血请尊重笔者劳动,转载请注明出处http://freeze.blog.51cto.com/ 

  1、关于读写分离

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

 

2、同类产品比较 

  1. 虽然大多数都是从程序里直接实现读写分离的,但对于分布式的部署和水平和垂直分割,一些代理的相似中间件的软件仍是挺实用的,Amoeba for Mysql 与MySQL Proxy比较 在MySQL proxy 6.0版本 上面若是想要读写分离而且 读集群、写集群 机器比较多状况下,用mysql proxy 须要至关大的工做量,目前mysql proxy没有现成的 lua脚本。mysql proxy根本没有配置文件, lua脚本就是它的所有,固然lua是至关方便的。那么一样这种东西须要编写大量的脚本才能完成一 个复杂的配置。而Amoeba for Mysql只须要进行相关的配置就能够知足需求。 
 
3、关于Amoeba
 
  1. Amoeba(变形虫)项目,该开源框架于2008年 开始发布一款 Amoeba for Mysql软件。这个软件致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的 时候充当SQL路由功能,专一于分布式数据库代理层(Database Proxy)开发。座落与 Client、DB Server(s)之间,对客户端透明。具备负载均衡、高可用性、SQL 过滤、读写分离、可路由相关的到目标数据库、可并发请求多台数据库合并结果。 经过Amoeba你可以完成多数据源的高可用、负载均衡、数据切片的功能,目前Amoeba已在不少 企业的生产线上面使用。 

 

4、Amoeba的安装

4.1下载 

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

4.2安装amoeba 

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

4.3安装JDK 

  1. 由于Amoeba是java开发的,须要JDK支持。 Amoeba框架是基于Java SE1.5开发的,建议使用Java SE 1.5版本。 
  2.  
  3. % java -version 
  4. java version "1.6.0_18" 
  5. Java(TM) SE Runtime Environment (build 1.6.0_18-b07) 
  6. Java HotSpot(TM) Client VM (build 16.0-b13, mixed mode, sharing) 
  7. 目前Amoeba经验证在JavaTM SE 1.5和Java SE 1.6能正常运行,(可能包括其余未经验证的版本)。 若是你的机器上没有安装JavaTM环境,能够访问http://www.oracle.com/technetwork/java/javase/downloads/index.html进行下载。能够根据你的操做系统等详情安装JavaTM环境。 
  8.  
  9. 去oracle官网下载jdk安装包后,安装jdk 
  10.  
  11. # chmod 755 jdk-6u25-linux-i586.bin 
  12. # ./jdk-6u25-linux-i586.bin 
  13. # mv jdk1.6.0_25/ /usr/local/jdk 
  14. 声明路径,修改/etc/profile,在末尾加上如下代码 
  15.  
  16. export AMOEBA_HOME=/usr/local/amoeba 
  17. export JAVA_HOME=/usr/local/jdk 
  18. export PATH=$PATH:$JAVA_HOME/bin:$JAVA_HOME/jre/bin:$AMOEBA_HOME/bin 


 5、Amoeba配置

  1. cd /usr/local/amoeba/conf 主要配置如下2个配置文件:  
  2. dbServers.xml  #定义链接数据库信息 
  3. amoeba.xml     #定义读写分离节点管理信息 

5.1 配置dbServers.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.                          such as 'multiPool' dbServer    
  9.                 --
  10.  
  11.         <dbServer name="abstractServer" abstractive="true"
  12.                 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory"
  13.                         <property name="manager">${defaultManager}</property
  14.                         <property name="sendBufferSize">64</property
  15.                         <property name="receiveBufferSize">128</property
  16.  
  17.                         <!-- mysql port --> 
  18.                         <property name="port">3306</property>         __ ** ##后端数据库端口**__ 
  19.  
  20.                         <!-- mysql schema --> 
  21.                         <property name="schema">test</property>        __ ** ##后端数据库默认库**__ 
  22.                         <!--  mysql password 
  23.                         <property name="password">password</property
  24.                         --
  25.                 </factoryConfig
  26.  
  27.                 <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool"
  28.                         <property name="maxActive">500</property
  29.                         <property name="maxIdle">500</property
  30.                         <property name="minIdle">10</property
  31.                         <property name="minEvictableIdleTimeMillis">600000</property
  32.                         <property name="timeBetweenEvictionRunsMillis">600000</property
  33.                         <property name="testOnBorrow">true</property
  34.                         <property name="testWhileIdle">true</property
  35.                 </poolConfig
  36.         </dbServer
  37.   
  38.         <dbServer name="master"  parent="abstractServer">                          __ ** ##定义主的写的节点**__ 
  39.                 <factoryConfig
  40.                         <property name="ipAddress">192.168.1.1</property>      __ ** ##主masterIP**__ 
  41.                         <property name="user">test1</property>                 __ ** ##与主mysql通讯,链接数据库的账号,如下是密码**__ 
  42.                         <property name="password">test1</property
  43.                 </factoryConfig
  44.         </dbServer
  45.  
  46.         <dbServer name="slave"  parent="abstractServer"
  47.                 <factoryConfig
  48.                         <property name="ipAddress">192.168.1.2</property
  49.                         <property name="user">test2</property>                 __ ** ##与从mysql通讯,链接数据库的账号,如下是密码**__ 
  50.                         <property name="password">test2</property
  51.                 </factoryConfig
  52.         </dbServer
  53.  
  54.         <dbServer name="server1" virtual="true"
  55.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">    __ ** ##定义写的池,把master节点加入**__ 
  56.                         <property name="loadbalance">1</property
  57.                         <property name="poolNames">master</property
  58.                 </poolConfig
  59.         </dbServer
  60.  
  61.         <dbServer name="server2" virtual="true"
  62.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">    __ ** ##定义读的池,把slave节点加入**__ 
  63.                         <property name="loadbalance">1</property
  64.                         <property name="poolNames">slave</property
  65.                 </poolConfig
  66.         </dbServer
  67. </amoeba:dbServers

5.2 配置amoeba.xml

  1. <?xml version="1.0" encoding="gbk"?> 
  2. <amoeba:configuration xmlns:amoeba="http://amoeba.meidusa.com/"
  3.  
  4.         <proxy
  5.  
  6.                 <!-- service class must implements com.meidusa.amoeba.service.Service --> 
  7.                         <!-- port --> 
  8.                          <property name="port">6666</property>                   __ ** ##定义amoeba读写分离proxy对外代理的端口**__ 
  9.                         <!-- bind ipAddress --> 
  10.                         <!--  
  11.                         <property name="ipAddress">127.0.0.1</property> 
  12.                          --> 
  13.  
  14.                         <property name="manager">${clientConnectioneManager}</property
  15.  
  16.                         <property name="connectionFactory"
  17.                                         <property name="sendBufferSize">128</property
  18.                                         <property name="receiveBufferSize">64</property
  19.                                 </bean
  20.                         </property
  21.  
  22.                         <property name="authenticator"
  23.                                          <property name="user">dbproxy</property>     __ ** ##定义proxy的管理账号密码,客户端和程序只须要链接proxy的账号密码便可,至关于中间接封装**__ 
  24.                                         <property name="password">123456</property
  25.  
  26.                                         <property name="filter"
  27.                                                 </bean
  28.                                         </property
  29.                                 </bean
  30.                         </property
  31.  
  32.                 </service
  33.  
  34.                 <!-- server class must implements com.meidusa.amoeba.service.Service --> 
  35.                         <!-- port --> 
  36.                         <!--  default value: random number 
  37.                         <property name="port">9066</property
  38.                         --
  39.                         <!-- bind ipAddress --> 
  40.                         <property name="ipAddress">127.0.0.1</property
  41.                         <property name="daemon">true</property
  42.                         <property name="manager">${clientConnectioneManager}</property
  43.                         <property name="connectionFactory"
  44.                 <runtime class="com.meidusa.amoeba.mysql.context.MysqlRuntimeContext"
  45.                         <!-- proxy server net IO Read thread size --> 
  46.                         <property name="readThreadPoolSize">20</property
  47.  
  48.                         <!-- proxy server client process thread size --> 
  49.  
  50.                         <!-- per connection cache prepared statement size  --> 
  51.                         <property name="statementCacheSize">500</property
  52.  
  53.                         <!-- query timeout( default: 60 second , TimeUnit:second) --> 
  54.                         <property name="queryTimeout">60</property
  55.                 </runtime
  56.  
  57.         </proxy
  58.  
  59.         <!--  
  60.                 Each ConnectionManager will start as thread 
  61.                 manager responsible for the Connection IO read , Death Detection 
  62.         --
  63.         <connectionManagerList
  64.                         <!--  
  65.                           default value is avaliable Processors  
  66.                         <property name="processors">5</property
  67.                          --
  68.                 </connectionManager
  69.  
  70.                         <!--  
  71.                           default value is avaliable Processors  
  72.                         <property name="processors">5</property
  73.                          --
  74.                 </connectionManager
  75.         </connectionManagerList
  76.  
  77.                 <!-- default using file loader --> 
  78.         <dbServerLoader class="com.meidusa.amoeba.context.DBServerConfigFileLoader"
  79.                 <property name="configFile">${amoeba.home}/conf/dbServers.xml</property
  80.         </dbServerLoader
  81.  
  82.         <queryRouter class="com.meidusa.amoeba.mysql.parser.MysqlQueryRouter"
  83.                 <property name="ruleLoader"
  84.                         <bean class="com.meidusa.amoeba.route.TableRuleFileLoader"
  85.                                 <property name="ruleFile">${amoeba.home}/conf/rule.xml</property
  86.                                 <property name="functionFile">${amoeba.home}/conf/ruleFunctionMap.xml</property
  87.                         </bean
  88.                 </property
  89.                 <property name="sqlFunctionFile">${amoeba.home}/conf/functionMap.xml</property
  90.                 <property name="LRUMapSize">1500</property
  91.                 <property name="defaultPool">server1</property>                   __ ** ##定义默认的池,一些除了SELECT\UPDATE\INSERT\DELETE的语句都会在defaultPool执行。**__ 
  92.                 <property name="writePool">server1</property>                      __ ** ##定义写的池**__ 
  93.                 <property name="readPool">server2</property>                      __ ** ##定义读的池**__ 
  94.                 <property name="needParse">true</property
  95.         </queryRouter
  96. </amoeba:configuration

 

6、启动Amoeba

  1. /usr/local/amoeba/bin/amoeba start & 
  2. 开机自动启动可加入到 /etc/rc.local内 
  3. echo "/usr/local/amoeba/bin/amoeba start &" >> /etc/rc.local 

7、日志排错

  1. 日志文件在/usr/local/amoeba/log下   

 

   PS:amoeba虽然是Java写的,看似效率不高,但功能异常强大,支持读写分离,表和库级别的读写分离,数据库水平分割,垂直分割,还有集群。是淘宝的得力做品。喜欢的童鞋能够尝试下。mysql-proxy 只是轻量级的读写分离程序,虽然C写的,可是驱动是须要lua的脚本跑,并且在高并发下常常挂掉。程序还忽略了一些字符设定,若是数据库不是同一编码还会出现乱码,amoeba就不存在。就简单介绍到这里吧。

 

 使用Amoeba for mysql实现mysql读写分离

原址以下:

http://www.centos.bz/2012/05/amoeba-for-mysql/

 

Amoeba for MySQL致力于MySQL的分布式数据库前端代理层,它主要在应用层访问MySQL的时候充当query 路由功能,专一 分布式数据库 proxy 开发。座落与Client、DB Server(s)之间。对客户端透明。具备负载均衡、高可用性、Query过滤、读写分离、可路由相关的query到目标数据库、可并发请求多台数据库合并结果。 在Amoeba上面你可以完成多数据源的高可用、负载均衡、数据切片的功能。目前在不少企业的生产线上面使用。
www.centos.bz这里使用Amoeba for mysql来实现mysql的读写分离,起到缓解主数据库服务器的压力,下面是实现这一方案的架构图:

mysql主从复制配置

由于读写分离,因此一台负责mysql的写操做,另外一台负责mysql的读操做,因此咱们这里使用mysql的主从复制再合适不过了。关于这一配置,请移步:
http://www.centos.bz/2011/07/linux-mysql-replication-sync-configure/

java环境配置

Amoeba框架是基于Java SE1.5开发的,建议使用Java SE 1.5版本。目前Amoeba经验证在JavaTM SE 1.5和Java SE 1.6能正常运行,(可能包括其余未经验证的版本)。
Java SE 1.6下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u32-downloads-1594644.html
我这里下载jdk-6u32-linux-i586-rpm.bin。
下载完成后执行sh jdk-6u32-linux-i586-rpm.bin开始安装,将会安装到/usr/java/jdk1.6.0_32目录。

Amoeba的安装

Amoeba下载地址:http://sourceforge.net/projects/amoeba/
下面是安装步骤:

  1. cd /tmp
  2. mkdir /usr/local/amoeba
  3. wget http://softlayer.dl.sourceforge.net/project/amoeba/Amoeba%20for%20mysql/2.x/amoeba-mysql-binary-2.1.0-RC5.tar.gz
  4. tar xzf amoeba-mysql-binary-2.1.0-RC5.tar.gz -C /usr/local/amoeba

配置用户环境变量

  1. vi ~/.bash_profile

设置为:

  1. PATH=$PATH:$HOME/bin:/usr/local/amoeba/bin
  2. JAVA_HOME=/usr/java/jdk1.6.0_32
  3.  
  4. export JAVA_HOME
  5. export PATH

当即生效:

  1. source  ~/.bash_profile

Amoeba for mysql配置

配置Amoeba for mysql的读写分离主要涉及两个文件:
一、/usr/local/amoeba/conf/dbServers.xml
此文件定义由Amoeba代理的数据库如何链接,好比最基础的:主机IP、端口、Amoeba使用的用户名和密码等等。
二、/usr/local/amoeba/conf/amoeba.xml
此文件定义了Amoeba代理的相关配置。

dbServers.xml文件配置

abstractServer配置:

  1. <dbServer name="abstractServer" abstractive="true">
  2.                 <factoryConfig class="com.meidusa.amoeba.mysql.net.MysqlServerConnectionFactory">
  3.                         <property name="manager">${defaultManager}</property>
  4.                         <property name="sendBufferSize">64</property>
  5.                         <property name="receiveBufferSize">128</property>
  6.  
  7.                         <!-- mysql port -->
  8.                         <property name="port">3306</property>
  9.  
  10.                         <!-- mysql schema -->
  11.                         <property name="schema">dbname</property>
  12.  
  13.                         <!-- mysql user -->
  14.                         <property name="user">root</property>
  15.  
  16.                         <!--  mysql password -->
  17.                         <property name="password">root</property>
  18.  
  19.                 </factoryConfig>
  20.  
  21.                 <poolConfig class="com.meidusa.amoeba.net.poolable.PoolableObjectPool">
  22.                         <property name="maxActive">500</property>
  23.                         <property name="maxIdle">500</property>
  24.                         <property name="minIdle">10</property>
  25.                         <property name="minEvictableIdleTimeMillis">600000</property>
  26.                         <property name="timeBetweenEvictionRunsMillis">600000</property>
  27.                         <property name="testOnBorrow">true</property>
  28.                         <property name="testWhileIdle">true</property>
  29.                 </poolConfig>
  30.         </dbServer>

此部分定义真实mysql服务器的端口,数据库名称,mysql用户及密码。
主从数据库定义:

  1. <dbServer name="Master"  parent="abstractServer">
  2.                 <factoryConfig>
  3.                         <!-- mysql ip -->
  4.                         <property name="ipAddress">192.168.0.1</property>
  5.                 </factoryConfig>
  6.         </dbServer>
  7. <dbServer name="Slave1"  parent="abstractServer">
  8.                 <factoryConfig>
  9.                         <!-- mysql ip -->
  10.                         <property name="ipAddress">192.168.0.2</property>
  11.                 </factoryConfig>
  12.         </dbServer>
  13. <dbServer name="Slave2"  parent="abstractServer">
  14.                 <factoryConfig>
  15.                         <!-- mysql ip -->
  16.                         <property name="ipAddress">192.168.0.3</property>
  17.                 </factoryConfig>
  18.         </dbServer>
  19.         <dbServer name="virtualSlave" virtual="true">
  20.                 <poolConfig class="com.meidusa.amoeba.server.MultipleServerPool">
  21.                         <!-- Load balancing strategy: 1=ROUNDROBIN , 2=WEIGHTBASED , 3=HA-->
  22.                         <property name="loadbalance">1</property>
  23.  
  24.                         <!-- Separated by commas,such as: server1,server2,server1 -->
  25.                         <property name="poolNames">Slave1,Slave2</property>
  26.                 </poolConfig>
  27.         </dbServer>

此部分定义主服务器,从服务器,及从服务器链接池。这里只定义数据库地址,它们的用户及密码就是上面的abstractServer里的设置。注意用来链接真实mysql服务器的用户必须拥有远程链接权限。

amoeba.xml配置

amoeba链接验证配置:

  1. <property name="authenticator">
  2.                                 <bean class="com.meidusa.amoeba.mysql.server.MysqlClientAuthenticator">
  3.  
  4.                                         <property name="user">root</property>
  5.                                         
  6.                                         <property name="password">root</property>
  7.  
  8.                                         <property name="filter">
  9.                                                 <bean class="com.meidusa.amoeba.server.IPAccessController">
  10.                                                         <property name="ipFile">${amoeba.home}/conf/access_list.conf</property>
  11.                                                 </bean>
  12.                                         </property>
  13.                                 </bean>
  14.                         </property>

这里定义链接amoeba时用来验证的用户及密码。
读写分离配置:

  1. <property name="defaultPool">Master</property>
  2.                 <property name="writePool">Master</property>
  3.                 <property name="readPool">virtualSlave</property>

defaultPool:配置了默认的数据库节点,一些除了SELECTUPDATEINSERTDELETE的语句都会在defaultPool执行。
writePool :配置了数据库写库,一般配为Master,如这里就配置为以前定义的Master数据库。
readPool :配置了数据库读库,一般配为Slave或者Slave组成的数据库池,如这里就配置以前的virtualSlave数据库池。

amoeba启动

启动命令:

  1. amoeba start

此命令之前台的方式启动,会输出启动时的信息,检查没有错误信息后,中断,并后台运行:

  1. amoeba start &

FAQ

一、没法正常链接?
首先根据执行amoeba start输出的信息排除配置文件没有问题,以后确认mysql用户是否有远程链接的权限,而后检查网站的数据库配置文件是否设置正确。
二、如何配置网站数据库链接文件?
默认的端口应该为8066,用户及密码在amoeba.xml里设置。
参考:http://docs.hexnova.com/amoeba/single-dbserver.html
http://docs.hexnova.com/amoeba/rw-splitting.html

相关文章
相关标签/搜索