feat: advance queue scanner periodically instead of every remote write (#22981)

pull/22990/head
William Baker 2021-12-13 10:09:36 -06:00 committed by GitHub
parent e3ff434f81
commit a7a5233432
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 29 additions and 8 deletions

View File

@ -7,6 +7,7 @@ import (
"os"
"path/filepath"
"sync"
"time"
"github.com/influxdata/influxdb/v2/kit/platform"
"github.com/influxdata/influxdb/v2/pkg/durablequeue"
@ -15,6 +16,10 @@ import (
"go.uber.org/zap"
)
const (
scannerAdvanceInterval = 10 * time.Second
)
type remoteWriter interface {
Write([]byte) error
}
@ -157,6 +162,20 @@ func (rq *replicationQueue) SendWrite() bool {
return false
}
advanceScanner := func() error {
if _, err = scan.Advance(); err != nil {
if err != io.EOF {
rq.logger.Error("Error in replication queue scanner", zap.Error(err))
}
return err
}
rq.metrics.Dequeue(rq.id, rq.queue.TotalBytes())
return nil
}
ticker := time.NewTicker(scannerAdvanceInterval)
defer ticker.Stop()
for scan.Next() {
if err := scan.Err(); err != nil {
if errors.Is(err, io.EOF) {
@ -174,18 +193,20 @@ func (rq *replicationQueue) SendWrite() bool {
return false
}
// TODO: As a potential future optimization, Advance() could be called only if a certain amount of time has passed
// since an Advance(), a certain amount of data has been transferred, a certain number of writes, etc. to avoid an
// fsync after every remote write.
if _, err = scan.Advance(); err != nil {
if err != io.EOF {
rq.logger.Error("Error in replication queue scanner", zap.Error(err))
// Advance the scanner periodically to prevent extended runs of local writes without updating the underlying queue
// position.
select {
case <-ticker.C:
if err := advanceScanner(); err != nil {
return false
}
return false
default:
}
rq.metrics.Dequeue(rq.id, rq.queue.TotalBytes())
}
if err := advanceScanner(); err != nil {
return false
}
return true
}