Kevin,
for simplicity, let's call the 3 clusters HG11, HG21 and HG31.
And always for simplicity, the servers are 10.10.X.Y .
And to add some complexity, we will also enable read/write split , where the readers are HG12, HG22 , HG32 .
INSERT INTO mysql_servers (hostgroup_id,hostname) VALUES
(11,"10.10.10.1"),
(12,"10.10.10.1"), (12,"10.10.10.2"), (12,"10.10.10.3"),
(21,"10.10.20.1"),
(22,"10.10.20.1"), (12,"10.10.20.2"), (12,"10.10.30.3"),
(11,"10.10.30.1"),
(12,"10.10.30.1"), (12,"10.10.30.2"), (12,"10.10.30.3");
## enable replication hostgroups
INSERT INTO mysql_replication_hostgroups (writer_hostgroup,reader_hostgroup) VALUES
(11,12),(21,22),(31,32);
## create rules for read/write split
INSERT INTO mysql_query_rules (rule_id, active, match_digest, flagOUT) VALUES
(1,1,'^SELECT.*FOR UPDATE',100),
(2,1,'^SELECT',200),
(3,1,'.*',100);
## sharding, sending traffic to masters
INSERT INTO mysql_query_rules (active, flagIN, schemaname, destination_hostgroup, apply) VALUES
(1,100, "shard001", 11, 1),
(1,100, "shard002", 11, 1),
(1,100, "shard003", 11, 1),
(1,100, "shard004", 11, 1),
...
(1,100, "shard050", 21, 1),
(1,100, "shard051", 21, 1),
(1,100, "shard052", 21, 1),
(1,100, "shard053", 21, 1),
(1,100, "shard054", 21, 1),
...
(1,100, "shard100", 21, 1),
(1,100, "shard101", 31, 1),
...
(1,100, "shard150", 31, 1);
## sharding, sending traffic to slaves
INSERT INTO mysql_query_rules (active, flagIN, schemaname, destination_hostgroup, apply)
SELECT 1, 200, schemaname, destination_hostgroup+1 , 1 FROM mysql_query_rules WHERE flagIN=100;
## load everything to runtime:
LOAD MYSQL SERVERS TO RUNTIME;
LOAD MYSQL QUERY RULES TO RUNTIME;
Now ProxySQL can route traffic using only 1 single port, while for HAProxy you would need 300 different ports.