使用 HAProxy 对 MySQL 进行负载平衡:读取通信数据包时出现错误?

使用 HAProxy 对 MySQL 进行负载平衡:读取通信数据包时出现错误?

我已经设置了通过 xinetd 使用 HAProxy 对 MySQL 从属服务器进行负载平衡.2个负载均衡器共享一个由Pacemaker管理的虚拟IP:

crm configure show

node SVR120-27148.localdomain
node SVR255-53192.localdomain
primitive failover-ip ocf:heartbeat:IPaddr2 \
    params ip="192.168.5.9" cidr_netmask="32" \
    op monitor interval="5s" \
    meta is-managed="true"
primitive haproxy ocf:heartbeat:haproxy \
    params conffile="/etc/haproxy/haproxy.cfg" \
    op monitor interval="30s" \
    meta is-managed="true"
colocation haproxy-with-failover-ip inf: haproxy failover-ip
order haproxy-after-failover-ip inf: failover-ip haproxy
property $id="cib-bootstrap-options" \
    dc-version="1.0.12-unknown" \
    cluster-infrastructure="openais" \
    no-quorum-policy="ignore" \
    expected-quorum-votes="2" \
    stonith-enabled="false" \
    last-lrm-refresh="1342783084"

/etc/haproxy/haproxy.cfg

global
    log 127.0.0.1 local1 debug
    maxconn 4096
    pidfile /var/run/haproxy.pid
    daemon

defaults
    log global
    mode tcp
    option dontlognull 
    retries 3 
    option redispatch
    maxconn 2000
    contimeout 5000
    clitimeout 50000
    srvtimeout 50000

frontend FE_mysql
    bind 192.168.5.9:3307
    default_backend BE_mysql

backend BE_mysql
    mode tcp
    balance roundrobin
    option tcpka
    option httpchk
    #server mysql1 192.168.6.47:3306 weight 1 check port 9199 inter 12000 rise 3 fall 3
    server mysql2 192.168.6.248:3306 weight 1 check port 9199 inter 12000 rise 3 fall 3
    server mysql3 192.168.6.129:3306 weight 1 check port 9199 inter 12000 rise 3 fall 3

我的问题是大多数时候通过虚拟 IP 连接,/var/log/mysqld.log不断出现以下信息:

120719 12:59:46 [Warning] Aborted connection 17237 to db: 'db' user: 'user' host: '192.168.5.192' (Got an error 
reading communication packets) 
120719 12:59:49 [Warning] Aborted connection 17242 to db: 'db' user: 'user' host: '192.168.5.192' (Got an error 
reading communication packets) 
120719 12:59:52 [Warning] Aborted connection 17248 to db: 'db' user: 'user' host: '192.168.5.192' (Got an error 
reading communication packets) 

(连接仍然建立)

192.168.5.192是 HAProxy 的 IP 地址。

mysql> show global status like 'Aborted%';
+------------------+-------+
| Variable_name    | Value |
+------------------+-------+
| Aborted_clients  | 53626 |
| Aborted_connects | 400   |
+------------------+-------+

我认为 128M 不足以满足以下要求max_allowed_packet

max_connections = 300
max_allowed_packet = 128M

_timeout变量:

mysql> show global variables like '%timeout';
+----------------------------+----------+
| Variable_name              | Value    |
+----------------------------+----------+
| connect_timeout            | 10       |
| delayed_insert_timeout     | 300      |
| innodb_lock_wait_timeout   | 60       |
| innodb_rollback_on_timeout | OFF      |
| interactive_timeout        | 3600     |
| lock_wait_timeout          | 31536000 |
| net_read_timeout           | 30       |
| net_write_timeout          | 60       |
| slave_net_timeout          | 3600     |
| wait_timeout               | 600      |
+----------------------------+----------+

有什么原因会导致这种情况吗?这与 HAProxy 有关吗?

有什么想法吗?

答案1

以下是 MySQL 中给出的原因文档

max_allowed_pa​​cket 变量值太小,或者查询需要的内存比您为 mysqld 分配的内存多。请参见第 C.5.2.10 节“数据包太大”。

在 Linux 中使用以太网协议,包括半双工和全双工。许多 Linux 以太网驱动程序都有此错误。您应该通过在客户端和服务器计算机之间使用 FTP 传输大型文件来测试此错误。如果传输处于突发-暂停-突发-暂停模式,则您遇到了 Linux 双工综合症。将网卡和集线器/交换机的双工模式切换为全双工或半双工,并测试结果以确定最佳设置。

线程库存在问题,导致读取时发生中断。

TCP/IP 配置错误。

以太网、集线器、交换机、电缆等出现故障。只有更换硬件才能正确诊断。

和,解释得更好:

尽管它们可能是更大问题的征兆,但它们可能是由正常(即可预防的)网络问题引起的。

即使它们位于同一个 LAN 上,由于各种原因,您的应用服务器和数据库之间也可能发生通信错误。在通信中断或超时的情况下,应用程序和/或 MySQL 很可能会重试并正常工作,问题永远不会浮现或显现出来。

根据我的经验,这些类型消息的最常见来源是应用程序(服务器)出现故障、应用程序未正确终止连接或异地复制中的延迟。

很可能它们在您启用 MySQL 服务器上的错误日志记录之前就已经发生了。

答案2

我发现增加 haproxy.cfg 文件中的超时设置可以解决此错误。我花了很多时间检查 my.cnf wait_timeout 等,并意识到瓶颈实际上是 HAProxy。

答案3

检查 haproxy mannul

tune.idletimer

设置 haproxy 认为空缓冲区可能与空闲流关联的持续时间。这用于在交替转发大数据和小数据时最佳地调整某些数据包大小。此参数决定使用 splice() 还是在 SSL 中发送大缓冲区。该值以毫秒为单位,介于 0 和 65535 之间。零值表示 haproxy 不会尝试检测空闲流。默认值为 1000,这似乎可以正确检测最终用户的暂停(例如:在单击之前阅读页面)。应该没有理由更改此值。请检查下面的 tune.ssl.maxrecord。

我设置tune.idletimer=60000并重新启动了 haproxy 服务。问题再次出现。我在 haproxy 1.8.14 中遇到了这个问题

旧的 haproxy 1.5.4 可以。

答案4

对我来说,我必须使用/更改的主要设置是:

timeout connect 6s
timeout client  600s
timeout server  600s

我怀疑有些客户端出于性能考虑会维护与 mysql 的套接字连接 - 尤其是 PHP,因此唯一的解决方法是允许它们更长时间地维护此类连接。我发现 600s 后错误消失,并使用该值进行处理。

相关内容