mirror of
https://github.com/livekit/livekit.git
synced 2026-09-01 20:09:08 +00:00
NodeSelector using system load metric (#94)
* use load when selecting nodes * Apply suggestions from code review Co-authored-by: David Zhao <david@davidzhao.com> * sysload selector test * wire nodeSelectorFromConfig * fix tests * Update pkg/routing/selectorsystemload_test.go Co-authored-by: David Zhao <david@davidzhao.com> * dz review: nits Co-authored-by: David Zhao <david@davidzhao.com>
This commit is contained in:
co-authored by
David Zhao
parent
0a9d12bc35
commit
c437152e2b
@@ -0,0 +1,34 @@
|
||||
package routing
|
||||
|
||||
import (
|
||||
livekit "github.com/livekit/livekit-server/proto"
|
||||
"github.com/thoas/go-funk"
|
||||
)
|
||||
|
||||
type SystemLoadSelector struct {
|
||||
SysloadLimit float32
|
||||
}
|
||||
|
||||
func (s *SystemLoadSelector) SelectNode(nodes []*livekit.Node, room *livekit.Room) (*livekit.Node, error) {
|
||||
nodes = GetAvailableNodes(nodes)
|
||||
if len(nodes) == 0 {
|
||||
return nil, ErrNoAvailableNodes
|
||||
}
|
||||
|
||||
nodesLowLoad := []*livekit.Node{}
|
||||
for _, node := range nodes {
|
||||
numCpus := node.Stats.NumCpus
|
||||
if numCpus == 0 {
|
||||
numCpus = 1
|
||||
}
|
||||
if node.Stats.LoadAvgLast1Min/float32(numCpus) < s.SysloadLimit {
|
||||
nodesLowLoad = append(nodesLowLoad, node)
|
||||
}
|
||||
}
|
||||
if len(nodesLowLoad) > 0 {
|
||||
nodes = nodesLowLoad
|
||||
}
|
||||
|
||||
idx := funk.RandomInt(0, len(nodes))
|
||||
return nodes[idx], nil
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
package routing_test
|
||||
|
||||
import (
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/livekit/livekit-server/pkg/routing"
|
||||
livekit "github.com/livekit/livekit-server/proto"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
var (
|
||||
nodeLoadLow = &livekit.Node{
|
||||
Stats: &livekit.NodeStats{
|
||||
UpdatedAt: time.Now().Unix(),
|
||||
NumCpus: 1,
|
||||
LoadAvgLast1Min: 0.0,
|
||||
},
|
||||
}
|
||||
|
||||
nodeLoadHigh = &livekit.Node{
|
||||
Stats: &livekit.NodeStats{
|
||||
UpdatedAt: time.Now().Unix(),
|
||||
NumCpus: 1,
|
||||
LoadAvgLast1Min: 2.0,
|
||||
},
|
||||
}
|
||||
)
|
||||
|
||||
func TestSystemLoadSelector_SelectNode(t *testing.T) {
|
||||
selector := routing.SystemLoadSelector{SysloadLimit: 1.0}
|
||||
|
||||
nodes := []*livekit.Node{}
|
||||
_, err := selector.SelectNode(nodes, nil)
|
||||
require.Error(t, err, "should error no available nodes")
|
||||
|
||||
// Select a node with high load when no nodes with low load are available
|
||||
nodes = []*livekit.Node{nodeLoadHigh}
|
||||
if _, err := selector.SelectNode(nodes, nil); err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
|
||||
// Select a node with low load when available
|
||||
nodes = []*livekit.Node{nodeLoadLow, nodeLoadHigh}
|
||||
for i := 0; i < 5; i++ {
|
||||
node, err := selector.SelectNode(nodes, nil)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
}
|
||||
if node != nodeLoadLow {
|
||||
t.Error("selected the wrong node")
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user