На повърхностно ниво единственото нещо, за което имам въпроси, е подреждането на увеличаване на групата за изчакване и въвеждане на работата:
func (s *Scheduler) Enqueue(req interface{}) {
select {
case s.reqChan <- req:
s.wg.Add(1)
}
}
Не мисля, че горното ще създаде голям проблем на практика с това голямо натоварване, но мисля, че може да е логично условие за състезанието. При по-ниски нива на едновременност и по-малки размери на работа, той може да постави в опашка съобщение, да превключи към горпрограма, която започва работа по това съобщение, СЛЕД работата в групата за изчакване.
След това сигурен ли сте process
методът е безопасен за нишки?? Предполагам, че въз основа на документацията на redis go работи с go run -race
има ли някакъв изход?
В даден момент е напълно разумно и се очаква производителността да спадне. Бих препоръчал да започнете тестове за производителност, за да видите къде започват да намаляват забавянето и пропускателната способност:
може би група от 10, 100, 500, 1000, 2500, 5000, 10000 или каквото има смисъл. IMO изглежда, че има 3 важни променливи за настройка:
- Размер на работническата група
- Размер на буфера на работната опашка
- Redis
MaxActive
Най-голямото нещо, което изскача, е, че изглежда като redis.Pool е конфигуриран да позволява неограничен брой връзки:
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)
},
}
// Максимален брой връзки, разпределени от пула в даден момент.// Когато е нула, няма ограничение за броя на връзките в пула.MaxActive int
Аз лично бих се опитал да разбера къде и кога производителността започва да намалява по отношение на размера на вашия пул от работници. Това може да улесни разбирането от какво е ограничена вашата програма.