表面レベルで私が質問しているのは、待機グループの増分と作業の照会の順序だけです。
func (s *Scheduler) Enqueue(req interface{}) {
select {
case s.reqChan <- req:
s.wg.Add(1)
}
}
上記のような大きなワークロードでは、実際にはそれほど問題になるとは思いませんが、論理的な競合状態である可能性があります。同時実行性のレベルが低く、作業サイズが小さい場合、メッセージをキューに入れ、そのメッセージの作業を開始するゴルーチンにconextスイッチを切り替えてから、待機グループで作業する場合があります。
次は、process
ですか? メソッドはスレッドセーフですか? redis goのドキュメントに基づいて、go run -race
で実行していると思います。 出力はありますか?
ある時点で、パフォーマンスが低下することは完全に合理的であり、期待されています。パフォーマンステストを開始して、レイテンシとスループットが低下し始める場所を確認することをお勧めします。
多分10、100、500、1000、2500、5000、10000、または意味のあるもののプール。 IMO調整する重要な変数が3つあるようです:
- ワーカープールのサイズ
- ワークキューのバッファサイズ
- Redis
MaxActive
飛び出す最大のことは、redisのように見えることです。プールは無制限の接続数を許可するように構成されています:
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)
},
}
//特定の時間にプールによって割り当てられる接続の最大数//ゼロの場合、プール内の接続数に制限はありません。MaxActiveint
私は個人的に、あなたの労働者プールのサイズに関して、パフォーマンスがどこでいつ低下し始めるかを理解しようとします。これにより、プログラムが何によって制約されているかを理解しやすくなる可能性があります。