HAProxy vs Nginx for MySQL 8.0 MGR: Which Load Balancer Performs Better?

This article details a practical performance and high‑availability comparison of HAProxy and Nginx as software load balancers for a MySQL 8.0 InnoDB Cluster (MGR) setup, covering environment configuration, Keepalived integration, test methodology, results, and final recommendations.

dbaplus Community
dbaplus Community
dbaplus Community
HAProxy vs Nginx for MySQL 8.0 MGR: Which Load Balancer Performs Better?

Background

The author’s team needed to deploy multiple MySQL 8.0 community‑edition clusters using MySQL Group Replication (MGR) with a primary‑replica topology and MySQL Router for read/write splitting. To avoid a single point of failure in the Router, they added a software load balancer (HAProxy or Nginx) and Keepalived on the management nodes for high availability.

Environment Configuration

Hardware (virtual machines)

Management Node 1 & 2: 2 CPU, 4 GB RAM, 32 GB disk, IP 10.*.*.216/217

Database Node 1‑3: 2 CPU, 8 GB RAM, 128 GB disk, IP 10.*.*.210‑212

Virtual IP: 10.*.*.218

Software versions

CentOS 8.0

MySQL 8.0.18

Keepalived 2.0.10

HAProxy 1.8.15

Nginx 1.18.0

Keepalived Configuration

vrrp_instance VI_1 {
    state MASTER
    interface ens192
    virtual_router_id 51
    priority 100
    advert_int 1
    authentication {
        auth_type PASS
        auth_pass 11111111
    }
    virtual_ipaddress { 10.*.*.218 }
    track_script { chk_alived }
}

vrrp_script chk_haproxy {
    script "/etc/keepalived/checkalived.sh"
    interval 3
    weight -5
}

The accompanying checkalived.sh script stops Keepalived when the monitored service (e.g., Nginx) is not running:

#!/bin/bash
if [ `ps -C nginx --no-header | wc -l` -eq 0 ]; then
    systemctl stop keepalived
fi

HAProxy Configuration

listen mysqlrw
    bind :3366
    mode tcp
    balance roundrobin
    server mysql1 10.*.*.210:6446 check maxconn 300
    server mysql2 10.*.*.211:6446 check maxconn 300
    server mysql3 10.*.*.212:6446 check maxconn 300

listen mysqlro
    bind :3367
    mode tcp
    balance roundrobin
    server mysql1 10.*.*.210:6447 check maxconn 300
    server mysql2 10.*.*.211:6447 check maxconn 300
    server mysql3 10.*.*.212:6447 check maxconn 300

listen stats
    bind 10.230.137.218:1080
    mode http
    stats refresh 30s
    stats uri /dbs
    stats auth admin:admin
    stats hide-version

Nginx Configuration (stream module)

stream {
    upstream db {
        server 10.*.*.210:6446;
        server 10.*.*.211:6446;
        server 10.*.*.212:6446;
    }
    server {
        listen 3366;
        proxy_pass db;
        proxy_connect_timeout 2s;
        access_log /usr/local/nginx/logs/access3366_log mysql;
    }
    upstream dbro {
        server 10.*.*.210:6447;
        server 10.*.*.211:6447;
        server 10.*.*.212:6447;
    }
    server {
        listen 3367;
        proxy_pass dbro;
        proxy_connect_timeout 2s;
        access_log /usr/local/nginx/logs/access3367_log mysql;
    }
}

Test Methodology

Four test cases were defined:

Load‑balancer distribution fairness (each DB node receives similar session count).

Detection of MySQL Router failure (kill a Router process and verify traffic is still balanced).

Performance comparison (measure total time for 64 concurrent queries).

High‑availability validation (kill the load‑balancer on the primary management node and confirm the virtual IP fails over to the standby).

A Bash loop executed a configurable number of queries against the read/write virtual port, counting sessions until a preset limit was reached:

while true; do
    mysql -u$USER -p$PASSWORD -h$ROUTE_HOST -P$RW_PORT --protocol=TCP -e "$SQL_TEXT1"
    let COUNT+=1
    if [ $COUNT -ge $SESS_NUM ]; then break; fi
done

Test Results

Both HAProxy and Nginx distributed the 64 queries across the three database nodes with roughly equal session counts. Execution time was comparable; neither load balancer showed a clear advantage under the same hardware constraints.

When the MySQL Router process was killed, both load balancers continued to route traffic to the remaining healthy nodes, confirming fault detection.

High‑availability tests demonstrated that Keepalived successfully promoted the standby management node, and the virtual IP remained reachable, allowing client connections to continue without interruption.

Conclusion

Functionally, HAProxy and Nginx both achieve balanced read/write distribution and can detect MySQL Router failures. Performance differences are negligible in this environment. HAProxy offers a built‑in graphical statistics page, making monitoring easier, whereas Nginx requires external log analysis. Both solutions, when combined with Keepalived, provide robust high‑availability for MySQL 8.0 MGR clusters.

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

mysqlNginxHAProxykeepalived
dbaplus Community
Written by

dbaplus Community

Enterprise-level professional community for Database, BigData, and AIOps. Daily original articles, weekly online tech talks, monthly offline salons, and quarterly XCOPS&DAMS conferences—delivered by industry experts.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.