原创 [原创] MySQL Proxy 学习笔记收藏



[原创] MySQL Proxy 学习笔记

作者:heiyeluren
时间:2008-1-28
博客:
http://blog.csdn.net/heiyeshuwu

【 测试平台 】

服务器端:
OS:FreeBSD 6.2
Lua: 5.1.1
MySQL Server:4.1.22-log
MySQL Proxy: 0.6.0


客户端:
OS:Windows XP Pro SP2
PHP: PHP 5.2.4 (cli)
MySQL Client: Ver 14.13 Distrib 5.1.19-beta for Win32

注意:本文使用的是最新版本 MySQL Proxy alpha 0.6.0 ,如果是0.5.0版本可能部分选项和操作不一致,同样的,以后如果除了新版本,请参照新版本文档。


【 MySQL Proxy 安装 】

$ fetch http://mirror.mysql-partners-jp.biz/Downloads/MySQL-Proxy/mysql-proxy-0.6.0-freebsd6-x86.tar.gz
$ tar zxvf mysql-proxy-
0.6.0-freebsd6-x86.tar.gz
$ cd mysql-proxy-
0.6.0-freebsd6-x86
$ cp sbin/mysql-proxy /usr/local/sbin/

如果无法正常使用,请检查相应的其他组件是否安装了,mysql-proxy 需要依赖 lua、libtool、glib、libevent 等库。


【 初步使用 】

执行 mysql-proxy --help-all 查看所有的设置选项,比较重要的选项大致描述一下功能:

管理功能选项

--admin-address=host:port — 指定一个mysqo-proxy的管理端口,缺省是 4041

代理功能选项

--proxy-address=host:port — 这个是mysql-proxy 服务器端的监听端口,缺省是 4040
--proxy-read-only-backend-addresses
=<host:port> — 远程只读Slave服务器的地址和端口,缺省为不设置(本选项在mysql-proxy0.5.0版本中没有)
--proxy-backend-addresses
=host:port — 指定远程MySQL服务器地址和端口,可以设置多个,缺省是 127.0.0.1:3306
--proxy-skip-profiling — 关闭查询分析功能,缺省是打开的
--proxy-fix-bug-
25371 — 修正 mysql的libmysql版本大于5.1.12的一个#25371号bug
--proxy-lua-script
=file — 指定一个Lua脚本程序来控制mysql-proxy的运行和设置,这个脚本在每次新建连接和脚本发生修改的的时候将重新调用

其他选项

--daemon — mysql-proxy以守护进程方式运行
--pid-file
=file — 设置mysql-proxy的存储PID文件的路径

我们执行试试,监听本地MySQL是3000端口:
/usr/local/sbin/mysql-proxy --proxy-backend-addresses=127.0.0.1:3000

然后从我的windows机器使用mysql客户端连接过去:
mysql -uroot -h 192.168.0.2 -P 4040

Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 3
Server version: 
4.1.22-log
Type 'help
;' or 'h' for help. Type 'c' to clear the buffer.
mysql>

远程的mysql-proxy缺省对外监听的是4040端口,它会对连接4040端口的连接做处理后丢给后端3000端口的mysql服务器处理,把结果返回。
我们执行一条sql试试:

mysql> select version();
+------------+
| version()  |
+------------+
4.1.22-log |
+------------+
1 row in set (0.01 sec)


 

【 对两台/多台MySQL的负载均衡 】

首先我们目前MySQL Proxy 是支持多台后端MySQL数据库的,它可以支持同时设置多个 --proxy-backend-addresses 选项来使用多个MySQL,比如:
/usr/local/sbin/mysql-proxy --proxy-address=192.168.0.2:3306 --proxy-backend-addresses=127.0.0.1:3000 --proxy-backend-addresses=192.168.0.2:4000
就分别连接了两台MySQL,一台是3000端口,一台是4000端口。

