You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Redis input plugin used pool.ConnPool for communication when gathering and use the default connections configs: IdleTimeout=5m, IdleCheckFrequency=1m. And redis client(go-redis v6.15.9) will create a goroutine for checking connections in pool if idle time greater than IdleTimeout with IdleCheckFrequency frequency.
## internal/pool/pool.go
func NewConnPool(opt *Options) *ConnPool {
p := &ConnPool{
opt: opt,
queue: make(chan struct{}, opt.PoolSize),
conns: make([]*Conn, 0, opt.PoolSize),
idleConns: make([]*Conn, 0, opt.PoolSize),
}
for i := 0; i < opt.MinIdleConns; i++ {
p.checkMinIdleConns()
}
###### create a goroutine to check connections in pool if that has expired.
if opt.IdleTimeout > 0 && opt.IdleCheckFrequency > 0 {
go p.reaper(opt.IdleCheckFrequency)
}
return p
}
Telegraf transmit the cancelCtx to control the "gatherLoop" method of all input plugins. When config file was changed, telegraf will call the cancelCtx to cancel all the gather loop of input plugins and renew a agent instance. And new redis plugins instances also been recreated(new pool.ConnPool). But redis connection pool of previous redis input plugin instance had not been closed; the goroutines for checking if connections in pool has expired still alive. So leading to massive goroutine leak when config file changed frequently.
func (a *Agent) runInputs(...) {
... ...
acc := NewAccumulator(input, unit.dst)
acc.SetPrecision(getPrecision(precision, interval))
wg.Add(1)
go func(input *models.RunningInput) {
defer wg.Done()
####### transmit ctx for control
a.gatherLoop(ctx, acc, input, ticker, interval)
}(input)
... ...
}
// gather runs an input's gather function periodically until the context is
// done.
func (a *Agent) gatherLoop(
ctx context.Context,
acc telegraf.Accumulator,
input *models.RunningInput,
ticker Ticker,
interval time.Duration,
) {
defer panicRecover(input)
for {
select {
case <-ticker.Elapsed():
err := a.gatherOnce(acc, input, ticker, interval)
if err != nil {
acc.AddError(err)
}
case <-ctx.Done(): ####### here will get the notify through cancelCtx when cancel func has been called
return
}
}
}
Redis input plugin used pool.ConnPool for communication when gathering and use the default connections configs: IdleTimeout=5m, IdleCheckFrequency=1m. And redis client(go-redis v6.15.9) will create a goroutine for checking connections in pool if idle time greater than IdleTimeout with IdleCheckFrequency frequency.
Telegraf transmit the cancelCtx to control the "gatherLoop" method of all input plugins. When config file was changed, telegraf will call the cancelCtx to cancel all the gather loop of input plugins and renew a agent instance. And new redis plugins instances also been recreated(new pool.ConnPool). But redis connection pool of previous redis input plugin instance had not been closed; the goroutines for checking if connections in pool has expired still alive. So leading to massive goroutine leak when config file changed frequently.
pprof Peek
#11143
The text was updated successfully, but these errors were encountered: