Skip to content

Commit 57f363d

Browse files
committed
feat(scheduler): use sharded keymutex in peer manager
- Replace single `sync.Mutex` with `keymutex.KeyMutex` (256 shards) - Lock/unlock per peer ID instead of globally, reducing contention - Add `k8s.io/utils` dependency for `keymutex` package Signed-off-by: Gaius <gaius.qi@gmail.com>
1 parent 5b723a4 commit 57f363d

3 files changed

Lines changed: 17 additions & 9 deletions

File tree

go.mod

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ require (
7979
gorm.io/driver/postgres v1.4.8
8080
gorm.io/gorm v1.25.0
8181
gorm.io/plugin/soft_delete v1.2.1
82+
k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3
8283
moul.io/zapgorm2 v1.3.0
8384
stathat.com/c/consistent v1.0.0
8485
)

go.sum

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,6 +1379,8 @@ honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWh
13791379
honnef.co/go/tools v0.0.1-2019.2.3/go.mod h1:a3bituU0lyd329TUQxRnasdCoJDkEUEAqEt0JzvZhAg=
13801380
honnef.co/go/tools v0.0.1-2020.1.3/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
13811381
honnef.co/go/tools v0.0.1-2020.1.4/go.mod h1:X/FiERA/W4tHapMX5mGpAtMSVEeEUOyHaw9vFzvIQ3k=
1382+
k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3 h1:jVkFFVfXdXP74B/zbO3hM3hpSFD0xvhQ5U686DPurkE=
1383+
k8s.io/utils v0.0.0-20260707023825-cf1189d6abe3/go.mod h1:M2s5JB1lIYP3jzZdorPLHXIPJzt9vv2muW5a6L9DtNM=
13821384
moul.io/zapgorm2 v1.3.0 h1:+CzUTMIcnafd0d/BvBce8T4uPn6DQnpIrz64cyixlkk=
13831385
moul.io/zapgorm2 v1.3.0/go.mod h1:nPVy6U9goFKHR4s+zfSo1xVFaoU7Qgd5DoCdOfzoCqs=
13841386
rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8=

scheduler/resource/standard/peer_manager.go

Lines changed: 14 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,8 @@ import (
2323
"sync"
2424
"time"
2525

26+
"k8s.io/utils/keymutex"
27+
2628
pkggc "d7y.io/dragonfly/v2/pkg/gc"
2729
"d7y.io/dragonfly/v2/scheduler/config"
2830
)
@@ -32,6 +34,9 @@ const (
3234
GCPeerID = "peer"
3335
)
3436

37+
// peerMutexShardCount is the number of mutex shards for peer mutations.
38+
const peerMutexShardCount = 256
39+
3540
// PeerManager is the interface used for peer manager.
3641
type PeerManager interface {
3742
// Load returns peer for a key.
@@ -73,8 +78,8 @@ type peerManager struct {
7378
// pieceDownloadTimeout is timeout of downloading piece.
7479
pieceDownloadTimeout time.Duration
7580

76-
// mu is peer mutex.
77-
mu *sync.Mutex
81+
// mu is a mutex for peer mutations.
82+
mu keymutex.KeyMutex
7883
}
7984

8085
// New peer manager interface.
@@ -84,7 +89,7 @@ func newPeerManager(cfg *config.GCConfig, gc pkggc.GC) (PeerManager, error) {
8489
peerTTL: cfg.PeerTTL,
8590
hostTTL: cfg.HostTTL,
8691
pieceDownloadTimeout: cfg.PieceDownloadTimeout,
87-
mu: &sync.Mutex{},
92+
mu: keymutex.NewHashed(peerMutexShardCount),
8893
}
8994

9095
if err := gc.Add(pkggc.Task{
@@ -111,8 +116,8 @@ func (p *peerManager) Load(key string) (*Peer, bool) {
111116

112117
// Store sets peer.
113118
func (p *peerManager) Store(peer *Peer) {
114-
p.mu.Lock()
115-
defer p.mu.Unlock()
119+
p.mu.LockKey(peer.ID)
120+
defer p.mu.UnlockKey(peer.ID) // nolint: errcheck
116121

117122
p.Map.Store(peer.ID, peer)
118123
peer.Task.StorePeer(peer)
@@ -123,8 +128,8 @@ func (p *peerManager) Store(peer *Peer) {
123128
// Otherwise, it stores and returns the given peer.
124129
// The loaded result is true if the peer was loaded, false if stored.
125130
func (p *peerManager) LoadOrStore(peer *Peer) (*Peer, bool) {
126-
p.mu.Lock()
127-
defer p.mu.Unlock()
131+
p.mu.LockKey(peer.ID)
132+
defer p.mu.UnlockKey(peer.ID) // nolint: errcheck
128133

129134
rawPeer, loaded := p.Map.LoadOrStore(peer.ID, peer)
130135
if !loaded {
@@ -137,8 +142,8 @@ func (p *peerManager) LoadOrStore(peer *Peer) (*Peer, bool) {
137142

138143
// Delete deletes peer for a key.
139144
func (p *peerManager) Delete(key string) {
140-
p.mu.Lock()
141-
defer p.mu.Unlock()
145+
p.mu.LockKey(key)
146+
defer p.mu.UnlockKey(key) // nolint: errcheck
142147

143148
if peer, loaded := p.Load(key); loaded {
144149
p.Map.Delete(key)

0 commit comments

Comments
 (0)