用HAProxy来检测MySQL复制的延迟的教程
在MySQL世界里,HAProxy通常来作为软件负载均衡器使用。彼得.博罗什在过去的邮件中解释了如何使用perconaxtradb集群(pxc)来对其设置。所以它只发送查询到可应用的节点。同样的方法可用于常规主从设置来读取负载并分散到多个从节点。不过,使用MySQL复制,另一个因素开始发挥作用:复制延迟。在这种情况下,被提及到的PerconaxtraDB集群以及我们提出只返回“向上”或者“向下”的检查方法行不通。我们将希望依赖其复制延迟来调整内部Haproxy的一个权重。这就是我们要做的在这篇文章中使用HAProxy1.5。
HAProxy的代理检测
HAProxy1.5运行我们运行一个代理检测,这是一项可以添加到常规健康检测项的检测。代理检测的好处是返回值可以是‘up'或‘down',但也可以是个权重值。
代理是什么呢?它是一个简单的可以访问给定端口上TCP连接的程。所以,如果我们要在一台MySQL服务器上运行代理,这需要:
- 如果不运行复制的话确保服务在HAProxy上是停止的
- 如果复制延迟小于10s,设置weight为100%
- 如果延迟大于等于10s,小于50s,设置weight为50%
- 在其他情况下设置weight为5%
我们可以使用这样一个脚本:
$lessagent.php
<!--?php
//Simplesocketserver
//Seehttp://php.net/manual/en/function.stream-socket-server.php
$port=$argv[1];
$mysql_port=$argv[2];
$mysql="/usr/bin/mysql";
$user='haproxy';
$password='haproxy_pwd';
$query="SHOWSLAVESTATUS";
functionset_weight($lag){
#Writeyourownruleshere
if($lag=='NULL'){
return"down";
}
elseif($lag<10){
return"up100%";
}
elseif($lag-->=10&&$lag<60){
return"up50%";
}
else
return"up5%";
}
set_time_limit(0);
$socket=stream_socket_server("tcp://127.0.0.1:$port",$errno,$errstr);
if(!$socket){
echo"$errstr($errno)
n";
}else{
while($conn=stream_socket_accept($socket,9999999999999)){
$cmd="$mysql-h127.0.0.1-u$user-p$password-P$mysql_port-Ee"$query"|grepSeconds_Behind_Master|cut-d':'-f2|tr-d''";
exec("$cmd",$lag);
$weight=set_weight($lag[0]);
unset($lag);
fputs($conn,$weight);
fclose($conn);
}
fclose($socket);
}
?>
如果你希望脚本从端口6789发出连接到运行在3306端口上的MySQL实例,这样运行:
$phpagent.php67893306
你还需要指定MySQL用户:
mysql>GRANTREPLICATIONCLIENTON*.*TO'haproxy'@'127.0.0.1'IDENTIFIEDBY'haproxy_pwd';
代理启动后,你可以检测一下它是否正常运行:
#telnet127.0.0.16789 Trying127.0.0.1... Connectedto127.0.0.1. Escapecharacteris'^]'. up100% Connectionclosedbyforeignhost.
假设它运行在本地的应用服务器上,有两个复制正在运行(192.168.10.2和192.168.10.3),应用的读请求在3307端口,你需要在HAProxy中配置一个前端和后端,像这样:
frontendread_only-front bind*:3307 modetcp optiontcplog logglobal default_backendread_only-back backendread_only-back modetcp balanceleastconn serverslave1192.168.10.2weight100checkagent-checkagent-port6789inter1000 rise1 fall1on-marked-downshutdown-sessions serverslave2192.168.10.3weight100checkagent-checkagent-port6789inter1000 rise1 fall1on-marked-downshutdown-sessions
现在所有的都准备好了,现在让我们看看怎么使用HAProxy来动态的改变重滞服务器,代码如下:
#Slave1
$mysql-Ee"showslavestatus"|grepSeconds_Behind_Master
Seconds_Behind_Master:0
#Slave2
$mysql-Ee"showslavestatus"|grepSeconds_Behind_Master
Seconds_Behind_Master:0
#HAProxy
$echo"showstat"|socatstdio/run/haproxy/admin.sock|cut-d','-f1,2,18,19
#pxname,svname,status,weight
read_only-front,FRONTEND,OPEN,
read_only-back,slave1,UP,100
read_only-back,slave2,UP,100
read_only-back,BACKEND,UP,200 时延1
#Slave1
$mysql-Ee"showslavestatus"|grepSeconds_Behind_Master
Seconds_Behind_Master:25
#Slave2
$mysql-Ee"showslavestatus"|grepSeconds_Behind_Master
Seconds_Behind_Master:0
#echo"showstat"|socatstdio/run/haproxy/admin.sock|cut-d','-f1,2,18,19
#pxname,svname,status,weight
read_only-front,FRONTEND,OPEN,
read_only-back,slave1,UP,50
read_only-back,slave2,UP,100
read_only-back,BACKEND,UP,150 时延2
#Slave1
$mysql-Ee"showslavestatus"|grepSeconds_Behind_Master
Seconds_Behind_Master:0
#Slave2
$mysql-Ee"showslavestatus"|grepSeconds_Behind_Master
Seconds_Behind_Master:NULL
#echo"showstat"|socatstdio/run/haproxy/admin.sock|cut-d','-f1,2,18,19
#pxname,svname,status,weight
read_only-front,FRONTEND,OPEN,
read_only-back,slave1,UP,100
read_only-back,slave2,DOWN(agent),100
read_only-back,BACKEND,UP,100 结论
在HAProxy1.5中代理检查是一个很好的新增功能。在上面的设置中是简单的:举例来说,如果HAProxy连接代理失败,它就不会被标记。推荐与代理检查一起,保持常规的健康度检查。
细心的读取者们(reads)将会注意到这个配置,如果在所有节点上都被复制,HAProxy将会停止发送给读取者.这可能不是最好的解决方案。但可能的选项是:停止代理并标记服务器为UP,使用状态套接字(socket)或者添加主节点作为备份服务器。
最后一点,使用Percona工具集的pt-heartbeat替代Seconds_Behind_Master,您可以编辑代理的代码,可以对复制的延迟进行测量。