假设有两台Slave的读数据服务器,我们使用mysql_proxy多个数据库的轮询技术来进行两台Slave数据库的负载均衡分散访问措施,mysql-proxy可以做到,缺省就具有了简单的均衡功能,它自带的均衡功能是当有多台MySQL服务器的时候,进行逐个访问的原则,比如有A、B两台MySQL服务器,那么第一个连接就访问A,第二个连接访问B,第三个连接访问A,一次分布,达到A、B两台MySQL访问均衡。

对于mysql-proxy这个功能,我们进行检测一下。增加一个Lua检测脚本 test-conn.lua,就一个函数:

function read_query( packet )
    
print("read_query: connection.backend_ndx: ", proxy.connection.backend_ndx)
end

执行:
/usr/local/sbin/mysql-proxy --proxy-address=192.168.0.2:3306 --proxy-backend-addresses=127.0.0.1:3000 --proxy-backend-addresses=192.168.0.2:4000 --proxy-lua-script=./test-conn.lua

在windows上调用mysql客户端连接过去,打开多个cmd窗口进行连接:mysql -u root -h 192.168.0.2 -P 3306

看到mysql-proxy服务器端输出结果:

read_query: connection.backend_ndx:     1
read_query: connection.backend_ndx:     
2
read_query: connection.backend_ndx:     
1
read_query: connection.backend_ndx:     
2
read_query: connection.backend_ndx:     
1
read_query: connection.backend_ndx:     
2


很明显是按照逐个来轮询,这样能够达到平均分配连接的目的。

但是一个问题就是如果一台机器硬件设备比另外一台设备差,那么对数据库的连接就不能使用平均的方式了,那么完全使用Lua脚本构建自己的轮询连接算法,mysql-proxy的强大之处就在于能够支持Lua脚本进行各种控制,包括 连接服务器(connect_server)、连接握手(read_handshake)、提交验证(read_auth)、验证结果(read_auth_result)、提交查询(read_query)、查询结果(read_query_result) 等控制都是通过简单的在 --proxy-lua-script 选项中指定脚本来进行控制。

现在我们来简单改进一下连接服务器连接分配的算法,就在Lua脚本中增加一个 connect_server 函数就行。
比如按照当前时间进行分布连接到两台MySQL上:

function connect_server()
    
