MySQL-Proxy负载平衡测试遇到的问题及其分析 && MySQL-Proxy工作机制

(1)MySQL-Proxy负载平衡测试中遇到的问题及其分析

 

(a)在0.8.1版mysql-proxy的负载平衡测试中,出现了如下的测试结果:

 

第一次启动mysql-proxy:
[root@rap2 ~]# mysqlslap -h 127.0.0.1 -P 4040 -u root -pcps-pt --create-schema=database_name --query='SELECT * FROM table_name WHERE id = 18' -c 7 -i 10 --number-of-queries 10000

* 有三台backend服务器,104,110和111
查询分配情况比较
104(主)     110(从)    111(从)
8.5%        51.6%      39.9%
(8519次)  (51598次)  (39839次)


在不重新启动mysql-proxy的情况下,继续执行上述测试,查询的分配情况如下所示:
* 有三台backend服务器,104,110和111
查询分配情况比较
104(主) 110(从)      111(从)
0%       50.6%        49.4%

(0次)     (50580次)  (49374次)

 

(b)分析上述测试结果可以得出这样的结论:
①在第一次启动mysql-proxy后,10万次查询中有一部分(8.5%)流向了主服务器(104),剩下的查询在从服务器110和111中也没有实现均衡分配, 由此可知,在本次测试中,mysql-proxy的负载平衡没有实现并且主服务器还承担一部分查询操作;
②第一次启动mysql-proxy后,先执行了一次10万次查询,然后继续执行同样的测试时,不但所有的查询都集中在从服务器(110和111), 而且从服务器之间也基本实现了查询次数的均衡分配;

那么为什么会出现上面奇怪的结论呢?
想知道结果的话,就要深入分析mysql-proxy的工作机制。
#想了解mysql-proxy的工作机制的话请参照【(2)MySQL-Proxy工作流程】。

 

(c)了解完mysql-proxy的工作机制,继续分析出现结论(b)的原因:
①当mysql-proxy处于第一次启动后,连接池中没有创建任何数据库服务器的连接。
  当第一次查询请求过来后,根据balance.lua中的idle_ro()逻辑,mysql-proxy选择从连接池中拿从服务器的连接。
  然而此时的连接池中没有任何连接,那么根据rw-splitting.lua中的connect_server()逻辑,
  mysql-proxy没有拿到任何连接时,优先从连接池中拿主服务器的连接,此时mysql-proxy就会默认创建一个主服务器的连接;
②查询请求越来越多,mysql-proxy会不断的创建主服务器的连接。当主服务器的连接数超过最低空闲连接数(min_idle_connections)后,
  mysql-proxy才会继续创建第一个从数据库的连接;
③mysql-proxy依次按照上述规则创建数据库连接,直至所有的数据库连接都被创建过并且其数目达到最低空闲连接数(min_idle_connections);
④当所有的主从数据库连接都被创建过后,再有查询请求过来的话,mysql-proxy会按照从服务器选择函数idle_ro()的逻辑来选择当前连接状态最少的从服务器进行连接(即实现了负载均衡)。
⑤有了上面四步的解析,现在应该对出现结论(b)的原因很清楚了吧。

 

(d)附录→关于在mysql-proxy0.8.0和0.8.1中实现负载均衡的脚本修正:

* 修改文件:
/usr/local/mysql_proxy_0.8.1/lib/mysql-proxy/lua/proxy/balance.lua

*修改函数:idle_ro()
*  < 表删除;  > 表追加;

<       local max_conns_ndx = 0
---
>         local max_conns_ndx = math.random(2,#proxy.global.backends)
>         local s_tmp = proxy.global.backends[max_conns_ndx]
>         local conns_tmp = s_tmp.pool.users[proxy.connection.client.username]
>         if s_tmp.type == proxy.BACKEND_TYPE_RO and
>            s_tmp.state ~= proxy.BACKEND_STATE_DOWN and
>            conns_tmp.cur_idle_connections > 0 then
>              max_conns = s_tmp.connected_clients
>         else
>           max_conns_ndx = 0
>         end

 

 

(2)MySQL-Proxy工作流程(如图附件proxy_main.jpg所示):

#连接池连接规则的创建在rw-splitting.lua中完成。
第一步:
按照backend服务器设置的顺序(通常是主服务器+从服务器若干台),当client发起连接时,
就先在没有满足最低空闲连接数的服务器上创建一个连接。

第二步:
当此次查询是读操作时,根据balance.lua中的idle_ro()逻辑选择从连接池中拿从服务器的连接。
从服务器选择函数idle_ro()的逻辑是选择当前为连接状态最少的服务器进行连接的(前提是当前连接池中有从服务器的连接)

第三步:
最后还没有拿到连接时,从连接池中拿主服务器的连接。

 

你可能感兴趣的:(mysql,工作,脚本,lua)