Linux – Use tc prio qdisc for MySQL Traffic Prioritization

filterlinuxMySQLtctraffic

I am struggling with tc prio qdisc for a few hours now.
I have read the lartc Documentation, Examples and HowTos, but this whole thing is kinda new for me and somewhat confusing 🙂

So this is my scenario:
A couple of fileservers serving a high-volume of http and ftp traffic.
I need to prioritize mysql traffic, because often when the links are full the sql traffic becomes slow and/or garbled, leading to connection errors, timeouts and so on.

This is what i have so far:

# tc qdisc add dev eth0 root handle 1: prio
# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 22 0xffff flowid 1:1
# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 3306 0xffff flowid 1:1
# tc filter add dev eth0 parent 1: prio 3 protocol all u32 match u32 0 0 flowid 1:3
# tc -s qdisc ls dev eth0
qdisc prio 1: root refcnt 2 bands 3 priomap  1 2 2 2 1 2 0 0 1 1 1 1 1 1 1 1
Sent 125836067 bytes 87549 pkt (dropped 0, overlimits 0 requeues 347) 
backlog 0b 0p requeues 347 

If i am not mistaken by the lartc docs this should put ssh and mysql traffic into prio band 1 and everything else into prio band 3, according to the docs, prio qdisc has 3 bands by default, lower bands should have higher priority

Can anyone confirm or deny this or do you have other thoughts?
I do not want to test this on the production systems before i can be absolutely sure it will work.
I am put off by the statistics, since they do not show a clear seperation of traffic

edit:
i just did some more testing with this configuration, doing a ping on the server, loading up the links, ping goes from 40ms to 170ms.
Doing this:

# tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip protocol 1 0xff flowid 1:1

Ping goes down to 40ms, so this might actually be working already 🙂

edit2:
after some more testing i came to up with the following:

tc qdisc add dev eth0 root handle 1: prio
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 22 0xffff flowid 1:1
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 3306 0xffff flowid 1:1
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip protocol 1 0xff flowid 1:1

for matching "any other traffic" one might use:

tc filter add dev eth0 protocol ip parent 1: prio 2 u32 match ip src 0/0 flowid 1:2

or

tc filter add dev eth0 parent 1: prio 2 protocol all u32 match u32 0 0 flowid 1:2

but i found not specifying a "catch all" filter did work as well, seems like the default prio band is already low.

Best Answer

Just to conclude, here is the simple solution to have priority traffic based on any parameter without thottling bandwidth

tc qdisc add dev eth0 root handle 1: prio 
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 22 0xffff flowid 1:1
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip dport 3306 0xffff flowid 1:1
tc filter add dev eth0 protocol ip parent 1: prio 1 u32 match ip protocol 1 0xff flowid 1:1

Explaination:

  1. create a prio qdisc named 1:
  2. add a filter matching port 22 -> band 1
  3. add another filter matching port 3306 -> band 1
  4. and another filter matching protocol 1 (icmp) -> band 1

You could have "u32 match src " or specify an sport or any protocol