mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
raft: use a singleton global rand
rand.NewSource creates a 4872 byte object. With a small number of raft groups in a process this isn't a problem. With 10k raft groups we'd use 46MB for these random sources. The only usage is in raft.resetRandomizedElectionTimeout which isn't performance critical. Fixes #6347.
This commit is contained in:
parent
1ebeef5cbf
commit
4a33aa3917
25
raft/raft.go
25
raft/raft.go
@ -22,6 +22,8 @@ import (
|
||||
"math/rand"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
pb "github.com/coreos/etcd/raft/raftpb"
|
||||
)
|
||||
@ -45,6 +47,25 @@ const (
|
||||
campaignTransfer CampaignType = "CampaignTransfer"
|
||||
)
|
||||
|
||||
// lockedRand is a small wrapper around rand.Rand to provide
|
||||
// synchronization. Only the methods needed by the code are exposed
|
||||
// (e.g. Intn).
|
||||
type lockedRand struct {
|
||||
mu sync.Mutex
|
||||
rand *rand.Rand
|
||||
}
|
||||
|
||||
func (r *lockedRand) Intn(n int) int {
|
||||
r.mu.Lock()
|
||||
v := r.rand.Intn(n)
|
||||
r.mu.Unlock()
|
||||
return v
|
||||
}
|
||||
|
||||
var globalRand = &lockedRand{
|
||||
rand: rand.New(rand.NewSource(time.Now().UnixNano())),
|
||||
}
|
||||
|
||||
// CampaignType represents the type of campaigning
|
||||
// the reason we use the type of string instead of uint64
|
||||
// is because it's simpler to compare and fill in raft entries
|
||||
@ -205,7 +226,6 @@ type raft struct {
|
||||
// when raft changes its state to follower or candidate.
|
||||
randomizedElectionTimeout int
|
||||
|
||||
rand *rand.Rand
|
||||
tick func()
|
||||
step stepFunc
|
||||
|
||||
@ -244,7 +264,6 @@ func newRaft(c *Config) *raft {
|
||||
logger: c.Logger,
|
||||
checkQuorum: c.CheckQuorum,
|
||||
}
|
||||
r.rand = rand.New(rand.NewSource(int64(c.ID)))
|
||||
for _, p := range peers {
|
||||
r.prs[p] = &Progress{Next: 1, ins: newInflights(r.maxInflight)}
|
||||
}
|
||||
@ -1024,7 +1043,7 @@ func (r *raft) pastElectionTimeout() bool {
|
||||
}
|
||||
|
||||
func (r *raft) resetRandomizedElectionTimeout() {
|
||||
r.randomizedElectionTimeout = r.electionTimeout + r.rand.Intn(r.electionTimeout)
|
||||
r.randomizedElectionTimeout = r.electionTimeout + globalRand.Intn(r.electionTimeout)
|
||||
}
|
||||
|
||||
// checkQuorumActive returns true if the quorum is active from
|
||||
|
Loading…
x
Reference in New Issue
Block a user