mysql-proxy中Admin Plugin的使用以及读写分离的问题

一年前听Hiro说过MySQL Proxy这个应用,直到现在才来了兴致鼓弄鼓弄,也是因为来到这边后,有生产环境一直在用mysql-proxy实现应用的读写分离,前辈搭好的架构现在好好学习下。也就是从昨天开始,亲自搭建了这个环境,学习学习。下面就说说我的测试环境以及遇到的很多晕来晕去的问题。

先简单说下什么是MySQL Proxy。从名字上就清晰可见代理嘛,就是在你能直接进行操作前,都要经过这个代理或是agent(国外片里的特工),client-agent-server就是这么一个过程,既然mysql-proxy加在客户端和服务端之间,那么它就必须要能听懂双方说的是什么,它的角色就像一名接线员(operator)。我们都知道mysql client和mysqld通信时,采用的是MySQL自己的网络协议,而MySQL Proxy也同样使用的是这个网络协议,那么三者之间也就没有什么障碍了。除了可以按照策略分发请求,既然放在两者中间,那么所有过来的请求它自然都可以截获,如果你愿意当然还可以做操作前的审核,也可注入些新的东西。Agent嘛,无所不能,不过你需要先对Lua无所不能LoL。

实验环境:

CentOS 5.4 + mysql-proxy-0.8.1-linux-glibc2.3-x86-64bit.tar.gz + mysql-5.0.77

192.168.109.5 (mysql-proxy) — 在前端,做读写分离(proxy和主库在一台机器上);

192.168.109.5 (master) + 192.168.109.6 (slave) — 主从同步(测试读写是否分离是,关闭同步,便于我们观察分离情况)

具体实施:

mysql-proxy  -admin-lua-script=/usr/local/mysql-proxy/admin.lua -admin-username=root -admin-password=pass -proxy-address=192.168.109.5:4040 -proxy-backend-addresses=192.168.109.5:3306 -proxy-read-only-backend-addresses=192.168.109.6:3306 -proxy-lua-script=/usr/local/mysql-proxy/rw-splitting.lua -proxy-lua-script=/usr/local/mysql-proxy/reporter.lua -daemon > /tmp/mysql-proxy-err.log

NOTE: mysql-proxy二进制包解压好就能用了,但是需要注意的是一些lib和libexec的路径,即便你-plugin-dir,-lua-path,-basedir都用了执行上面的语句还是会告诉你不是libmysql-chassis.so.0、libadmin.so发现不了,就是commands.so,commands.lua,proxy.so这些找不到。你看下源码包下的./configure -help,就会知道mysql-proxy的相关默认路径(/usr/local/bin, /usr/local/lib),所以,解压后把目录下对应的文件/文件夹copy到这些目录下就不会在有那些犯人的error了。

Lua Scripts: admin.lua和reporter.lua这两个Lua脚本就可以使用mysql-proxy提供的Admin Plugin的功能,对请求进行统计同时还可以显示各种状态;rw-splitting.lua这个脚本就是我们用来做读写分离的,它里面还有两个可以调整的参数分别是:min_idle_connections,max_idle_connections,测试中发现,mysql-proxy与mysqld建立的是长连接,如果你不去主动断开连接,该线程会一直空置在那里,那么这两个命令就可以很好的控制空闲线程的数量,减少资源的浪费。

Admin Plugin 测试:

打开一个客户端,通过mysql-proxy的管理端口(4041),登录到mysql-proxy上,便可以执行Proxy的一些管理语句。

1. shell> mysql -uroot -ppass -P4041 -h192.168.109.5

2. mysql> show querycounter;
+——————-+
| query_counter |
+——————-+
|             2                  |
+——————-+

Note: 这个语句显示的数字是一个累加值,默认一开始是NULL,由这么几部分组成:当你通过mysql连接proxy时会被+1,当你每执行一次sql语句时会被+1,当你quit断开连接时会被+1。

3.  mysql> show proxy processlist;
+——+——————————+————————————+
| Id      | IP Address                            | Time                                                  |
+——+——————————+————————————+
| 14      | 192.168.115.9:48611       | Wed Nov 10 10:17:58 2010   |
| 15      | 192.168.115.10:47626   | Wed Nov 10 10:18:24 2010    |
+——+——————————+————————————+

