diff --git a/store/README.md b/store/README.md index d388fa6046d23c03cc5eb2ab4dc941c0ebed15a8..0f318eba3d86dd916ea4ea06adb4f392a77e0429 100644 --- a/store/README.md +++ b/store/README.md @@ -33,3 +33,54 @@ BenchmarkSet_valsize1000-6 50 28066678 ns/op BenchmarkSet_valsize10000-6 50 28736228 ns/op ok github.com/dgraph-io/dgraph/store 48.393s ``` + +Also based on dgraph-io/experiments/db: + +## BoltDB + +Without copying the resulting byte slice from Bolt. **Unsafe** +``` +$ go test -bench BenchmarkRead . +testing: warning: no tests to run +PASS +BenchmarkReadBolt_1024 500000 3858 ns/op +BenchmarkReadBolt_10KB 500000 3738 ns/op +BenchmarkReadBolt_500KB 1000000 3141 ns/op +BenchmarkReadBolt_1MB 1000000 3026 ns/op +ok github.com/dgraph-io/experiments/db 102.513s +``` + +Copying the resulting byte slice. **Safe** +``` +$ go test -bench BenchmarkRead . +testing: warning: no tests to run +PASS +BenchmarkReadBolt_1024 200000 6760 ns/op +BenchmarkReadBolt_10KB 100000 21249 ns/op +BenchmarkReadBolt_500KB 10000 214449 ns/op +BenchmarkReadBolt_1MB 3000 350712 ns/op +ok github.com/dgraph-io/experiments/db 80.890s +``` + +## RocksDB + +``` +$ go test -bench BenchmarkGet . +PASS +BenchmarkGet_valsize1024 300000 5715 ns/op +BenchmarkGet_valsize10KB 50000 27619 ns/op +BenchmarkGet_valsize500KB 2000 604185 ns/op +BenchmarkGet_valsize1MB 2000 1064685 ns/op +ok github.com/dgraph-io/dgraph/store 55.029s +``` + +### Thoughts +DGraph uses append only commit log to sync new mutations to disk before returning. +Every time a posting list gets init, it checks for both the stored posting list and +the mutations committed after the posting list was written. Hence, our access pattern +from store is largely read-only, with fewer writes. This is true, irrespective of how +many writes get commited by the end user. + +Hence, BoltDB is a better choice. It performs better for reads/seeks, despite DGraph needing +a value copy. Writes are somewhat slower, but that shouldn't be a problem because of the +above mentioned reasons. diff --git a/store/store_test.go b/store/store_test.go index 0f98232398240eb9aa01aacacb7767c903fc0d57..b4261c7260157e10bfd4edb83fa4a89594f88dc9 100644 --- a/store/store_test.go +++ b/store/store_test.go @@ -82,7 +82,6 @@ func benchmarkGet(valSize int, b *testing.B) { return } } - b.Logf("Wrote %d keys.", nkeys) b.ResetTimer() for i := 0; i < b.N; i++ { @@ -98,9 +97,10 @@ func benchmarkGet(valSize int, b *testing.B) { } } -func BenchmarkGet_valsize100(b *testing.B) { benchmarkGet(100, b) } -func BenchmarkGet_valsize1000(b *testing.B) { benchmarkGet(1000, b) } -func BenchmarkGet_valsize10000(b *testing.B) { benchmarkGet(10000, b) } +func BenchmarkGet_valsize1024(b *testing.B) { benchmarkGet(1024, b) } +func BenchmarkGet_valsize10KB(b *testing.B) { benchmarkGet(10240, b) } +func BenchmarkGet_valsize500KB(b *testing.B) { benchmarkGet(1<<19, b) } +func BenchmarkGet_valsize1MB(b *testing.B) { benchmarkGet(1<<20, b) } func benchmarkSet(valSize int, b *testing.B) { path, err := ioutil.TempDir("", "storetest_") @@ -125,6 +125,7 @@ func benchmarkSet(valSize int, b *testing.B) { } } -func BenchmarkSet_valsize100(b *testing.B) { benchmarkSet(100, b) } -func BenchmarkSet_valsize1000(b *testing.B) { benchmarkSet(1000, b) } -func BenchmarkSet_valsize10000(b *testing.B) { benchmarkSet(10000, b) } +func BenchmarkSet_valsize1024(b *testing.B) { benchmarkSet(1024, b) } +func BenchmarkSet_valsize10KB(b *testing.B) { benchmarkSet(10240, b) } +func BenchmarkSet_valsize500KB(b *testing.B) { benchmarkSet(1<<19, b) } +func BenchmarkSet_valsize1MB(b *testing.B) { benchmarkSet(1<<20, b) }