Oppervlakkig gezien is het enige waar ik vragen over heb het bestellen van een toenemende wachtgroep en het onderbreken van het werk:
func (s *Scheduler) Enqueue(req interface{}) {
select {
case s.reqChan <- req:
s.wg.Add(1)
}
}
Ik denk niet dat het bovenstaande in de praktijk veel problemen zal opleveren met deze grote werklast, maar ik denk dat het een logische race-conditie kan zijn. Bij lagere niveaus van gelijktijdigheid en kleinere werkomvang kan het een bericht in de wachtrij plaatsen, aansluitend overschakelen naar een goroutine die aan dat bericht begint te werken, DAARNA het werk in de wachtgroep.
Vervolgens weet je het zeker process
methode is threadsafe?? Ik neem aan dat op basis van de redis go-documentatie, wordt uitgevoerd met go run -race
heb je output?
Op een gegeven moment is het volkomen redelijk en wordt verwacht dat de prestaties afnemen. Ik raad aan om prestatietests te starten om te zien waar latentie en doorvoer beginnen af te nemen:
misschien een pool van 10, 100, 500, 1000, 2500, 5000, 10000 of wat dan ook logisch is. IMO het lijkt erop dat er 3 belangrijke variabelen zijn om af te stemmen:
- Grootte werknemerspool
- Buffergrootte werkwachtrij
- Redis
MaxActive
Het grootste dat eruit springt, is dat het eruitziet als redis.Pool is geconfigureerd om een onbeperkt aantal verbindingen toe te staan:
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)
},
}
// Maximaal aantal verbindingen toegewezen door de pool op een bepaald moment.// Wanneer nul, is er geen limiet op het aantal verbindingen in de pool.MaxActive int
Ik zou persoonlijk proberen te begrijpen waar en wanneer de prestaties beginnen af te nemen met betrekking tot de grootte van uw werknemerspool. Dit maakt het misschien gemakkelijker om te begrijpen waardoor uw programma wordt beperkt.