Note: 这个语句的输出结果,可以告诉我们当前的请求都来自哪里是什么时候连过来的,和Mysql的show processlist效果一样,只不过信息不是那么丰富。有时候执行这个语句会报错误,别太在意,当有请求连接过来以后,你再次执行,就正常了,不知道什么原因。

4. mysql> SELECT * FROM backends;
+—————-+————————-+——-+——+
| backend_ndx | address                            | state  | type |
+—————-+————————-+——-+——+
|           1                 | 192.168.109.5:3306 | 1          | 1        |
|           2                 | 192.168.109.6:3306 | 0         | 2        |
+—————-+————————-+——-+——+

Note: 这个sql语句,还是蛮不错的,告诉我们proxy后端当前代理了哪些DB Server;type这个字段有两个值,1表示该数据库是主库,2表示该数据库是从库;state字段提示DB处于一个什么状态,0表示当前没有请求处于空闲,1表示已经有客户端发起过请求了,即便你断开客端后,这个值还是1,2表示mysqld的服务被停掉了。

5. 还有一个sql可以执行,打开admi.lua你会看到有一个help,就是下面的,告诉你可以执行的语句有谁。

mysql> select help;
+————————————+———————————————————-+
| command                                        | description                                                                          |
+————————————+———————————————————-+
| SELECT HELP                                | This command.                                                                   |
| SHOW PROXY PROCESSLIST  | Show all connections and their true IP Address. |
+———————————-+———————————————————-+

NOTE: 当reporter.lua和rw-splitting.lua一起被设置时,show querycounter;与show proxy processlist; 执行失败没有结果输出。

读写分离遇到的问题:

通过mysql-proxy的4040端连接进来,无论我执行写的操作还是查询的操作,所有的请求都会被发到主库(192.168.109.5)上,也就是-proxy-backend-addresses指定的主机。还发现上面启动的mysql-proxy,也不会对多了连接请求进行轮询分配,就是盯着那个192.168.109.5的主机一个来-_-!!!…郁啦。如果将上面的启动项中-proxy-read-only-backend-addresses也改为-proxy-backend-addresses,那么就可以对请求做轮询处理了,不过这样的话,客服端的请求就也会在从库进行写入操作,不允许的。

终于有了新的发现,就在此刻为了这个纠结的问题,我又再一次的仔细看了一下线上前辈配置的启动项,发现和我的有区别呀,没有配置主库的-proxy-backend-addresses,只有-proxy-read-only-backend-addresses配置的4个从库的ip。我调整后,还是不行呀!!!!奇怪的是,4040连接过来后,mysql-proxy直接就与主库建立了连接,不应该呀,还没有发送具体的操作请求怎么就,擅自决定呢,霸道!?苍天呀。。。有谁能拯救下我呀。。。都第二天啦

troubleshooting…….helping…….

——UPDATED——

2010-11-10 17:20 —MySQL Proxy终于弄明白了,问题解决了,谢谢坐在我旁边东软的哥们,还有MSN群里Dong兄的提示。分析如下:

其实,之前的启动选项是没有问题的,问题的关键在于rw-splitting.lua脚本中的min_idle_connections,max_idle_connections,这两个参数的默认设置最小是4,最大是8,而恰恰之前我测试的时候开启的客户端只有3个,所以,每次连接进来,select看到的总是主库上的记录,proxy会将预先建好的连接连到主库上,如果你连接的请求数小于这个默认值,那么是不会进行读写分离的,只有当请求数大于这个默认值时才会将读的请求发给从库去读,因为proxy会通过read_query()这个函数将新建立连接,按照我们之前启动项中的规则重定向,写到proxy-backend-addresses,读到proxy-read-only-backend-addresses。

此外,当我们使用rw-splitting.lua这个脚本启动,proxy-backend-addresses是读写均可,proxy-read-only-backend-addresses是只读;否则如果光设置后者,也均支持读写。

@打完,收工!

觉得文章有用?立即: 和朋友一起 共学习 共进步!

猜您喜欢

2 thoughts on “mysql-proxy中Admin Plugin的使用以及读写分离的问题

  1. 您好,请问为什么我链接4041端口后运行任何命令都报错呢?
    ERROR 2006 (HY000): MySQL server has gone away
    No connection. Trying to reconnect…
    Connection id: 1
    Current database: *** NONE ***

    ERROR 1105 (07000): need a resultset + proxy.PROXY_SEND_RESULT

发表评论

电子邮件地址不会被公开。 必填项已用 * 标注

*

您可以使用这些 HTML 标签和属性: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>