-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Don't block appends when segments are highly contented
Under higher write load, the segment write lock can cause long delays for a goroutine to acquire it for a write and append operation. This causes ingestor to report "slow request" at times because multiple locks are getting blocked for while and the request goes slower. For collector shipping segments, it generally has many segements on disk that it needs to send. So instead of blocking when a segment is locked, we now just return a locked error and let collector move to the next segment. It will retry the prior segment again in a few seconds. This allows for better and reduces the slow requests warnings quite a bit.
- Loading branch information
Showing
12 changed files
with
116 additions
and
18 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
//go:build !linux | ||
|
||
package main | ||
|
||
func pinToCPU(cpu int) error {} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
package main | ||
|
||
import ( | ||
"golang.org/x/sys/unix" | ||
) | ||
|
||
func pinToCPU(cpu int) error { | ||
var newMask unix.CPUSet | ||
newMask.Set(cpu) | ||
return unix.SchedSetaffinity(cpu, &newMask) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
package sync | ||
|
||
import ( | ||
"sync" | ||
"sync/atomic" | ||
) | ||
|
||
// CountingRWMutex is a RWMutex that keeps track of the number of goroutines waiting for the lock. | ||
type CountingRWMutex struct { | ||
mu sync.RWMutex | ||
waiting int64 | ||
limit int64 | ||
} | ||
|
||
func NewCountingRWMutex(limit int) *CountingRWMutex { | ||
return &CountingRWMutex{limit: int64(limit)} | ||
} | ||
|
||
// RLock locks rw for reading. | ||
func (rw *CountingRWMutex) RLock() { | ||
atomic.AddInt64(&rw.waiting, 1) | ||
rw.mu.RLock() | ||
} | ||
|
||
// RUnlock undoes a single RLock call; it does not affect other simultaneous readers. | ||
func (rw *CountingRWMutex) RUnlock() { | ||
atomic.AddInt64(&rw.waiting, -1) | ||
rw.mu.RUnlock() | ||
} | ||
|
||
// Lock locks rw for writing. | ||
func (rw *CountingRWMutex) Lock() { | ||
atomic.AddInt64(&rw.waiting, 1) | ||
rw.mu.Lock() | ||
} | ||
|
||
// Unlock undoes a single Lock call; it does not affect other simultaneous readers. | ||
func (rw *CountingRWMutex) Unlock() { | ||
atomic.AddInt64(&rw.waiting, -1) | ||
rw.mu.Unlock() | ||
} | ||
|
||
// TryLock tries to lock rw for writing if the pending waitinger is less than the limit. | ||
func (rw *CountingRWMutex) TryLock() bool { | ||
if atomic.LoadInt64(&rw.waiting) > rw.limit { | ||
return false | ||
} | ||
return rw.mu.TryLock() | ||
} | ||
|
||
// Waiters returns the number of goroutines waiting for the lock. | ||
func (rw *CountingRWMutex) Waiters() int64 { | ||
return atomic.LoadInt64(&rw.waiting) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters