mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
raft: node bench matches reality
This commit is contained in:
parent
9a33678878
commit
3f867bc6ed
@ -16,6 +16,7 @@ package raft
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"testing"
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
|
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
|
||||||
)
|
)
|
||||||
@ -32,14 +33,20 @@ func BenchmarkOneNode(b *testing.B) {
|
|||||||
defer n.Stop()
|
defer n.Stop()
|
||||||
|
|
||||||
n.Campaign(ctx)
|
n.Campaign(ctx)
|
||||||
|
go func() {
|
||||||
for i := 0; i < b.N; i++ {
|
for i := 0; i < b.N; i++ {
|
||||||
rd := <-n.Ready()
|
|
||||||
s.Append(rd.Entries)
|
|
||||||
n.Advance()
|
|
||||||
n.Propose(ctx, []byte("foo"))
|
n.Propose(ctx, []byte("foo"))
|
||||||
}
|
}
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
rd := <-n.Ready()
|
rd := <-n.Ready()
|
||||||
if rd.HardState.Commit != uint64(b.N+1) {
|
s.Append(rd.Entries)
|
||||||
b.Errorf("commit = %d, want %d", rd.HardState.Commit, b.N+1)
|
// a reasonable disk sync latency
|
||||||
|
time.Sleep(1 * time.Millisecond)
|
||||||
|
n.Advance()
|
||||||
|
if rd.HardState.Commit == uint64(b.N+1) {
|
||||||
|
return
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,7 +23,15 @@ type node struct {
|
|||||||
|
|
||||||
func startNode(id uint64, peers []raft.Peer, iface iface) *node {
|
func startNode(id uint64, peers []raft.Peer, iface iface) *node {
|
||||||
st := raft.NewMemoryStorage()
|
st := raft.NewMemoryStorage()
|
||||||
rn := raft.StartNode(id, peers, 10, 1, st)
|
c := &raft.Config{
|
||||||
|
ID: id,
|
||||||
|
ElectionTick: 10,
|
||||||
|
HeartbeatTick: 1,
|
||||||
|
Storage: st,
|
||||||
|
MaxSizePerMsg: 1024 * 1024,
|
||||||
|
MaxInflightMsgs: 256,
|
||||||
|
}
|
||||||
|
rn := raft.StartNode(c, peers)
|
||||||
n := &node{
|
n := &node{
|
||||||
Node: rn,
|
Node: rn,
|
||||||
id: id,
|
id: id,
|
||||||
@ -50,6 +58,7 @@ func (n *node) start() {
|
|||||||
n.storage.SetHardState(n.state)
|
n.storage.SetHardState(n.state)
|
||||||
}
|
}
|
||||||
n.storage.Append(rd.Entries)
|
n.storage.Append(rd.Entries)
|
||||||
|
time.Sleep(time.Millisecond)
|
||||||
// TODO: make send async, more like real world...
|
// TODO: make send async, more like real world...
|
||||||
for _, m := range rd.Messages {
|
for _, m := range rd.Messages {
|
||||||
n.iface.send(m)
|
n.iface.send(m)
|
||||||
@ -96,7 +105,15 @@ func (n *node) stop() {
|
|||||||
func (n *node) restart() {
|
func (n *node) restart() {
|
||||||
// wait for the shutdown
|
// wait for the shutdown
|
||||||
<-n.stopc
|
<-n.stopc
|
||||||
n.Node = raft.RestartNode(n.id, 10, 1, n.storage, 0)
|
c := &raft.Config{
|
||||||
|
ID: n.id,
|
||||||
|
ElectionTick: 10,
|
||||||
|
HeartbeatTick: 1,
|
||||||
|
Storage: n.storage,
|
||||||
|
MaxSizePerMsg: 1024 * 1024,
|
||||||
|
MaxInflightMsgs: 256,
|
||||||
|
}
|
||||||
|
n.Node = raft.RestartNode(c)
|
||||||
n.start()
|
n.start()
|
||||||
n.iface.connect()
|
n.iface.connect()
|
||||||
}
|
}
|
||||||
|
39
raft/rafttest/node_bench_test.go
Normal file
39
raft/rafttest/node_bench_test.go
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
package rafttest
|
||||||
|
|
||||||
|
import (
|
||||||
|
"testing"
|
||||||
|
"time"
|
||||||
|
|
||||||
|
"github.com/coreos/etcd/Godeps/_workspace/src/golang.org/x/net/context"
|
||||||
|
"github.com/coreos/etcd/raft"
|
||||||
|
)
|
||||||
|
|
||||||
|
func BenchmarkProposal3Nodes(b *testing.B) {
|
||||||
|
peers := []raft.Peer{{1, nil}, {2, nil}, {3, nil}}
|
||||||
|
nt := newRaftNetwork(1, 2, 3)
|
||||||
|
|
||||||
|
nodes := make([]*node, 0)
|
||||||
|
|
||||||
|
for i := 1; i <= 3; i++ {
|
||||||
|
n := startNode(uint64(i), peers, nt.nodeNetwork(uint64(i)))
|
||||||
|
nodes = append(nodes, n)
|
||||||
|
}
|
||||||
|
// get ready and warm up
|
||||||
|
time.Sleep(50 * time.Millisecond)
|
||||||
|
|
||||||
|
b.ResetTimer()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
nodes[0].Propose(context.TODO(), []byte("somedata"))
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, n := range nodes {
|
||||||
|
if n.state.Commit != uint64(b.N+4) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
}
|
||||||
|
b.StopTimer()
|
||||||
|
|
||||||
|
for _, n := range nodes {
|
||||||
|
n.stop()
|
||||||
|
}
|
||||||
|
}
|
@ -19,16 +19,17 @@ func TestBasicProgress(t *testing.T) {
|
|||||||
nodes = append(nodes, n)
|
nodes = append(nodes, n)
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(50 * time.Millisecond)
|
time.Sleep(10 * time.Millisecond)
|
||||||
for i := 0; i < 1000; i++ {
|
|
||||||
|
for i := 0; i < 10000; i++ {
|
||||||
nodes[0].Propose(context.TODO(), []byte("somedata"))
|
nodes[0].Propose(context.TODO(), []byte("somedata"))
|
||||||
}
|
}
|
||||||
|
|
||||||
time.Sleep(100 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
n.stop()
|
n.stop()
|
||||||
if n.state.Commit != 1006 {
|
if n.state.Commit != 10006 {
|
||||||
t.Errorf("commit = %d, want = 1006", n.state.Commit)
|
t.Errorf("commit = %d, want = 10006", n.state.Commit)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -63,7 +64,7 @@ func TestRestart(t *testing.T) {
|
|||||||
nodes[1].restart()
|
nodes[1].restart()
|
||||||
|
|
||||||
// give some time for nodes to catch up with the raft leader
|
// give some time for nodes to catch up with the raft leader
|
||||||
time.Sleep(300 * time.Millisecond)
|
time.Sleep(500 * time.Millisecond)
|
||||||
for _, n := range nodes {
|
for _, n := range nodes {
|
||||||
n.stop()
|
n.stop()
|
||||||
if n.state.Commit != 1206 {
|
if n.state.Commit != 1206 {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user