Na povrchové úrovni jediná věc, ke které mám dotazy, je objednání narůstající čekací skupiny a zprovoznění práce:
func (s *Scheduler) Enqueue(req interface{}) {
select {
case s.reqChan <- req:
s.wg.Add(1)
}
}
Nemyslím si, že výše uvedené způsobí v praxi velké problémy s tak velkým pracovním zatížením, ale myslím si, že to může být logický závod. Při nižších úrovních souběžnosti a menších pracovních velikostech může zařadit zprávu do fronty, přepnout se na gorutinu, která zahájí práci na této zprávě, POTOM práci ve skupině čekání.
Dále jste si jisti process
metoda je bezpečná proti vláknům? Předpokládám, že na základě dokumentace redis go běží s go run -race
máte nějaký výstup?
V určitém okamžiku je to zcela rozumné a očekává se, že výkon klesne. Doporučil bych spustit testy výkonu, abyste zjistili, kde začíná klesat latence a propustnost:
možná fond 10, 100, 500, 1 000, 2 500, 5 000, 10 000 nebo cokoli, co dává smysl. IMO to vypadá, že je potřeba vyladit 3 důležité proměnné:
- Velikost fondu pracovníků
- Velikost vyrovnávací paměti pracovní fronty
- Redis
MaxActive
Největší věc, která vyskočí, je, že to vypadá jako redis.Pool je nakonfigurován tak, aby umožňoval neomezený počet připojení:
pool := &redis.Pool{
MaxIdle: 50,
IdleTimeout: 240 * time.Second,
TestOnBorrow: func(c redis.Conn, t time.Time) error {
_, err := c.Do("PING")
return err
},
Dial: func() (redis.Conn, error) {
return dial("tcp", address, password)
},
}
// Maximální počet připojení přidělených fondem v daný čas.// Když je nula, počet spojení ve fondu není omezen.MaxActive int
Osobně bych se pokusil pochopit, kde a kdy výkon začíná klesat s ohledem na velikost vašeho fondu pracovníků. To může usnadnit pochopení toho, čím je váš program omezen.