From 73dee0bec478245a41d007637cc08d1c1e50d0c6 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Tue, 2 May 2017 17:18:10 -0700 Subject: [PATCH 1/2] mvcc: cache consistentIndex Called on every entry apply and boltdb requests aren't free. --- mvcc/kvstore.go | 18 +++++++++++++++--- 1 file changed, 15 insertions(+), 3 deletions(-) diff --git a/mvcc/kvstore.go b/mvcc/kvstore.go index e5260638c..27908db40 100644 --- a/mvcc/kvstore.go +++ b/mvcc/kvstore.go @@ -19,6 +19,7 @@ import ( "errors" "math" "sync" + "sync/atomic" "time" "github.com/coreos/etcd/lease" @@ -67,6 +68,10 @@ type store struct { ReadView WriteView + // consistentIndex caches the "consistent_index" key's value. Accessed + // through atomics so must be 64-bit aligned. + consistentIndex uint64 + // mu read locks for txns and write locks for non-txn store changes. mu sync.RWMutex @@ -234,6 +239,7 @@ func (s *store) Restore(b backend.Backend) error { close(s.stopc) s.fifoSched.Stop() + atomic.StoreUint64(&s.consistentIndex, 0) s.b = b s.kvindex = newTreeIndex() s.currentRev = 1 @@ -380,14 +386,18 @@ func (s *store) saveIndex(tx backend.BatchTx) { return } bs := s.bytesBuf8 - binary.BigEndian.PutUint64(bs, s.ig.ConsistentIndex()) + ci := s.ig.ConsistentIndex() + binary.BigEndian.PutUint64(bs, ci) // put the index into the underlying backend // tx has been locked in TxnBegin, so there is no need to lock it again tx.UnsafePut(metaBucketName, consistentIndexKeyName, bs) + atomic.StoreUint64(&s.consistentIndex, ci) } func (s *store) ConsistentIndex() uint64 { - // TODO: cache index in a uint64 field? + if ci := atomic.LoadUint64(&s.consistentIndex); ci > 0 { + return ci + } tx := s.b.BatchTx() tx.Lock() defer tx.Unlock() @@ -395,7 +405,9 @@ func (s *store) ConsistentIndex() uint64 { if len(vs) == 0 { return 0 } - return binary.BigEndian.Uint64(vs[0]) + v := binary.BigEndian.Uint64(vs[0]) + atomic.StoreUint64(&s.consistentIndex, v) + return v } // appendMarkTombstone appends tombstone mark to normal revision bytes. From ac4855e91182017aa288299835fcf4f642008522 Mon Sep 17 00:00:00 2001 From: Anthony Romano Date: Tue, 2 May 2017 17:20:51 -0700 Subject: [PATCH 2/2] mvcc: benchmark ConsistentIndex --- mvcc/kvstore_bench_test.go | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/mvcc/kvstore_bench_test.go b/mvcc/kvstore_bench_test.go index 33fdc17fc..547a5d91e 100644 --- a/mvcc/kvstore_bench_test.go +++ b/mvcc/kvstore_bench_test.go @@ -45,6 +45,24 @@ func BenchmarkStorePut(b *testing.B) { } } +func BenchmarkConsistentIndex(b *testing.B) { + fci := fakeConsistentIndex(10) + be, tmpPath := backend.NewDefaultTmpBackend() + s := NewStore(be, &lease.FakeLessor{}, &fci) + defer cleanup(s, be, tmpPath) + + tx := s.b.BatchTx() + tx.Lock() + s.saveIndex(tx) + tx.Unlock() + + b.ReportAllocs() + b.ResetTimer() + for i := 0; i < b.N; i++ { + s.ConsistentIndex() + } +} + // BenchmarkStoreTxnPutUpdate is same as above, but instead updates single key func BenchmarkStorePutUpdate(b *testing.B) { var i fakeConsistentIndex