ContentSquare / chproxy

Open-Source ClickHouse http proxy and load balancer
https://www.chproxy.org/
MIT License
1.28k stars 259 forks source link

[Feature] Weighted round robin load balancing #441

Open azhard4int opened 4 months ago

azhard4int commented 4 months ago

We are using CHProxy in Usermaven and looking for a weighted round robin load balancing strategy. We want to route high paying customers traffic to the beefy servers.

Describe the solution you'd like A clear and concise description of what you want to happen.

We would like to implement this feature, a variable with weighted for the servers configuration. We'll implement the weighted round robin load balancing implementation:

Something like this:

func weightedRoundRobin(servers []*Server) *Server {
    var totalWeight int
    var bestServer *Server

    for i := range servers {
        servers[i].mu.Lock()
        if !servers[i].IsHealthy {
            servers[i].mu.Unlock()
            continue
        }
        servers[i].CurrentWeight += servers[i].Weight
        totalWeight += servers[i].Weight

        if bestServer == nil || servers[i].CurrentWeight > bestServer.CurrentWeight {
            bestServer = servers[i]
        }
        servers[i].mu.Unlock()
    }

    if bestServer != nil {
        bestServer.mu.Lock()
        bestServer.CurrentWeight -= totalWeight
        bestServer.mu.Unlock()
    }

    return bestServer
}
mga-chka commented 4 months ago

FYI, we had issues in the past with the load balancing logic.

But, feel free to provide a PR. As long as the weightedRoundRobin is only unsable with a specific flag/option in the conf, it souldn't be an issue. If you need to change the current load balancing business code, the review of the PR might take a while and could be refused (since this part is subtle, and we don't want to break it again).