if (tonumber(os.date("%M")) % 2 == 0then
        proxy.connection.backend_ndx 
= 2
    
else
        proxy.connection.backend_ndx 
= 1
    
end
end

或者我们采取随机方式,在两台MySQL之间随机挑选一台:

function connect_server()
    local server_index 
= math.random(12)
    proxy.connection.backend_ndx
end

我们客户端继续连接多次,监测连接的服务器,发现连接的机器是随机展开的:

read_query: connection.backend_ndx:     1
read_query: connection.backend_ndx:     
2
read_query: connection.backend_ndx:     
2
read_query: connection.backend_ndx:     
1
read_query: connection.backend_ndx:     
1
read_query: connection.backend_ndx:     
2
read_query: connection.backend_ndx:     
2
read_query: connection.backend_ndx:     
1
read_query: connection.backend_ndx:     
1
read_query: connection.backend_ndx:     
1
read_query: connection.backend_ndx:     
2



【 压力测试 】

1. 连接数据库压力测试

测试代码使用PHP5.2,测试文件 php_mysql_proxy.php 代码:

<?php
//连接函数
function mysql_proxy_connect($is_close=true){
    
$link = mysql_connect("192.168.0.2:3306", "root", "", true);
    
if (!$link){
        
die('Could not connect: ' . mysql_error());
    }
    
if ($is_close){
        
echo ' close connection ... ';
        
mysql_close($link);
    }
    
return true;
}

//测试函数
function test($sum, $is_close=true){
    
for($i=0$i<$sum$i++){
        
echo "Connect mysql-proxy ". $i .".. ";
        
if (mysql_proxy_connect($is_close)){
            
echo "Succeed ";
        } 
else {
            
echo "Failed ";
        }
        
    }
}
?>

//测试1 (连续连接1w次,每次连接后不关闭连接)
test(10000);

Server: mysql-proxy 的CPU占用是从0.1%一直升到 12.4% 左右,然后结束后慢慢减下来,mysqld 的cpu占用率很低,%0.2左右
Client: 客户端在连接后马上关闭连接的状态下,一直持续到3948个连接的时候无法再连接到mysql-proxy
客户端输出:

...
Connect mysql-proxy 
3945.. close connection ... Succeed
Connect mysql-proxy 
3946.. close connection ... Succeed
Connect mysql-proxy 
3947.. close connection ... Succeed
Connect mysql-proxy 
3948..
Warning: mysql_connect(): Can't connect to MySQL server on '
192.168.0.2' (10048)
 in C:php_mysql_proxy.php on line 
4
Could not connect: Can't connect to MySQL server on '
192.168.0.2' (10048)

//测试2(连续连接1w次,每次连接后不关闭连接)
test(10000, false);

Server: mysql-proxy 的CPU占用是从0.1%一直升到 14.5% 左右,然后结束后慢慢减下来, mysqld 的cpu占用率也很低,%0.2左右
Client: 客户端在连接后马上不关闭连接的状态下,一直持续到3946个连接的时候无法再连接到mysql-proxy,基本跟关闭连接的最终处理数量差不多
输出信息:

Connect mysql-proxy 3944.. Succeed
Connect mysql-proxy 
3945.. Succeed
Connect mysql-proxy 
3946..
Warning: mysql_connect(): Can't connect to MySQL server on '
192.168.0.2' (10048)
 in C:php_mysql_proxy.php on line 
4
Could not connect:



2. 执行查询测试

测试脚本,php_mysql_proxy.php,代码如下:

<?php
//时间函数
function microtime_float(){
    
list($usec, $sec= explode(" ", microtime());
    
return ((float)$usec + (float)$sec);
}

//测试函数1(简单查询)
function test1(){
    
$link = mysql_connect("192.168.0.2:3306", "root", "", true);
    
if (!$link){
        
die('Could not connect: ' . mysql_error());
    }
    
for($i=0$i<10000$i++){
        
$res = mysql_query("select now()",$link);
        
echo "Query ".$i." ... ";
        
if (!$res){
            
echo('Could not query: ' . mysql_error());
            
return false;
        }
        
$row = mysql_fetch_row($res);
        
echo " Succeed ";
    }
}

//测试函数2(复杂查询)
function test2(){
    
$link = mysql_connect("192.168.0.2:3306", "root", "", true);
    
if (!$link){
        
die('Could not connect: ' . mysql_error());
    }
    
mysql_select_db("replaction", $link);
    
for($i=0$i<10000$i++){
        
$res = mysql_query("select * from t1 where id in (select id from t1)",$link);
        
echo "Query ".$i." ... ";
        
if (!$res){
            
echo('Could not query: ' . mysql_error());
            
return false;
        }
        
while($row = mysql_fetch_row($res)){}
        
echo " Succeed ";
    }    
}
?>


//执行测试1
$start_time = microtime_float();
test1();
$end_time = microtime_float();
echo "\nExecute Time: ". ($end_time - $start_time) ."\n";

测试结果:PHP执行时间和服务器端cpu占用率
Execute Time: 39.4633390903
mysql-proxy: 17.56%
mysqld-1: 5.26%
mysqld-2: 2.12%

//执行测试2
$start_time = microtime_float();
test2();
$end_time = microtime_float();
echo "\nExecute Time: ". ($end_time - $start_time) ."\n";

测试结果:PHP执行时间和服务器端cpu占用率
Execute Time: 62.6189789772
mysql-proxy: 19.09%
mysqld-1: 6.25%
mysqld-2: 3.08%

可以基本看出两者差别不是非常大,也可能是因为数据太少的缘故。


【 管理MySQL Proxy 】

在启动 mysql-proxy 之后,就会打开两个端口,一个是4040,这个是缺省用于提供给MySQL客户端连接使用的端口,可以通过 --proxy-address 选项修改为其他的,比如设置为 --proxy-address=192.168.0.2:3306,就完全模拟成了一台MySQL数据库了。另外默认开放 4041 的端口,这个是用来提供给管理 mysql-proxy 使用的,可以使用标准的mysql客户端来连接,同样能够通过 --admin-address 选项来设置为其他管理端口。

目前版本的管理功能还比较弱,只能够查看两个貌似是数据表的关于 mysql-proxy 的一些信息:
 mysql -u root -h 192.168.0.2 -P 4041

Welcome to the MySQL monitor.  Commands end with ; or g.
Your MySQL connection id is 1
Server version: 
5.1.20-agent MySQL Enterprise Agent

说明这是一个版本为5.1.20的MySQL的代理程序,查看目前mysql-proxy的运行信息:


mysql> select * from proxy_connections;
+------+--------+-------+------------+
| id   | type   | state | db         |
+------+--------+-------+------------+
|    0 | server | 0     |            |
|    1 | proxy  | 0     |            |
|    2 | proxy  | 10    | replaction |
|    3 | server | 10    |            |
+------+--------+-------+------------+
4 rows in set (0.02 sec)

mysql> select * from proxy_config;
+----------------------------+------------------+
| option                     | value            |
+----------------------------+------------------+
| admin.address              | :4041            |
| proxy.address              | 192.168.0.2:3306 |
| proxy.lua_script           | NULL             |
| proxy.backend_addresses[0] | 127.0.0.1:3000   |
| proxy.fix_bug_25371        | 0                |
| proxy.profiling            | 1                |
+----------------------------+------------------+
6 rows in set (0.02 sec)

 除了这两个状态信息,我貌似没有发现别的,不过基本的运行信息都包含了。


【 总结 】

先说说优点,使用简单,安装方便,各种平台的二进制版都有(这个是MySQL的传统优点),同时性能不错。
再说说缺点,缺点同样很明显,说两个典型的缺点:

1. 无法 Master/Slave 的区分
我一开始兴冲冲的以为 --proxy-read-only-backend-addresses 选项来构建一个支持Master/Slave的环境进行测试,但是我反复测试,发现无法实现,每次都是连接到Master,或者是做到每次都是按照连接算法来进行,mysql-proxy无法区分本次操作是写入操作还是读取操作而且划分到不同的MySQL机器。我后来又尝试也力求通过Lua脚本的方式来解决问题,自己定义连接情况,不过目前来看,定义的基本Lua接口,connect_server 是连接服务器,read_query 是整理SQL语句,我发现不论如何都是先执行了 connect_server 才去执行 read_query 的, 就是是先连接MySQL,然后执行的查询,这样就无法实现先拿到SQL语句,然后进行分析,发现是 insert/update/delete 全部拿到Master去执行,剩余的拿到Slave去执行,但是目前貌似无法实现,可能是我文档读的不够,或者是操作方法不对,非常希望在日后新版本中有比较方便简单的方式实现,因为一般使用 mysql-proxy 的人来说,都是因为负载高,数据连接太多或者是需要管理多台Slave机器,目前让 mysql-proxy 管理多台服务器是没有问题的,负载均衡也可以通过自行写Lua脚本控制。

2. mysql-proxy admin的管理功能太弱
目前发现除了能够查看两项信息之外,mysql-proxy admin 功能没有别的,比如重启服务呀,或者是查看目前执行连接和执行的SQL语句等等都没有,稍微弱了一点,希望在后期版本中加强。

大致功能都比较清楚了,测试速度也比较快,基本上目前来说,用于一些应用问题是不大的,稳定性也还好,毕竟目前是alpha版本,我们完全有热情去期待在正式版中会有很多新功能和对目前功能的改进,我无比的期待着。


【 相关URL 】

[ MySQL Proxy 相关URL ]
下载地址:http://dev.mysql.com/downloads/mysql-proxy/index.html
官方手册:http://dev.mysql.com/doc/refman/5.1/en/mysql-proxy.html
官方wiki:http://forge.mysql.com/wiki/MySQL_Proxy

[ Lua 相关URL ]
Lua官方网站:http://www.lua.org/
Lua英文手册:http://www.lua.org/manual/5.1/
Lua中文手册:http://www.codingnow.com/2000/download/lua_manual.html


(转载请著名来源:http://blog.csdn.net/heiyeshuwu,本文如有纰漏或者不正确的地方,欢迎指正,谢谢!)


【补充】

added 2008-01-29: 今天在InfoQ上面看到一篇文章《用MySQL-Proxy实现读写分离》文章使用了一个Lua脚本实现了读写分离的实现,大家可以参考。

发表于 @ 2008年01月28日 00:27:00|评论(loading...)|举报|收藏

新一篇: [转]Nginx 0.5.33 + PHP 5.2.5(FastCGI)搭建胜过Apache 10倍的Web服务器(第2版) | 旧一篇: [转]社区全文检索引擎Hyper Estraier 学习笔记

用户操作
[即时聊天] [发私信] [加为好友]
heiyeluren
订阅我的博客
XML聚合  FeedSky
订阅到鲜果
订阅到Google
订阅到抓虾
heiyeluren的公告

联系方式:


访问统计: free hit counter code
FeedSky订阅:
FeedSky订阅
文章分类
收藏
    ::eYou::
    kevin world
    lewis - 老吕
    qyb - BT的花
    Realzay的blog
    叶金荣
    天堂地狱鬼-dulao5's Blog
    沙漠之周
    狐狸糊涂
    老韩
    與子觀化
    鞋门
    ::Yahoo::
    glemir’s blog
    happy_fish - 分布式文件系统FastDFS
    LinZi's Blog
    Rainx
    stauren
    互联网,请记住我 - 162同学的技术博客
    冰的河
    北冥之鱼-张彪同学
    天韵之星
    小蚂蚁同学滴测试博客
    随网之舞 - kaven的DHTML博客
    风雪之隅
    ::朋友::
    【推荐】中文分类网
    DDR的博客
    kevin world
    miky
    PHPCup.cn论坛
    俺兄弟的blog
    冰河的技术博客:心随风动
    好旅网
    小少的技术博客
    无尘居
    晋陵路人的Blog
    李天华同学滴技术博客
    沙狐部落
    轻量级的editor
    ::网友::
    blankyao同学
    Code & Stock.
    Hello, Willko
    LionD8的Blog
    magiclab.cn
    MooPHP - 轻量级PHP框架
    Phzzy
    Xhttpd.cn
    张贺同学的博客
    技术大牛老余的博客
    抚琴居
    旋木木同学滴博客
    流水孟春
    矛盾网
    程序人生
    邢红瑞的blog
    阿健的博客
    :PHP博客:
    .: Easy style :.
    [琴剑楼]
    CoolCode.cn
    Haohappy的Blog
    Hightman
    iwind的blog
    Javascript开发站
    JD Space
    Nio's Weblog
    Open Source PHP
    PHP面对对象
    SourceForge.net
    trip的专栏
    UGIA.cn
    windix's blog
    Windix's Weblog
    一个藏袍
    俊麟 Michael`s blog
    偶然的blog
    刘敏的blog
    大龄青年的Blog
    廖宇雷的blog
    懒猫开始新生活blog
    某人的栖息地
    王春生的博客
    神仙
    :牛人blog:
    DBA notes
    http://blog.csdn.net/tingya/
    侯捷网站
    孟岩
    搜索引擎研究
    方舟
    王咏刚的BLOG
    竹笋炒肉
    荣耀
    车东[Blog^2]
    透明思考
    陈硕的Blog
    DHTML
    DHTMLGoodies
    FCKEditor
    Google Code
    Google Web Toolkit
    HTML Goodies
    HTML.it
    HTMLAre
    HTMLdog
    JavaScript Kit
    jQuery
    KindEditor
    Prototype
    TinyMCE
    W3 Schools
    Yahoo JavaScript Developer Center
    Yahoo! Developer Network
    Yahoo! UI Library (YUI)
    网页设计师Web标准
    Java国内站
    ChinaJavaWorld.com技术论坛
    IBM developerWorks 中国: Java
    Java中文站
    Java开源大全
    Java爱好者
    JR - Java翻译站
    J道-JDON
    Matrix: 与Java共舞
    中国Java开发网
    中文java技术网
    PHP国内站点
    CSDN PHP论坛
    Discuz!
    FleaPHP
    Google--PHP用户组
    IBM DeveloperWorks
    JavsScript技术讨论
    Nirvana Studio
    OpenPHP.cn
    PHPChina
    TiM Club
    中文 PFC 1.0 手册--PHP5的开发包
    中文 PFC 1.0 手册--PHP5的开发包
    中文PHP网
    太平洋--PHP开发区
    爱MySQL
    超越PHP
    PHP国外站点
    ADOdb
    Agavi Framework
    Cake PHP
    MySQL Performance Blog
    MySQL Performance Blog
    Nonaweb
    PEAR
    PECL
    PECL Windows
    PHP Builder
    PHP Classes
    PHP Classes
    PHP New Download
    PHP Security Consortium
    php.MVC
    php.MVC
    PHPkitchen(OO & MVC)
    phpPatterns
    PHP国外图书下载
    smart template
    Smarty
    SourceForge.net
    Symfony Framework
    Zend
    Zend Framework
    Unix C/C++
    Free Gentux
    周立发的blog(Linux C)
    Unix/Linux
    BSD智库
    ChinaUnix
    FreeBSDChina
    FreeLAMP
    IBM开发者Linux专区
    Linux Byte
    LinuxKit
    LinuxTS
    Linux伊甸园
    Linux技术中坚站
    Linux非常空间
    Love Unix
    NetBSD&OpenBSD中文用户组
    NetBSD中国社区
    Oracle中国用户讨论组
    OurLinux
    Unix中文
    Unix中文
    Unix中文宝库
    中国Linux公社
    中国Unix用户技术论坛
    中文FreeBSD用户组
    永远的Unix
    炎黄角马
    程序设计
    CSDN
    IBM开发者中心
    Microsoft TechNet: 主页
    MSDN 中文网站
    PHP中文站
    Sun技术社区
    中国IT认证实验室--企业应用技术
    中国协议分析网
    喜悦国际村
    太平洋电脑网---开发特区
    实用网站
    veBook(国外大量免费图书下载网站)
    Whois.net
    中国Web信息博物馆
    中国互联网络信息中心whois查询
    服务器系统信息查看
    网络安全
    AnySide.com
    CGI Secutiry
    K-OTik Security Monitoring
    Linux Security
    Packet Storm Security
    PHP Secure
    RFC中文文档索引
    Safemode.org
    SecuriTeam.com
    Security Corporation
    SecurityFocus
    SecurityTracker
    Zone-h (区域黑客,每天公布各国被黑的网站)
    中华安全网
    中国信息安全组织
    国家计算机网络应急处理中心
    安全天使
    安全焦点
    幻影旅团
    绿盟科技
    网络安全评估中心(cnns )
    在线手册
    Apache2.0中文文档
    Beyond Linux From Scratch
    Debian参考手册
    FreeBSD Porter 手册
    FreeBSD使用手册
    Linux C函数中文参考手册
    MySQL 4.1.0 中文参考手册
    NetBSD在线手册
    OpenBSD在线FAQ
    PHP ADODB 1.99版手册中文翻译(Tripc)
    PHP中文手册(国内)
    PHP中文手册(国外)
    PostgreSQL中文文档
    Red Hat Linux 9入门指南
    Red Hat Linux 9安装指南
    Red Hat Linux 9定制手册
    中国OSS技术手册中心
    技术文档手册中心-ChinaUnix
    存档
    Csdn Blog version 3.1a
    Copyright © heiyeluren