Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

0.3.3 release - ease of build, sample compatibility, fixes, benchmark…

… post
  • Loading branch information...
commit 5f182980386ff90dfde88a273a49712cb4018434 1 parent 8d646da
@hdiedrich hdiedrich authored
Showing with 7,781 additions and 733 deletions.
  1. +131 −45 Makefile
  2. +7 −4 README.html
  3. +6 −3 README.md
  4. +5 −5 doc/BENCHMARK-README.html
  5. +124 −77 doc/BENCHMARK1.html
  6. +144 −98 doc/BENCHMARK1.md
  7. +0 −173 doc/BENCHMARK2.html
  8. +0 −162 doc/BENCHMARK2.md
  9. +82 −10 doc/CHANGES.html
  10. +74 −12 doc/CHANGES.md
  11. +1 −0  etc/bench/Makefile
  12. +5 −5 etc/bench/README.html
  13. +5 −5 etc/bench/README.md
  14. +13 −4 etc/bench/bench.erl
  15. +10 −0 etc/test/depr/Makefile
  16. +1,482 −0 etc/test/depr/erlunit/erlunit.erl
  17. +120 −0 etc/test/depr/erlunit/erlunit.hrl
  18. +903 −0 etc/test/depr/test1.erl
  19. +491 −0 etc/test/depr/test2.erl
  20. +2,590 −0 etc/test/depr/test3.erl
  21. +817 −0 etc/test/depr/test4.erl
  22. +38 −0 etc/test/dialyzer.mk
  23. +128 −0 etc/test/maketest.mk
  24. +14 −0 examples/Makefile
  25. +2 −2 examples/hello.erl
  26. +48 −5 examples/hello_plus.erl
  27. +130 −0 examples/hello_pre3.erl
  28. +13 −13 examples/parallel.erl
  29. +177 −0 examples/parallel_pre3.erl
  30. +1 −1  examples/voter.erl
  31. +30 −55 include/erlvolt.hrl
  32. +3 −27 include/erlvolt_wire.hrl
  33. +2 −0  src/Makefile
  34. +1 −1  src/erlvolt.app.src
  35. +3 −2 src/erlvolt.erl
  36. +2 −1  src/erlvolt_app.erl
  37. +8 −7 src/erlvolt_conn.erl
  38. +13 −2 src/erlvolt_conn_mgr.erl
  39. +140 −0 src/erlvolt_internal.hrl
  40. +2 −2 src/erlvolt_profiler.erl
  41. +16 −12 src/erlvolt_wire.erl
View
176 Makefile
@@ -1,20 +1,20 @@
###-------------------------------------------------------------------------###
### File : Makefile ###
-### Version : 0.3.0/beta ###
+### Version : 0.3/beta ###
### Description : Erlang VoltDB driver main build and run rules ###
### Copyright : VoltDB, LLC - http://www.voltdb.com ###
### Production : Eonblast Corporation - http://www.eonblast.com ###
### Author : H. Diedrich <hd2012@eonblast.com> ###
### License : MIT ###
### Created : 17 Apr 2010 ###
-### Changed : 02 Feb 2013 ###
+### Changed : 06 Feb 2013 ###
###-------------------------------------------------------------------------###
### ###
### This driver is being contributed to VoltDB by Eonblast Corporation. ###
### ###
###-------------------------------------------------------------------------###
### ###
-### Erlvolt 0.3.0/alpha - Erlang VoltDB client API. ###
+### Erlvolt 0.3/beta - Erlang VoltDB client API. ###
### ###
### This file is part of VoltDB. ###
### Copyright (C) 2008-2013 VoltDB, LLC http://www.voltdb.com ###
@@ -77,12 +77,13 @@
###-------------------------------------------------------------------------###
LIBDIR=$(shell erl -eval 'io:format("~s~n", [code:lib_dir()])' -s init stop -noshell)
-VERSION=0.3.1
+VERSION=0.3.3
PKGNAME=erlvolt
APP_NAME=erlvolt
MODULES=$(shell ls -1 src/*.erl | awk -F[/.] '{ print $$2 }' | sed '$$q;s/$$/,/g')
MAKETIME=$(shell date)
+LESSVERB=--no-print-directory
#
# Main Build, Hello, Bench
@@ -90,14 +91,14 @@ MAKETIME=$(shell date)
# Build the driver, with debug info compiled in
all: app
- @(cd src; $(MAKE) DEBUG=true)
- @(cd etc/bench; $(MAKE) DEBUG=true)
+ @(cd src; $(MAKE) $(LESSVERB) DEBUG=true)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) DEBUG=true)
# Hello 'redirects' to a robuster hello world
hello: hello-plus
# This executed examples/hello_plus.erl.
# Simplest source see examples/hello.erl,
- # 'make hello-barebones' executes it.
+ # 'make hello-barebones' executes that.
#
@@ -105,16 +106,16 @@ hello: hello-plus
#
fast: app
- @(cd src;$(MAKE) NATIVE=true)
- @(cd etc/bench; $(MAKE) NATIVE=true)
+ @(cd src;$(MAKE) $(LESSVERB) NATIVE=true)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) NATIVE=true)
profile: app
- @(cd src;$(MAKE) PROFILE=true NATIVE=true)
- @(cd etc/bench; $(MAKE) PROFILE=true NATIVE=true)
+ @(cd src;$(MAKE) $(LESSVERB) PROFILE=true NATIVE=true)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) PROFILE=true NATIVE=true)
profile-debug: app
- @(cd src;$(MAKE) PROFILE=true DEBUG=true)
- @(cd etc/bench;$(MAKE) PROFILE=true DEBUG=true)
+ @(cd src;$(MAKE) $(LESSVERB) PROFILE=true DEBUG=true)
+ @(cd etc/bench;$(MAKE) $(LESSVERB) PROFILE=true DEBUG=true)
app: ebin/$(PKGNAME).app
@@ -128,25 +129,37 @@ ebin/$(PKGNAME).app: src/$(PKGNAME).app.src
# A slightly more robust hello world: hello_plus.erl
hello-plus: all
- @(cd examples; $(MAKE) hello-plus DEBUG=true)
+ @(cd examples; $(MAKE) $(LESSVERB) hello-plus DEBUG=true)
erl -pa ./ebin -s hello_plus run -s init stop -noshell
# A simpler hello.erl
hello-barebones: all
- @(cd examples; $(MAKE) hello DEBUG=true)
+ @(cd examples; $(MAKE) $(LESSVERB) hello DEBUG=true)
erl -pa ./ebin -s hello run -s init stop -noshell
+# A simpler hello.erl
+hello-barebones-pre3: all
+ @(cd examples; $(MAKE) $(LESSVERB) hello-barebones-pre3 DEBUG=true)
+ erl -pa ./ebin -s hello_pre3 run -s init stop -noshell
+
# A more Erlang hello world with many processes.
parallel: all
- @(cd examples; $(MAKE) parallel DEBUG=true)
+ @(cd examples; $(MAKE) $(LESSVERB) parallel DEBUG=true)
erl -pa ./ebin -s parallel run -s init stop -noshell
+# A more Erlang hello world with many processes, for VoltDB pre 3.0.
+# The only difference is a switch in the column order in the hello sample.
+parallel-pre3: all
+ @(cd examples; $(MAKE) $(LESSVERB) parallel-pre3 DEBUG=true)
+ erl -pa ./ebin -s parallel_pre3 run -s init stop -noshell
+
+
#
# Voter sample
#
voter: all
- @(cd examples; $(MAKE) voter DEBUG=true)
+ @(cd examples; $(MAKE) $(LESSVERB) voter DEBUG=true)
erl -pa ./ebin -s voter run -s init stop -noshell
#
@@ -161,23 +174,23 @@ benches: bench-vsm bench-vsd bench-vbm bench-vbd
### Voter steady managed (reference 13,000 T/sec/core)
bench-vsm:
- @(cd etc/bench; $(MAKE) bench-vsm NATIVE=true)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) bench-vsm NATIVE=true)
### Voter steady direct (reference 21,000 T/sec/core)
bench-vsd:
- @(cd etc/bench; $(MAKE) bench-vsd NATIVE=true)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) bench-vsd NATIVE=true)
### Voter bursts managed (reference 10,000 T/sec/core)
bench-vbm:
- @(cd etc/bench; $(MAKE) bench-vbm NATIVE=true)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) bench-vbm NATIVE=true)
### Voter bursts direct (reference 16,000 T/sec/core)
bench-vbd:
- @(cd etc/bench; $(MAKE) bench-vbd NATIVE=true)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) bench-vbd NATIVE=true)
### Hello steady direct (reference 21,000 T/sec/core)
bench-hsd:
- @(cd etc/bench; $(MAKE) bench-hsd NATIVE=true)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) bench-hsd NATIVE=true)
### Multi-VM benchmark (VSD)
# optional parameters (default):
@@ -187,21 +200,38 @@ bench-hsd:
# SPAWN (100) # of parallel ('steady') workers = max server load
# use e.g. make bench-mvm CALLS=1000000
bench-mvm:
- @(cd etc/bench; $(MAKE) bench-mvm)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) bench-mvm)
bench-help:
- @(cd etc/bench; $(MAKE) bench-help)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) bench-help)
#
# Doc Creation
#
+# Create doc HTML from source comments
+# IF THIS FAILS, IT'S THE -E
+docs: clean-docs
+ @echo make docs
+ sed -E -f etc/markedoc.sed README.md > doc/readme.edoc
+ sed -E -f etc/markedoc.sed CHANGES.md > doc/changes.edoc
+ erl -noshell -run edoc_run application "'erlvolt'" '"."' '[{def,{vsn,""}},{stylesheet, "erlvolt-style.css"}]'
+ LANG=C sed -E -i "" -e "s/<table width=\"100%\" border=\"1\"/<table width=\"100%\" class=index border=\"0\"/" doc/*.html
+
+# Pushes created docs into dir ../Erlvolt-github-pages to push to github pages.
+# Make sure to do 'make docs' first.
+# will fail if you haven't checked out github pages into ../Erlvolt-github-pages
+pages:
+ (cd ../Erlvolt-github-pages; git pull origin gh-pages)
+ cp -r doc/* ../Erlvolt-github-pages
+ (cd ../Erlvolt-github-pages; git add .; git commit -m 'make pages'; git push origin gh-pages)
+
# Create HTML from Markdown to test README.md appearance
html:
+ @echo make html
lua etc/markdown.lua README.md
lua etc/markdown.lua doc/CHANGES.md
lua etc/markdown.lua doc/BENCHMARK1.md
- lua etc/markdown.lua doc/BENCHMARK2.md
lua etc/markdown.lua etc/bench/README.md && cp etc/bench/README.html doc/BENCHMARK-README.html
#
# Building and Deployment
@@ -210,31 +240,24 @@ html:
# clean and doc creation for release, any branch
release: clean html
-# clean for master branch
-master: release
- etc/replace %-%.* ""
- etc/replace TODO.*$ ""
- rm -f doc/edoc-info
- rm -f doc/erlang.png
- rm -f doc/erlvolt-footer.png
- rm -f doc/erlvolt-style.css
- rm -f doc/stylesheet.css
-
clean:
+ @echo clean
@# these can all appear
- @(cd src; $(MAKE) clean)
- @(cd examples; $(MAKE) clean)
- @(cd etc/bench; $(MAKE) clean)
+ @(cd src; $(MAKE) $(LESSVERB) clean)
+ @(cd examples; $(MAKE) $(LESSVERB) clean)
+ @(cd etc/bench; $(MAKE) $(LESSVERB) clean)
+ @rm -f ct_run*
+ @rm -f .DS_Store
+ @rm -rf */.DS_Store
+ @rm -rf */*.DS_Store
@rm -rf ebin/*.app
@rm -rf ebin/*.beam
@rm -rf ebin/*.dump
@rm -rf ebin/cover
@rm -f *.beam
@rm -f *.dump
- @rm -f *.html
@rm -f *.log
@rm -f *.totals
- @rm -rf ct_run*
@rm -f variables-ct*
@rm -rf etc/test/ct_run*
@rm -f etc/test/variables-ct*
@@ -242,33 +265,96 @@ clean:
@rm -f etc/test/*.html
@rm -f etc/test/ct_default.css
@rm -f etc/test/jquery*.js
+ @rm -f doc/.!*.html
@rm -rf $(PKGNAME)-$(VERSION)
@rm -f $(PKGNAME)-$(VERSION).tgz
- # clean
clean-docs:
+ @echo clean docs
@rm -f doc/readme.edoc
@rm -f doc/changes.edoc
@rm -f doc/overview.edoc
@rm -f doc/*.html
+ @rm -f doc/.!*.html
@rm -f doc/README.html
@rm -f doc/CHANGES.html
@rm -f doc/BENCHMARKS.html
@rm -f doc/BENCHMARK1.html
- @rm -f doc/BENCHMARK2.html
@rm -f doc/BENCHMARK-README.html
package: clean
- @mkdir $(PKGNAME)-$(VERSION)/ && cp -rf ebin include Makefile README.md src etc examples $(PKGNAME)-$(VERSION)
+ @mkdir $(PKGNAME)-$(VERSION)/ && cp -rf ebin include Makefile README.md README.html src doc etc examples $(PKGNAME)-$(VERSION)
@COPYFILE_DISABLE=true tar zcf $(PKGNAME)-$(VERSION).tgz $(PKGNAME)-$(VERSION)
@rm -rf $(PKGNAME)-$(VERSION)/
-
#
-# Tests
+# Unit Tests
#
test: all
(cd etc/test; ct_run -suite environment_SUITE basics_SUITE -pa ../../ebin)
+#
+# Dialyzer Tests
+#
+
+include etc/test/dialyzer.mk
+
+
+#
+# Make Help
+#
+help:
+ # building
+ # --------
+ # all: Build all, with debug info, w/o profiler
+ # fast: Build native HiPE beams, 20% faster
+ # profile: Build native and with profiler, which is slower
+ # profile-debug: Build with profiler and debug info
+ # clean: Clean all built files
+ #
+ # examples
+ # --------
+ # hello: Build hello world example, needs running hello world database
+ # hello-plus: A slightly more robust hello world: hello_plus.erl
+ # hello-barebones: A simpler hello.erl
+ # hello-barebones-pre3: A simpler hello.erl
+ # parallel: A more Erlang hello world with many processes.
+ # parallel-pre3: A more Erlang hello world with many processes, for VoltDB pre 3.0.
+ # voter: Build voter example, needs running voter database
+ #
+ # benchmarks
+ # ----------
+ # bench-help: More details on the following bench rules
+ # bench: Alias for bench-vsd
+ # benches: Bench-vsm bench-vsd bench-vbm bench-vbd
+ # bench-vsm: Voter steady managed (reference 13,000 T/sec/core)
+ # bench-vsd: Voter steady direct (reference 21,000 T/sec/core)
+ # bench-vbm: Voter bursts managed (reference 10,000 T/sec/core)
+ # bench-vbd: Voter bursts direct (reference 16,000 T/sec/core)
+ # bench-hsd: Hello steady direct (reference 21,000 T/sec/core)
+ # bench-mvm: Multi-VM benchmark (VSD)
+ # Optional parameters (default):
+ # VMS (5) # of virtual machines (erl Erlang emulators) started
+ # CORES (1) # number of cores used per VM (erl parameter +S)
+ # CALLS (100000) # of transactions per VM for the benchmark
+ # SPAWN (100) # of parallel ('steady') workers = max server load
+ # Use e.g. make bench-mvm CALLS=1000000
+ #
+ # documentation building
+ # ----------------------
+ # docs: Create doc HTML from source comments
+ # html: Create HTML from Markdown to test README.md appearance
+ # clean-docs: Clean the files built by make docs and make html
+ #
+ # release building
+ # ----------------
+ # release: Clean and doc creation for release, any branch
+ # package: make zipped tarball
+ #
+ # source tests
+ # ------------
+ # test: run Common Tests (unit tests)
+ # dialyzer: run dialyzer source tests
+ @echo
View
11 README.html
@@ -2,20 +2,23 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <title>voltdb-client-erlang Erlvolt 0.3.1/beta</title>
+ <title>voltdb-client-erlang Erlvolt 0.3.3/beta</title>
<link rel="stylesheet" type="text/css" href="default.css" />
</head>
<body>
-<h1>voltdb-client-erlang Erlvolt 0.3.1/beta</h1>
+<h1>voltdb-client-erlang Erlvolt 0.3.3/beta</h1>
-<p><strong>Release: 'Erlvolt 0.3.1/beta'</strong> <br/>
+<p><strong>Release: 'Erlvolt 0.3.3/beta'</strong> <br/>
<strong>Author: H. Diedrich</strong> <br/>
<strong>Production: Eonblast Corporation</strong> <br/>
<strong>Copyright: (c) 2013 VoltDB, Inc</strong> <br/>
<strong>Licence: MIT</strong> <br/>
<strong>Date: 4 Feb 2013</strong> </p>
+<p><strong>VoltDB: 2.8, 3.0</strong>
+<strong>Erlang: R15B03, R16 RC</strong></p>
+
<p>This is an <a href="http://www.erlang.org">Erlang</a> <a href="hhtp://www.voltdb.com">VoltDB</a> driver provided by <a href="http://www.eonblast.com">Eonblast</a>. It is <a href="#Samples">easy</a> to use but provides strong <a href="#Adding_a_Pool">connection pooling</a> and a broad array of <a href="#Options">options</a>. It is optimized for a central node architecture and super high velocity OLTP.</p>
<p>While databases generally can be accessed via ODBC in Erlang, you should see better performance when using a <em>driver</em> like Erlvolt. For <a href="#Samples">samples</a>, <a href="#Usage">API description</a> and fine tuning <a href="#Options">options</a> see below. </p>
@@ -140,7 +143,7 @@
<pre><code>-module(hello).
-export([run/0]).
--import(erlvolt).
+
-include("erlvolt.hrl").
run() -&gt;
View
9 README.md
@@ -1,13 +1,16 @@
-voltdb-client-erlang Erlvolt 0.3.1/beta
+voltdb-client-erlang Erlvolt 0.3.3/beta
=======================================
-**Release: 'Erlvolt 0.3.1/beta'**
+**Release: 'Erlvolt 0.3.3/beta'**
**Author: H. Diedrich**
**Production: Eonblast Corporation**
**Copyright: (c) 2013 VoltDB, Inc**
**Licence: MIT**
**Date: 4 Feb 2013**
+**VoltDB: 2.8, 3.0**
+**Erlang: R15B03, R16 RC**
+
This is an [Erlang](http://www.erlang.org) [VoltDB](hhtp://www.voltdb.com) driver provided by [Eonblast](http://www.eonblast.com). It is [easy][Samples] to use but provides strong [connection pooling][Adding_a_Pool] and a broad array of [options][options]. It is optimized for a central node architecture and super high velocity OLTP.
While databases generally can be accessed via ODBC in Erlang, you should see better performance when using a *driver* like Erlvolt. For [samples][Samples], [API description][Usage] and fine tuning [options][Options] see below.
@@ -123,7 +126,7 @@ This is a hello world program. Follow the steps below to try it out.
-module(hello).
-export([run/0]).
- -import(erlvolt).
+
-include("erlvolt.hrl").
run() ->
View
10 doc/BENCHMARK-README.html
@@ -9,14 +9,14 @@
<h1>Benchmarks</h1>
-<p><strong>voltdb-client-erlang Erlvolt 0.3.0</strong></p>
+<p><strong>voltdb-client-erlang Erlvolt 0.3</strong> </p>
-<p><strong>Release: 'Erlvolt 0.3.0'</strong> <br/>
+<p><strong>Release: 'Erlvolt 0.3.2'</strong> <br/>
<strong>Author: H. Diedrich</strong> <br/>
<strong>Production: Eonblast Corporation</strong> <br/>
<strong>Copyright: (c) 2013 VoltDB, Inc</strong> <br/>
<strong>Licence: MIT</strong> <br/>
-<strong>Date: Jan 31 2013</strong></p>
+<strong>Date: 31 Jan 2013</strong></p>
<h2>Quick Start</h2>
@@ -30,7 +30,7 @@
<h2>Quick Read</h2>
-<p>For reference benchmarks done in the EC2 cloud, see doc/BENCHMARKS.md or html.</p>
+<p>For a reference benchmark done in the EC2 cloud, see doc/BENCHMARK1.md or html.</p>
<h2>Usage</h2>
@@ -380,5 +380,5 @@
<hr/>
-<p>/hd 3 feb 13</p>
+<p>/hd 31 jan 13</p>
</body></html>
View
201 doc/BENCHMARK1.html
@@ -2,168 +2,215 @@
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <title>VoltDB Blog: 212 TPS/core with Erlang and VoltDB </title>
+ <title>VoltDB Blog: 877,000 TPS with Erlang and VoltDB </title>
<link rel="stylesheet" type="text/css" href="default.css" />
</head>
<body>
-<h1>VoltDB Blog: 212 TPS/core with Erlang and VoltDB </h1>
+<h1>VoltDB Blog: 877,000 TPS with Erlang and VoltDB </h1>
-<p>Henning Diedrich - 31 Jan 2013</p>
+<p>Henning Diedrich - 6 Feb 2013</p>
-<p><strong>Running on a suitable EC2 configuration (see details below), with our new VoltDB Erlang driver we achieved 212,000 transactions per second.</strong></p>
+<p><strong>Running on a suitable EC2 configuration (see details below), with our new VoltDB Erlang driver we achieved 877,519 transactions per second.</strong></p>
-<p>I am Henning Diedrich, CEO of <a href="http://www.eonblast.com">Eonblast Corporation</a> a games company. I would like to introduce the new Erlang VoltDB driver we created, a piece of software that allows two genre-defining technologies to work together: VoltDB and Erlang.</p>
+<p>I am Henning Diedrich [1], CEO of Eonblast Corporation [2] a games company. I would like to introduce the new Erlang VoltDB driver we created, a piece of software that allows two genre-defining technologies to work together: VoltDB [3] and Erlang [4].</p>
<h2>The Driver</h2>
-<p>I first came to VoltDB on the hunt for a better database for heavy duty online-game servers. I experienced first hand what a pain it was to try to scale MySQL and found VoltDB uniquely suitable for the requirements of more complex game worlds. Better than any other database in fact.</p>
+<p>I first came to VoltDB on the hunt for a better database for heavy duty online-game servers. I experienced first hand [5] what a pain it was to try to scale MySQL and found <strong>VoltDB</strong> [3] uniquely suitable for the requirements of more complex game worlds. Better than any other database in fact [6].</p>
-<p>I had also looked for a better language than Java for programming servers and for that, I had found Erlang. To be able to use them together, I started creating the Erlang driver for VoltDB.</p>
+<p>I had also looked for a better language than Java for programming servers and for that, <strong>Erlang</strong> [7] had caught my attention. To be able to use them together [8], I started creating the Erlang driver for VoltDB [9].</p>
-<p>Work for this started three years ago and I donated a first version of the driver to VoltDB at their request in 2009. It was perfectly usable but out of the box only provided for synchronous connections. In 2012 VoltDB decided to sponsor the creation of a bigger and badder version. Now the real deal has arrived.</p>
+<p>Work for this started three years ago and I donated a first version of the driver [10] to VoltDB at their request in 2010. It was perfectly usable but out of the box only provided for synchronous connections. In 2012 VoltDB decided to sponsor the creation of a bigger and badder version. Now the real deal has arrived [11].</p>
-<p>The benchmark described below was made with the new, asynchronous driver. It is pure Erlang, full of parallel microprocesses, blazingly fast and fit for VoltDB 3. It incorporates almost all of the previous, robust driver version. And on my quest to ensure reliable, consistently high throughput, I was able to draw from my experience maintaining an Erlang MySQL driver, Emysql. The connection pooling and call queueing is modeled after the ones used in this reliable workhorse, which was originally designed at Electronic Arts. They enable the Erlang driver to absorb access peaks, and to distribute load across VoltDB server nodes.</p>
+<p>The benchmark described below was made with the new, asynchronous driver. It is pure Erlang, full of parallel microprocesses, blazingly fast and fit for VoltDB 3 [12]. It builds on and incorporates almost all of the previous, robust driver version. And on my quest to ensure reliable, consistently high throughput, I was able to draw from my experience maintaining an Erlang <strong>MySQL</strong> driver, Emysql [13]. The connection pooling and call queueing is modeled after the ones used in that reliable workhorse, originally designed at Electronic Arts. They enable the Erlang driver to absorb access peaks, and to distribute load across VoltDB server nodes.</p>
-<p>To come up with a useful benchmark script I could employ the lessons learned from the Node.js benchmark I did for VoltDB a while ago, see http://blog.voltdb.com/695k-tps-nodejs-and-voltdb/. This time around I knew which numbers I would be looking for and what double checks I should have in place to put the cloud cluster to good use.</p>
+<p>To come up with a useful benchmark script I could employ the lessons learned from the Node.js benchmark [14] I did for VoltDB a while ago. This time around I knew which numbers I would be looking for and what double checks I should have in place to put the cloud cluster to good use.</p>
-<p>The internal structure of the driver has been implemented as would be expected: your application's microprocesses are made to send a message to a dedicated connection process that handles the socket work. After the request is sent, the initiating process is either blocked in a synchronous receive (this, of course, does not block all your other processes) or goes on to to use its time as it pleases, if you choose the asynchronous mode. The answer from the server arrives in your processes' mailbox. </p>
+<p>The internal structure of the driver has been implemented as would be expected: your program's microprocesses use the functions the driver exposes to send a message to a dedicated connection process, which handles the socket work. After the request is sent, the initiating process is either blocked in a <em>synchronous</em> receive (this, of course, does <em>not</em> block all your <em>other</em> processes) or goes on to to use its time as it pleases, should you choose the <em>asynchronous</em> mode. The answer from the server arrives in your processes' mailbox.  (Note, <em>synchronous</em> in this context, when looking at the driver. The call to the VoltDB server is still an asynchronous call. The driver simply has your process wait in a receive block.)</p>
-<p>There are many options that you can use. E.g. the 'monitored' mode, where a worker process is created that handles the sending of the request, shielding your initiating process from any hiccups in the driver. You can 'fire and forget', for writes where you don't care to hear that they succeeded. Or 'blowout' if you don't even care to hear about failure.</p>
+<p>There are many options that you can use. E.g. the <em>monitored</em> mode, where a worker process is created that handles the sending of the request, thereby shielding your initiating process from any hiccups in the driver. You can <em>fire and forget</em>, for writes where you don't care to hear that they succeeded. Or <em>blowout</em> if you don't even care to hear about failure.</p>
<h2>The Benchmark Application</h2>
-<p>The benchmark is based on the VoltDB voter example, which comes with every VoltDB distribution. It 'validates and stores phoned-in votes for talent show contestants'. In the original example setup there is a web page that displays the results for illustration, updated every 400ms. You'll find it in the <VoltDB_Home>/examples/voter directory.</p>
+<p>The benchmark is based on the VoltDB voter example, which comes with every VoltDB distribution. It 'validates and stores phoned-in votes for talent show contestants'. In the original example setup, there is a web page that displays the results for illustration, updated every 400ms. You'll find it in the <code>examples/voter</code> directory of your <em>VoltDB</em> installation.</p>
-<p>The benchmark starts out with a preparational phase, where the database is filled with 6 contestants' names and then one million write transactions are fired towards the server, per CPU core, that each register a 'vote' for one of the contestant, picked at random. In the end, the votes won by each contestants are displayed, using a materialized view and a VoltDB ad-hoc query.</p>
+<p>The benchmark starts out with a preparational phase, where the database is filled with 6 contestants' names and then one million write transactions are fired towards the server, per CPU core, that each register a 'vote' for one of the contestants, picked at random. In the end, the votes won by each contestants are displayed, using a materialized view and a VoltDB ad-hoc query. (In VoltDB parlance, ad-hoc queries are normal queries that are not pre-formulated in a stored procedure.)</p>
-<p>The Erlang benchmark application that implements a Voter client is packaged with the driver, which can be downloaded here https://github.com/VoltDB/voltdb-client-erlang. The benchmark source is under etc/bench, where you'll also find a detailed README.md that explains how to build and deploy the application. For a (slow) test run on localhost, it's basically:</p>
+<p>The benchmark source is under etc/bench [15] of the <em>driver</em> home directory, where you'll also find a detailed README.md that explains the multiple ways to run the benchmark and make it fit your setup. For a (slow) test run on localhost, it's basically:</p>
<p>    $ git clone git://github.com/VoltDB/voltdb.git voltdb
    $ git clone git://github.com/VoltDB/voltdb-client-erlang.git erlvolt
    $ cd voltdb/examples/voter &amp;&amp; ./run.sh &amp;
-    $ cd &amp;&amp; cd erlvolt &amp;&amp; make bench</p>
+    $ cd &amp;&amp; cd erlvolt &amp;&amp; make clean all bench</p>
<p>That should give you a screen like this:</p>
-<pre><code> metal:~ hd$ cd voltdb/examples/voter &amp;&amp; ./run.sh &amp;
- [1] 62084
+<pre><code> metal:~ hd$ cd voltdb-3-com/examples/voter &amp;&amp; ./run.sh &amp;
+ [1] 10817
metal:~ hd$ Initializing VoltDB...
- _    __      ____  ____  ____ 
- | |  / /___  / / /_/ __ \/ __ )
- | | / / __ \/ / __/ / / / __  |
- | |/ / /_/ / / /_/ /_/ / /_/ / 
+ _ __ ____ ____ ____
+ | | / /___ / / /_/ __ \/ __ )
+ | | / / __ \/ / __/ / / / __ |
+ | |/ / /_/ / / /_/ /_/ / /_/ /
|___/\____/_/\__/_____/_____/
--------------------------------
- WARN: Running 3.0 preview (iv2 mode). NOT SUPPORTED IN PRODUCTION.
- Build: 3.0 voltdb-3.0-beta2-110-g178a1e6 Community Edition
+ Build: 3.0 voltdb-3.0-95-gfffab2b Community Edition
Connecting to VoltDB cluster as the leader...
- Appointing HSId 0:0 as leader for partition 0
- Appointing HSId 0:1 as leader for partition 1
- MP 0:6 for partition 16383 finished leader promotion. Took 104 ms.
- WARN: Mailbox is not registered for site id -4
- Initializing initiator ID: 0, SiteID: 0:13
+ Initializing initiator ID: 0, SiteID: 0:5
WARN: Running without redundancy (k=0) is not recommended for production use.
Server completed initialization.
- cd &amp;&amp; cd ErlVolt2 &amp;&amp; make bench
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_app.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_conn.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_conn_mgr.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_profiler.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_sup.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_wire.erl
- erlc -W -I ../../include  +native -smp  -o ../../ebin bench.erl
+
+ metal:erlvolt hd$ cd &amp;&amp; cd erlvolt &amp;&amp; make clean all bench
+ clean
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_app.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_conn.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_conn_mgr.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_profiler.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_sup.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_wire.erl
+ erlc -W -I ../../include +debug_info -o ../../ebin bench.erl
+
Erlvolt Bench 0.9 (client 'VSD')
-------------------------------------------------------------------------------------------------------------------------------------
- Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, 'n/a' stats/sec
- Hosts: localhost:21212 localhost:21212 
+ Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, "n/a" stats/sec
+ Hosts: localhost:21212
connect ...
preparation ...
- calls ... ........................................................................................................................................
- cool down ... 
+ Start at: 2013-02-06 18:56:20 .....................
+ Starting: 2013-02-06 18:56:20
+ calls ... ..................................
+ cool down ...
check writes ... ok
- results ...  votes:     100,000 (6 contestants)
- ....Jessie Alloway:      16,811
- ...Tabatha Gehling:      16,661
- ....Jessie Eichman:      16,643
- .....Alana Bregman:      16,634
- .....Edwina Burnam:      16,632
- ......Kelly Clauss:      16,619
+ results ... votes: 100,000 (6 contestants)
+ .....Edwina Burnam: 16,817
+ ....Jessie Alloway: 16,808
+ ...Tabatha Gehling: 16,669
+ .....Alana Bregman: 16,613
+ ....Jessie Eichman: 16,556
+ ......Kelly Clauss: 16,537
close pool ...
- Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, 'n/a' stats/sec
+ Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, "n/a" stats/sec
-------------------------------------------------------------------------------------------------------------------------------------
- Client 'VSD' overall: 3,657 T/sec throughput, 0.00% fails, total transactions: 100,000, fails: 0, total time: 27.338sec 
- Erlvolt 0.3.0, bench started 2013-01-31 22:09:27, ended 2013-01-31 22:09:54, database: +100,000 new votes
- [+++]
- metal:ErlVolt2 hd$ 
+
+ Client 'VSD' overall: 14,357 T/sec throughput, 0.00% fails, total transactions: 100,000, fails: 0, total time: 6.965sec
+ Erlvolt 0.3.3, bench started 2013-02-06 18:56:20, ended 2013-02-06 18:56:26, database: +100,000 new votes
+ [++++++++++++++]
</code></pre>
-<p>Instructions on how to use it in the cloud can be found in etc/bench/README.me.</p>
+
+<p>For further instructions, e.g. how to best run the benchmark in the cloud, please see etc/bench/README.md [16], or verbatim doc/BENCHMARK-README.html, in your driver home folder.</p>
<h2>The Benchmark Results</h2>
-<p>Using 3 nodes connected to a 5 node VoltDB cluster, each client node executed an average of 70,600 TPS for a total of 212,000 TPS. Clients and server worked at only 40% load, so more tuning would probably have yielded higher results, on both client and server side. </p>
+<p>When run on a single core (-smb +S 1), with a 12-node VoltDB server cluster listening on the other side, the Erlang driver showed throughput of <strong>26,500 transactions per second (TPS) and more per one core</strong>. When fully utilizing a 16-core cluster instance as client node, it routinely reached throughput of <strong>260,000 transactions per second per machine</strong>. (CPU specs see below.)</p>
-<p>Since this benchmark was about the driver, not the server, I made no attempts to tune the server cluster.</p>
+<p>Using 8 client nodes connected to a 12-node VoltDB cluster, each client node executed an average of 109,689 transactions per second for a <strong>cluster total of 877,519 TPS</strong>.</p>
+
+<p>Since this benchmark was about the driver, not the server, I made no attempts to tune the server cluster. After a lot of experimenting, I believe that the lower performance per client core for bigger server clusters would reflect the network limitations of the EC2 cloud, even for the bigger cluster instances [17] where the hope would be that a benchmark would not end up network-bound.</p>
+
+<p>Part of the goal for the benchmark was testing how the driver would hold up under load and that turned out very well. The driver does not crash from really heavy overload and it copes well with 'backpressure' [18] when the server does not allow further requests for being at capacity. However, the fastest benchmarks resulted when not overloading the server.</p>
<h2>The Environment</h2>
-<p>I created an 8-node Amazon EC2 m3.2xlarge cluster broken up into Erlang client and VoltDB server nodes. The m3.2xlarge provide the following, as described by the Amazon EC2 Instance Types page:</p>
+<p>I started a 20-node Amazon EC2 cc2.xlarge cluster broken up into 8 Erlang client and 12 VoltDB server nodes. The m3.2xlarge provide the following, as described by the Amazon EC2 Instance Types page [17]:</p>
-<h3>M3 Double Extra Large Instance</h3>
+<h3>Cluster Compute Eight Extra Large Instance (cc2.8xlarge)</h3>
<ul>
- <li>30 GiB memory</li>
- <li>26 EC2 Compute Units (8 virtual cores with 3.25 EC2 Compute Units each)</li>
+ <li>60.5 GiB of memory</li>
+ <li>88 EC2 Compute Units (2 x Intel Xeon E5-2670, eight-core)</li>
+ <li>3370 GB of instance storage</li>
<li>64-bit platform</li>
- <li>I/O Performance: High</li>
- <li>API name: m3.2xlarge</li>
+ <li>I/O Performance: Very High (10 Gigabit Ethernet)</li>
</ul>
<p>These nodes were configured with:</p>
<ul>
<li>Ubuntu Server 12.04 LTS for Cluster Instances AMI</li>
- <li>Oracle JDK 1.7</li>
- <li>Erlang 15</li>
+ <li>Oracle Java JDK 1.7</li>
+ <li>Erlang R15B03</li>
<li>VoltDB Enterprise Edition 3.0 RC</li>
</ul>
-<p>Each of the five server nodes was set to six partitions, so I had 30 partitions across the cluster.</p>
+<p>On advice from VoltDB, each of the five server nodes was set to six partitions, so I had 30 partitions across the database cluster.</p>
+
+<p>This benchmark would perform the same on the free Community Edition of Volt 3.0.</p>
<h2>The Transactions</h2>
-<p>The clients "firehosed" the VoltDB cluster by calling Voter’s vote() stored procedure continuously. This procedure performed not merely one write but, depending on how you count, 4 to 6 operations:</p>
+<p>The clients "firehose" the VoltDB cluster by calling Voter's <code>vote()</code> stored procedure continuously. This procedure performes not only one write but, depending on how you count, 4 to 6 operations:</p>
<ul>
- <li>Retrieve the caller’s location (select)</li>
- <li>Verify that the caller had not exceeded his/her vote maximum (select)</li>
- <li>Verify that the caller was voting for a valid contestant (select)</li>
- <li>If yes to all of the above, a vote was cast on behalf of that caller (insert)</li>
+ <li>It retrieves the caller's location (a <code>select</code>)</li>
+ <li>Verifies that the caller has not exceeded his/her vote maximum (a <code>select</code>)</li>
+ <li>Verifies that the caller was voting for a valid contestant (a <code>select</code>)</li>
+ <li>And if yes to all of the above, a vote is cast on behalf of that caller (an <code>insert</code>)</li>
</ul>
-<p>On top of this, each insert also triggered an update to two different materialized views.</p>
+<p>On top of this, each <code>insert</code> also triggers an update to two different materialized views.</p>
+
+<p>Here are the actual queries that define the used stored procedures [19]:</p>
+
+<pre><code>// Checks if the vote is for a valid contestant
+SELECT contestant_number FROM contestants WHERE contestant_number = ?;
+
+// Checks if the voter has exceeded their allowed number of votes
+SELECT num_votes FROM v_votes_by_phone_number WHERE phone_number = ?;
+
+// Checks an area code to retrieve the corresponding state
+SELECT state FROM area_code_state WHERE area_code = ?;
+
+// Records a vote
+INSERT INTO votes (phone_number, state, contestant_number) VALUES (?, ?, ?);
+</code></pre>
+
+<p>Consequently, the 877,000 TPS performed <strong>3.5 million SQL operations per second</strong>, i.e. three selects and one insert.</p>
-<p>Consequently, the 212,000 TPS performed 848,000 SQL operations per second, i.e. three selects and one insert. </p>
<h2>Observations &amp; Notes</h2>
-<p>The most important number from this, to my mind, is the pretty constant 9,000 transactions per second per CPU core that I saw. This will allow you to make rough estimates on the amount of hardware you may need on the business server side (the VoltDB 'client' side).</p>
+<p>The most important number from this, to my mind, is the <strong>26,500 transactions per second per CPU core</strong> that I saw, which translates into 100,000 operations. This will allow you to make rough estimates on the amount of hardware you may need on the business server side (the VoltDB client side). Your client will usually have more work to do than simply swamp the server, as the benchmark does. So you have an upper limit here and can feel your way down from there. Note that many machines will show a significantly higher performance profile than EC2 instances.</p>
<p>We decided for the Amazon Elastic Cloud for the benchmark in the hopes that this would result into the most transparent setup. A local cluster of eight "bare metal" nodes would certainly perform better than the EC2 instance, and be way more economic if you used them on a daily basis. But our throughput numbers would be hard to reproduce independently.</p>
-<p>As it is, you could try the exact same benchmark yourself, easily. VoltDB and the new driver can be downloaded from http://voltdb.com/community/downloads.php. The README.md of the driver has more instructions on how to use it. To find experimental new versions of the driver as well as fast bug fixes, try https://github.com/VoltDB/voltdb-client-erlang, and VoltDB is also on github, at https://github.com/VoltDB/voltdb.</p>
-
-<p>/hd 31 jan 13</p>
+<p>As it is, you could try the exact same benchmark yourself, easily. VoltDB and the new driver can be downloaded from VoltDB [20]. The README.md [21] of the driver, and of the benchmark [16] have more instructions on how to use the driver and how to make benchmarks. To find experimental new versions of the driver as well as fast bug fixes, try the Eonblast Erlvolt repo at git [22]. The free VoltDB community edition is also on github [23].</p>
+
+<p>[1] Author on Twitter: https://twitter.com/hdiedrich <br/>
+[2] Eonblast: http://www.eonblast.com <br/>
+[3] VoltDB: http://www.voltdb.com <br/>
+[4] Erlang: http://www.erlang.org <br/>
+[5] Deepolis: http://www.deepolis.com <br/>
+[6] Choosing the Best Database For a Game: http://voltdb.com/dig-deeper/webinars.php <br/>
+[7] Why Erlang? http://www.slideshare.net/eonblast/why-erlang-gdc-online-2012 <br/>
+[8] Erlang and VoltDB: http://www.slideshare.net/eonblast/voltdb-and-erlang-tech-planet-2012 <br/>
+[9] Erlvolt 0.2: https://github.com/Eonblast/Erlvolt/tree/01b304f8975c2168be105c1b9c972386264c0a4e <br/>
+[10] http://blog.voltdb.com/community-contributions-erlang-client-library/ <br/>
+[11] Erlvolt 0.3: https://github.com/VoltDB/voltdb-client-erlang <br/>
+[12] VoltDB 3: http://blog.voltdb.com/introducing-voltdb-3-0/ <br/>
+[13] Emysql: https://github.com/Eonblast/Emysql <br/>
+[14] 695k with Node.js: http://blog.voltdb.com/695k-tps-nodejs-and-voltdb/ <br/>
+[15] bench.erl: https://github.com/VoltDB/voltdb-client-erlang/blob/master/etc/bench/bench.erl <br/>
+[16] Bench README: https://github.com/VoltDB/voltdb-client-erlang/blob/master/etc/bench <br/>
+[17] Amazon EC2 Cluster Instances: http://aws.amazon.com/ec2/instance-types/ <br/>
+[18] Backpressure: http://voltdb.com/docs/UsingVoltDB/DesignAppLogic.php <br/>
+[19] Query Source: https://github.com/VoltDB/voltdb/blob/master/examples/voter/src/voter/procedures/Vote.java <br/>
+[20] VoltDB Downloads: VoltDB http://voltdb.com/community/downloads.php <br/>
+[21] Driver README: https://github.com/VoltDB/voltdb-client-erlang <br/>
+[22] Erlvolt Development: https://github.com/Eonblast/Erlvolt <br/>
+[23] VoltDB Community Edition: https://github.com/VoltDB/voltdb </p>
+
+<p>/hd 6 feb 13</p>
</body></html>
View
242 doc/BENCHMARK1.md
@@ -1,158 +1,204 @@
-VoltDB Blog: 212 TPS/core with Erlang and VoltDB 
-======================================
+VoltDB Blog: 877,000 TPS with Erlang and VoltDB 
+===============================================
-Henning Diedrich - 31 Jan 2013
+Henning Diedrich - 6 Feb 2013
-**Running on a suitable EC2 configuration (see details below), with our new VoltDB Erlang driver we achieved 212,000 transactions per second.**
+**Running on a suitable EC2 configuration (see details below), with our new VoltDB Erlang driver we achieved 877,519 transactions per second.**
-I am Henning Diedrich, CEO of [Eonblast Corporation](http://www.eonblast.com) a games company. I would like to introduce the new Erlang VoltDB driver we created, a piece of software that allows two genre-defining technologies to work together: VoltDB and Erlang.
+I am Henning Diedrich [1], CEO of Eonblast Corporation [2] a games company. I would like to introduce the new Erlang VoltDB driver we created, a piece of software that allows two genre-defining technologies to work together: VoltDB [3] and Erlang [4].
The Driver
--------------
-I first came to VoltDB on the hunt for a better database for heavy duty online-game servers. I experienced first hand what a pain it was to try to scale MySQL and found VoltDB uniquely suitable for the requirements of more complex game worlds. Better than any other database in fact.
+I first came to VoltDB on the hunt for a better database for heavy duty online-game servers. I experienced first hand [5] what a pain it was to try to scale MySQL and found **VoltDB** [3] uniquely suitable for the requirements of more complex game worlds. Better than any other database in fact [6].
-I had also looked for a better language than Java for programming servers and for that, I had found Erlang. To be able to use them together, I started creating the Erlang driver for VoltDB.
+I had also looked for a better language than Java for programming servers and for that, **Erlang** [7] had caught my attention. To be able to use them together [8], I started creating the Erlang driver for VoltDB [9].
-Work for this started three years ago and I donated a first version of the driver to VoltDB at their request in 2009. It was perfectly usable but out of the box only provided for synchronous connections. In 2012 VoltDB decided to sponsor the creation of a bigger and badder version. Now the real deal has arrived.
+Work for this started three years ago and I donated a first version of the driver [10] to VoltDB at their request in 2010. It was perfectly usable but out of the box only provided for synchronous connections. In 2012 VoltDB decided to sponsor the creation of a bigger and badder version. Now the real deal has arrived [11].
-The benchmark described below was made with the new, asynchronous driver. It is pure Erlang, full of parallel microprocesses, blazingly fast and fit for VoltDB 3. It incorporates almost all of the previous, robust driver version. And on my quest to ensure reliable, consistently high throughput, I was able to draw from my experience maintaining an Erlang MySQL driver, Emysql. The connection pooling and call queueing is modeled after the ones used in this reliable workhorse, which was originally designed at Electronic Arts. They enable the Erlang driver to absorb access peaks, and to distribute load across VoltDB server nodes.
+The benchmark described below was made with the new, asynchronous driver. It is pure Erlang, full of parallel microprocesses, blazingly fast and fit for VoltDB 3 [12]. It builds on and incorporates almost all of the previous, robust driver version. And on my quest to ensure reliable, consistently high throughput, I was able to draw from my experience maintaining an Erlang **MySQL** driver, Emysql [13]. The connection pooling and call queueing is modeled after the ones used in that reliable workhorse, originally designed at Electronic Arts. They enable the Erlang driver to absorb access peaks, and to distribute load across VoltDB server nodes.
-To come up with a useful benchmark script I could employ the lessons learned from the Node.js benchmark I did for VoltDB a while ago, see http://blog.voltdb.com/695k-tps-nodejs-and-voltdb/. This time around I knew which numbers I would be looking for and what double checks I should have in place to put the cloud cluster to good use.
+To come up with a useful benchmark script I could employ the lessons learned from the Node.js benchmark [14] I did for VoltDB a while ago. This time around I knew which numbers I would be looking for and what double checks I should have in place to put the cloud cluster to good use.
-The internal structure of the driver has been implemented as would be expected: your application's microprocesses are made to send a message to a dedicated connection process that handles the socket work. After the request is sent, the initiating process is either blocked in a synchronous receive (this, of course, does not block all your other processes) or goes on to to use its time as it pleases, if you choose the asynchronous mode. The answer from the server arrives in your processes' mailbox. 
+The internal structure of the driver has been implemented as would be expected: your program's microprocesses use the functions the driver exposes to send a message to a dedicated connection process, which handles the socket work. After the request is sent, the initiating process is either blocked in a *synchronous* receive (this, of course, does *not* block all your *other* processes) or goes on to to use its time as it pleases, should you choose the *asynchronous* mode. The answer from the server arrives in your processes' mailbox.  (Note, *synchronous* in this context, when looking at the driver. The call to the VoltDB server is still an asynchronous call. The driver simply has your process wait in a receive block.)
-There are many options that you can use. E.g. the 'monitored' mode, where a worker process is created that handles the sending of the request, shielding your initiating process from any hiccups in the driver. You can 'fire and forget', for writes where you don't care to hear that they succeeded. Or 'blowout' if you don't even care to hear about failure.
+There are many options that you can use. E.g. the *monitored* mode, where a worker process is created that handles the sending of the request, thereby shielding your initiating process from any hiccups in the driver. You can *fire and forget*, for writes where you don't care to hear that they succeeded. Or *blowout* if you don't even care to hear about failure.
The Benchmark Application
-------------------------------------
-The benchmark is based on the VoltDB voter example, which comes with every VoltDB distribution. It 'validates and stores phoned-in votes for talent show contestants'. In the original example setup there is a web page that displays the results for illustration, updated every 400ms. You'll find it in the <VoltDB_Home>/examples/voter directory.
+The benchmark is based on the VoltDB voter example, which comes with every VoltDB distribution. It 'validates and stores phoned-in votes for talent show contestants'. In the original example setup, there is a web page that displays the results for illustration, updated every 400ms. You'll find it in the `examples/voter` directory of your *VoltDB* installation.
-The benchmark starts out with a preparational phase, where the database is filled with 6 contestants' names and then one million write transactions are fired towards the server, per CPU core, that each register a 'vote' for one of the contestant, picked at random. In the end, the votes won by each contestants are displayed, using a materialized view and a VoltDB ad-hoc query.
+The benchmark starts out with a preparational phase, where the database is filled with 6 contestants' names and then one million write transactions are fired towards the server, per CPU core, that each register a 'vote' for one of the contestants, picked at random. In the end, the votes won by each contestants are displayed, using a materialized view and a VoltDB ad-hoc query. (In VoltDB parlance, ad-hoc queries are normal queries that are not pre-formulated in a stored procedure.)
-The Erlang benchmark application that implements a Voter client is packaged with the driver, which can be downloaded here https://github.com/VoltDB/voltdb-client-erlang. The benchmark source is under etc/bench, where you'll also find a detailed README.md that explains how to build and deploy the application. For a (slow) test run on localhost, it's basically:
+The benchmark source is under etc/bench [15] of the *driver* home directory, where you'll also find a detailed README.md that explains the multiple ways to run the benchmark and make it fit your setup. For a (slow) test run on localhost, it's basically:
    $ git clone git://github.com/VoltDB/voltdb.git voltdb
    $ git clone git://github.com/VoltDB/voltdb-client-erlang.git erlvolt
    $ cd voltdb/examples/voter && ./run.sh &
-    $ cd && cd erlvolt && make bench
+    $ cd && cd erlvolt && make clean all bench
That should give you a screen like this:
- metal:~ hd$ cd voltdb/examples/voter && ./run.sh &
- [1] 62084
- metal:~ hd$ Initializing VoltDB...
-
- _    __      ____  ____  ____ 
- | |  / /___  / / /_/ __ \/ __ )
- | | / / __ \/ / __/ / / / __  |
- | |/ / /_/ / / /_/ /_/ / /_/ / 
- |___/\____/_/\__/_____/_____/
-
- --------------------------------
-
- WARN: Running 3.0 preview (iv2 mode). NOT SUPPORTED IN PRODUCTION.
- Build: 3.0 voltdb-3.0-beta2-110-g178a1e6 Community Edition
- Connecting to VoltDB cluster as the leader...
- Appointing HSId 0:0 as leader for partition 0
- Appointing HSId 0:1 as leader for partition 1
- MP 0:6 for partition 16383 finished leader promotion. Took 104 ms.
- WARN: Mailbox is not registered for site id -4
- Initializing initiator ID: 0, SiteID: 0:13
- WARN: Running without redundancy (k=0) is not recommended for production use.
- Server completed initialization.
-
- cd && cd ErlVolt2 && make bench
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_app.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_conn.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_conn_mgr.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_profiler.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_sup.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_wire.erl
- erlc -W -I ../../include  +native -smp  -o ../../ebin bench.erl
-
- Erlvolt Bench 0.9 (client 'VSD')
- -------------------------------------------------------------------------------------------------------------------------------------
- Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, 'n/a' stats/sec
- Hosts: localhost:21212 localhost:21212 
- connect ...
- preparation ...
- calls ... ........................................................................................................................................
- cool down ... 
- check writes ... ok
- results ...  votes:     100,000 (6 contestants)
- ....Jessie Alloway:      16,811
- ...Tabatha Gehling:      16,661
- ....Jessie Eichman:      16,643
- .....Alana Bregman:      16,634
- .....Edwina Burnam:      16,632
- ......Kelly Clauss:      16,619
- close pool ...
- Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, 'n/a' stats/sec
- -------------------------------------------------------------------------------------------------------------------------------------
- Client 'VSD' overall: 3,657 T/sec throughput, 0.00% fails, total transactions: 100,000, fails: 0, total time: 27.338sec 
- Erlvolt 0.3.0, bench started 2013-01-31 22:09:27, ended 2013-01-31 22:09:54, database: +100,000 new votes
- [+++]
- metal:ErlVolt2 hd$ 
-
-
-Instructions on how to use it in the cloud can be found in etc/bench/README.me.
+ metal:~ hd$ cd voltdb-3-com/examples/voter && ./run.sh &
+ [1] 10817
+ metal:~ hd$ Initializing VoltDB...
+
+ _ __ ____ ____ ____
+ | | / /___ / / /_/ __ \/ __ )
+ | | / / __ \/ / __/ / / / __ |
+ | |/ / /_/ / / /_/ /_/ / /_/ /
+ |___/\____/_/\__/_____/_____/
+
+ --------------------------------
+
+ Build: 3.0 voltdb-3.0-95-gfffab2b Community Edition
+ Connecting to VoltDB cluster as the leader...
+ Initializing initiator ID: 0, SiteID: 0:5
+ WARN: Running without redundancy (k=0) is not recommended for production use.
+ Server completed initialization.
+
+
+ metal:erlvolt hd$ cd && cd erlvolt && make clean all bench
+ clean
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_app.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_conn.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_conn_mgr.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_profiler.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_sup.erl
+ erlc -W -I ../include +debug_info -o ../ebin erlvolt_wire.erl
+ erlc -W -I ../../include +debug_info -o ../../ebin bench.erl
+
+
+ Erlvolt Bench 0.9 (client 'VSD')
+ -------------------------------------------------------------------------------------------------------------------------------------
+ Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, "n/a" stats/sec
+ Hosts: localhost:21212
+ connect ...
+ preparation ...
+ Start at: 2013-02-06 18:56:20 .....................
+ Starting: 2013-02-06 18:56:20
+ calls ... ..................................
+ cool down ...
+ check writes ... ok
+ results ... votes: 100,000 (6 contestants)
+ .....Edwina Burnam: 16,817
+ ....Jessie Alloway: 16,808
+ ...Tabatha Gehling: 16,669
+ .....Alana Bregman: 16,613
+ ....Jessie Eichman: 16,556
+ ......Kelly Clauss: 16,537
+ close pool ...
+ Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, "n/a" stats/sec
+ -------------------------------------------------------------------------------------------------------------------------------------
+
+ Client 'VSD' overall: 14,357 T/sec throughput, 0.00% fails, total transactions: 100,000, fails: 0, total time: 6.965sec
+ Erlvolt 0.3.3, bench started 2013-02-06 18:56:20, ended 2013-02-06 18:56:26, database: +100,000 new votes
+ [++++++++++++++]
+
+
+
+For further instructions, e.g. how to best run the benchmark in the cloud, please see etc/bench/README.md [16], or verbatim doc/BENCHMARK-README.html, in your driver home folder.
The Benchmark Results
--------------------------------
-Using 3 nodes connected to a 5 node VoltDB cluster, each client node executed an average of 70,600 TPS for a total of 212,000 TPS. Clients and server worked at only 40% load, so more tuning would probably have yielded higher results, on both client and server side. 
+When run on a single core (-smb +S 1), with a 12-node VoltDB server cluster listening on the other side, the Erlang driver showed throughput of **26,500 transactions per second (TPS) and more per one core**. When fully utilizing a 16-core cluster instance as client node, it routinely reached throughput of **260,000 transactions per second per machine**. (CPU specs see below.)
-Since this benchmark was about the driver, not the server, I made no attempts to tune the server cluster.
+Using 8 client nodes connected to a 12-node VoltDB cluster, each client node executed an average of 109,689 transactions per second for a **cluster total of 877,519 TPS**.
+
+Since this benchmark was about the driver, not the server, I made no attempts to tune the server cluster. After a lot of experimenting, I believe that the lower performance per client core for bigger server clusters would reflect the network limitations of the EC2 cloud, even for the bigger cluster instances [17] where the hope would be that a benchmark would not end up network-bound.
+
+Part of the goal for the benchmark was testing how the driver would hold up under load and that turned out very well. The driver does not crash from really heavy overload and it copes well with 'backpressure' [18] when the server does not allow further requests for being at capacity. However, the fastest benchmarks resulted when not overloading the server.
The Environment
-----------------------
-I created an 8-node Amazon EC2 m3.2xlarge cluster broken up into Erlang client and VoltDB server nodes. The m3.2xlarge provide the following, as described by the Amazon EC2 Instance Types page:
+I started a 20-node Amazon EC2 cc2.xlarge cluster broken up into 8 Erlang client and 12 VoltDB server nodes. The m3.2xlarge provide the following, as described by the Amazon EC2 Instance Types page [17]:
-### M3 Double Extra Large Instance
+### Cluster Compute Eight Extra Large Instance (cc2.8xlarge)
-* 30 GiB memory
-* 26 EC2 Compute Units (8 virtual cores with 3.25 EC2 Compute Units each)
-* 64-bit platform
-* I/O Performance: High
-* API name: m3.2xlarge
+ * 60.5 GiB of memory
+ * 88 EC2 Compute Units (2 x Intel Xeon E5-2670, eight-core)
+ * 3370 GB of instance storage
+ * 64-bit platform
+ * I/O Performance: Very High (10 Gigabit Ethernet)
These nodes were configured with:
* Ubuntu Server 12.04 LTS for Cluster Instances AMI
-* Oracle JDK 1.7
-* Erlang 15
+* Oracle Java JDK 1.7
+* Erlang R15B03
* VoltDB Enterprise Edition 3.0 RC
-Each of the five server nodes was set to six partitions, so I had 30 partitions across the cluster.
+On advice from VoltDB, each of the five server nodes was set to six partitions, so I had 30 partitions across the database cluster.
+
+This benchmark would perform the same on the free Community Edition of Volt 3.0.
The Transactions
-----------------------
-The clients "firehosed" the VoltDB cluster by calling Voter’s vote() stored procedure continuously. This procedure performed not merely one write but, depending on how you count, 4 to 6 operations:
+The clients "firehose" the VoltDB cluster by calling Voter's `vote()` stored procedure continuously. This procedure performes not only one write but, depending on how you count, 4 to 6 operations:
+
+* It retrieves the caller's location (a `select`)
+* Verifies that the caller has not exceeded his/her vote maximum (a `select`)
+* Verifies that the caller was voting for a valid contestant (a `select`)
+* And if yes to all of the above, a vote is cast on behalf of that caller (an `insert`)
+
+On top of this, each `insert` also triggers an update to two different materialized views.
-* Retrieve the caller’s location (select)
-* Verify that the caller had not exceeded his/her vote maximum (select)
-* Verify that the caller was voting for a valid contestant (select)
-* If yes to all of the above, a vote was cast on behalf of that caller (insert)
+Here are the actual queries that define the used stored procedures [19]:
-On top of this, each insert also triggered an update to two different materialized views.
+ // Checks if the vote is for a valid contestant
+ SELECT contestant_number FROM contestants WHERE contestant_number = ?;
+
+ // Checks if the voter has exceeded their allowed number of votes
+ SELECT num_votes FROM v_votes_by_phone_number WHERE phone_number = ?;
+
+ // Checks an area code to retrieve the corresponding state
+ SELECT state FROM area_code_state WHERE area_code = ?;
+
+ // Records a vote
+ INSERT INTO votes (phone_number, state, contestant_number) VALUES (?, ?, ?);
+
+Consequently, the 877,000 TPS performed **3.5 million SQL operations per second**, i.e. three selects and one insert.
-Consequently, the 212,000 TPS performed 848,000 SQL operations per second, i.e. three selects and one insert. 
Observations & Notes
-----------------------------
-The most important number from this, to my mind, is the pretty constant 9,000 transactions per second per CPU core that I saw. This will allow you to make rough estimates on the amount of hardware you may need on the business server side (the VoltDB 'client' side).
+The most important number from this, to my mind, is the **26,500 transactions per second per CPU core** that I saw, which translates into 100,000 operations. This will allow you to make rough estimates on the amount of hardware you may need on the business server side (the VoltDB client side). Your client will usually have more work to do than simply swamp the server, as the benchmark does. So you have an upper limit here and can feel your way down from there. Note that many machines will show a significantly higher performance profile than EC2 instances.
We decided for the Amazon Elastic Cloud for the benchmark in the hopes that this would result into the most transparent setup. A local cluster of eight "bare metal" nodes would certainly perform better than the EC2 instance, and be way more economic if you used them on a daily basis. But our throughput numbers would be hard to reproduce independently.
-As it is, you could try the exact same benchmark yourself, easily. VoltDB and the new driver can be downloaded from http://voltdb.com/community/downloads.php. The README.md of the driver has more instructions on how to use it. To find experimental new versions of the driver as well as fast bug fixes, try https://github.com/VoltDB/voltdb-client-erlang, and VoltDB is also on github, at https://github.com/VoltDB/voltdb.
-
-/hd 31 jan 13
+As it is, you could try the exact same benchmark yourself, easily. VoltDB and the new driver can be downloaded from VoltDB [20]. The README.md [21] of the driver, and of the benchmark [16] have more instructions on how to use the driver and how to make benchmarks. To find experimental new versions of the driver as well as fast bug fixes, try the Eonblast Erlvolt repo at git [22]. The free VoltDB community edition is also on github [23].
+
+[1] Author on Twitter: https://twitter.com/hdiedrich
+[2] Eonblast: http://www.eonblast.com
+[3] VoltDB: http://www.voltdb.com
+[4] Erlang: http://www.erlang.org
+[5] Deepolis: http://www.deepolis.com
+[6] Choosing the Best Database For a Game: http://voltdb.com/dig-deeper/webinars.php
+[7] Why Erlang? http://www.slideshare.net/eonblast/why-erlang-gdc-online-2012
+[8] Erlang and VoltDB: http://www.slideshare.net/eonblast/voltdb-and-erlang-tech-planet-2012
+[9] Erlvolt 0.2: https://github.com/Eonblast/Erlvolt/tree/01b304f8975c2168be105c1b9c972386264c0a4e
+[10] http://blog.voltdb.com/community-contributions-erlang-client-library/
+[11] Erlvolt 0.3: https://github.com/VoltDB/voltdb-client-erlang
+[12] VoltDB 3: http://blog.voltdb.com/introducing-voltdb-3-0/
+[13] Emysql: https://github.com/Eonblast/Emysql
+[14] 695k with Node.js: http://blog.voltdb.com/695k-tps-nodejs-and-voltdb/
+[15] bench.erl: https://github.com/VoltDB/voltdb-client-erlang/blob/master/etc/bench/bench.erl
+[16] Bench README: https://github.com/VoltDB/voltdb-client-erlang/blob/master/etc/bench
+[17] Amazon EC2 Cluster Instances: http://aws.amazon.com/ec2/instance-types/
+[18] Backpressure: http://voltdb.com/docs/UsingVoltDB/DesignAppLogic.php
+[19] Query Source: https://github.com/VoltDB/voltdb/blob/master/examples/voter/src/voter/procedures/Vote.java
+[20] VoltDB Downloads: VoltDB http://voltdb.com/community/downloads.php
+[21] Driver README: https://github.com/VoltDB/voltdb-client-erlang
+[22] Erlvolt Development: https://github.com/Eonblast/Erlvolt
+[23] VoltDB Community Edition: https://github.com/VoltDB/voltdb
+
+/hd 6 feb 13
View
173 doc/BENCHMARK2.html
@@ -1,173 +0,0 @@
-<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
-<html>
-<head>
- <meta http-equiv="content-type" content="text/html; charset=utf-8" />
- <title>VoltDB Blog: 877,000 TPS with Erlang and VoltDB </title>
- <link rel="stylesheet" type="text/css" href="default.css" />
-</head>
-<body>
-
-<h1>VoltDB Blog: 877,000 TPS with Erlang and VoltDB </h1>
-
-<p>Henning Diedrich - 4 Feb 2013</p>
-
-<p><strong>Running on a suitable EC2 configuration (see details below), with our new VoltDB Erlang driver we achieved 877,519 transactions per second.</strong></p>
-
-<p>I am Henning Diedrich, CEO of <a href="http://www.eonblast.com">Eonblast Corporation</a> a games company. I would like to introduce the new Erlang VoltDB driver we created, a piece of software that allows two genre-defining technologies to work together: VoltDB and Erlang.</p>
-
-<h2>The Driver</h2>
-
-<p>I first came to VoltDB on the hunt for a better database for heavy duty online-game servers. I experienced first hand what a pain it was to try to scale MySQL and found <strong>VoltDB</strong> uniquely suitable for the requirements of more complex game worlds. Better than any other database in fact.</p>
-
-<p>I had also looked for a better language than Java for programming servers and for that, <strong>Erlang</strong> had caught my attention. To be able to use them together, I started creating the Erlang driver for VoltDB.</p>
-
-<p>Work for this started three years ago and I donated a first version of the driver to VoltDB at their request in 2010. It was perfectly usable but out of the box only provided for synchronous connections. In 2012 VoltDB decided to sponsor the creation of a bigger and badder version. Now the real deal has arrived.</p>
-
-<p>The benchmark described below was made with the new, asynchronous driver. It is pure Erlang, full of parallel microprocesses, blazingly fast and fit for VoltDB 3. It incorporates almost all of the previous, robust driver version. And on my quest to ensure reliable, consistently high throughput, I was able to draw from my experience maintaining an Erlang <strong>MySQL</strong> driver, Emysql. The connection pooling and call queueing is modeled after the ones used in this reliable workhorse, which was originally designed at Electronic Arts. They enable the Erlang driver to absorb access peaks, and to distribute load across VoltDB server nodes.</p>
-
-<p>To come up with a useful benchmark script I could employ the lessons learned from the Node.js benchmark I did for VoltDB a while ago, see http://blog.voltdb.com/695k-tps-nodejs-and-voltdb/. This time around I knew which numbers I would be looking for and what double checks I should have in place to put the cloud cluster to good use.</p>
-
-<p>The internal structure of the driver has been implemented as would be expected: your program's microprocesses use the functions the driver exposes to send a message to a dedicated connection process, which handles the socket work. After the request is sent, the initiating process is either blocked in a <em>synchronous</em> receive (this, of course, does <em>not</em> block all your <em>other</em> processes) or goes on to to use its time as it pleases, should you choose the <em>asynchronous</em> mode. The answer from the server arrives in your processes' mailbox. </p>
-
-<p>There are many options that you can use. E.g. the 'monitored' mode, where a worker process is created that handles the sending of the request, thereby shielding your initiating process from any hiccups in the driver. You can <em>fire and forget</em>, for writes where you don't care to hear that they succeeded. Or <em>blowout</em> if you don't even care to hear about failure.</p>
-
-<h2>The Benchmark Application</h2>
-
-<p>The benchmark is based on the VoltDB voter example, which comes with every VoltDB distribution. It 'validates and stores phoned-in votes for talent show contestants'. In the original example setup, there is a web page that displays the results for illustration, updated every 400ms. You'll find it in the <code>examples/voter</code> directory of your <em>VoltDB</em> installation.</p>
-
-<p>The benchmark starts out with a preparational phase, where the database is filled with 6 contestants' names and then one million write transactions are fired towards the server, per CPU core, that each register a 'vote' for one of the contestant, picked at random. In the end, the votes won by each contestants are displayed, using a materialized view and a VoltDB ad-hoc query.</p>
-
-<p>The benchmark source is under etc/bench of the <em>driver</em> home directory, where you'll also find a detailed README.md that explains the multiple was to run the benchmark and make it fit your setup. For a (slow) test run on localhost, it's basically:</p>
-
-<p>    $ git clone git://github.com/VoltDB/voltdb.git voltdb
-    $ git clone git://github.com/VoltDB/voltdb-client-erlang.git erlvolt
-    $ cd voltdb/examples/voter &amp;&amp; ./run.sh &amp;
-    $ cd &amp;&amp; cd erlvolt &amp;&amp; make bench</p>
-
-<p>That should give you a screen like this:</p>
-
-<pre><code> metal:~ hd$ cd voltdb/examples/voter &amp;&amp; ./run.sh &amp;
- [1] 62084
- metal:~ hd$ Initializing VoltDB...
-
- _    __      ____  ____  ____ 
- | |  / /___  / / /_/ __ \/ __ )
- | | / / __ \/ / __/ / / / __  |
- | |/ / /_/ / / /_/ /_/ / /_/ / 
- |___/\____/_/\__/_____/_____/
-
- --------------------------------
-
- WARN: Running 3.0 preview (iv2 mode). NOT SUPPORTED IN PRODUCTION.
- Build: 3.0 voltdb-3.0-beta2-110-g178a1e6 Community Edition
- Connecting to VoltDB cluster as the leader...
- Appointing HSId 0:0 as leader for partition 0
- Appointing HSId 0:1 as leader for partition 1
- MP 0:6 for partition 16383 finished leader promotion. Took 104 ms.
- WARN: Mailbox is not registered for site id -4
- Initializing initiator ID: 0, SiteID: 0:13
- WARN: Running without redundancy (k=0) is not recommended for production use.
- Server completed initialization.
-
- cd &amp;&amp; cd ErlVolt2 &amp;&amp; make bench
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_app.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_conn.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_conn_mgr.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_profiler.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_sup.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_wire.erl
- erlc -W -I ../../include  +native -smp  -o ../../ebin bench.erl
-
- Erlvolt Bench 0.9 (client 'VSD')
- -------------------------------------------------------------------------------------------------------------------------------------
- Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, 'n/a' stats/sec
- Hosts: localhost:21212 localhost:21212 
- connect ...
- preparation ...
- calls ... ........................................................................................................................................
- cool down ... 
- check writes ... ok
- results ...  votes:     100,000 (6 contestants)
- ....Jessie Alloway:      16,811
- ...Tabatha Gehling:      16,661
- ....Jessie Eichman:      16,643
- .....Alana Bregman:      16,634
- .....Edwina Burnam:      16,632
- ......Kelly Clauss:      16,619
- close pool ...
- Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, 'n/a' stats/sec
- -------------------------------------------------------------------------------------------------------------------------------------
- Client 'VSD' overall: 3,657 T/sec throughput, 0.00% fails, total transactions: 100,000, fails: 0, total time: 27.338sec 
- Erlvolt 0.3.0, bench started 2013-01-31 22:09:27, ended 2013-01-31 22:09:54, database: +100,000 new votes
- [+++]
- metal:ErlVolt2 hd$ 
-</code></pre>
-
-
-<p>For further instructions, e.g. how to best run the benchmark in the cloud, please see etc/bench/README.me, or verbatim doc/BENCHMARK-README.html, in your driver home folder.</p>
-
-
-<h2>The Benchmark Results</h2>
-
-<p>When run on a single core (-smb +S 1), with a 12-node VoltDB server cluster listening on the other side, the Erlang driver showed throughput of 26,500 transactions per second (TPS) and more. When fully utilizing a 16-core cluster instance as client node, it routinely reached throughput of 260,000 TPS.</p>
-
-<p>Using 8 client nodes connected to a 12-node VoltDB cluster, each client node executed an average of 109,689 transactions per second for a total of 877,519 TPS.</p>
-
-<p>Since this benchmark was about the driver, not the server, I made no attempts to tune the server cluster. After a lot of experimenting, I believe that the lower performance per client core for bigger server clusters, would reflect the network limitations of the EC2 cloud, even for cluster instance where the hope would be that a benchmark would not end up network-bound.</p>
-
-<p>Part of the goal for the benchmark was testing how the driver would hold up under load and that turned out very well. The driver does not crash from really heavy overload and it copes well with 'backpressure' when the server does not allow further requests for being at capacity. However, the fastest benchmarks result when not overloading the server.</p>
-
-
-<h2>The Environment</h2>
-
-<p>I started a 20-node Amazon EC2 cc2.xlarge cluster broken up into 8 Erlang client and 12 VoltDB server nodes. The m3.2xlarge provide the following, as described by the Amazon EC2 Instance Types page:</p>
-
-<h3>M3 Double Extra Large Instance</h3>
-
-<ul>
- <li>30 GiB memory</li>
- <li>26 EC2 Compute Units (8 virtual cores with 3.25 EC2 Compute Units each)</li>
- <li>64-bit platform</li>
- <li>I/O Performance: High</li>
- <li>API name: m3.2xlarge</li>
-</ul>
-
-<p>These nodes were configured with:</p>
-
-<ul>
- <li>Ubuntu Server 12.04 LTS for Cluster Instances AMI</li>
- <li>Oracle JDK 1.7</li>
- <li>Erlang 15</li>
- <li>VoltDB Enterprise Edition 3.0 RC</li>
-</ul>
-
-<p>Each of the five server nodes was set to six partitions, so I had 30 partitions across the cluster.</p>
-
-
-<h2>The Transactions</h2>
-
-<p>The clients "firehose" the VoltDB cluster by calling Voter's <code>vote()</code> stored procedure continuously. This procedure performes not only one write but, depending on how you count, 4 to 6 operations:</p>
-
-<ul>
- <li>It retrieves the caller's location (a select)</li>
- <li>Verifies that the caller has not exceeded his/her vote maximum (a select)</li>
- <li>Verifies that the caller was voting for a valid contestant (a select)</li>
- <li>And if yes to all of the above, a vote is cast on behalf of that caller (an insert)</li>
-</ul>
-
-<p>On top of this, each insert also triggers an update to two different materialized views.</p>
-
-<p>Consequently, the 877,000 TPS performed 3.5 million SQL operations per second, i.e. three selects and one insert. </p>
-
-<h2>Observations &amp; Notes</h2>
-
-<p>The most important number from this, to my mind, is the 26,500 transactions per second per CPU core that I saw. This will allow you to make rough estimates on the amount of hardware you may need on the business server side (the VoltDB 'client' side). Your client will usually have more work to do than simply swamp the server, as the benchmark does. So you have an upper limit here and can feel your way down from there.</p>
-
-<p>We decided for the Amazon Elastic Cloud for the benchmark in the hopes that this would result into the most transparent setup. A local cluster of eight "bare metal" nodes would certainly perform better than the EC2 instance, and be way more economic if you used them on a daily basis. But our throughput numbers would be hard to reproduce independently.</p>
-
-<p>As it is, you could try the exact same benchmark yourself, easily. VoltDB and the new driver can be downloaded from http://voltdb.com/community/downloads.php. The README.md of the driver, and its etc/bench/README.md have more instructions on how to use the driver and how to make benchmarks. To find experimental new versions of the driver as well as fast bug fixes, try https://github.com/VoltDB/voltdb-client-erlang. The VoltDB community edition is also on github, at https://github.com/VoltDB/voltdb.</p>
-
-<p>/hd 4 feb 13</p>
-
-</body></html>
View
162 doc/BENCHMARK2.md
@@ -1,162 +0,0 @@
-VoltDB Blog: 877,000 TPS with Erlang and VoltDB 
-===============================================
-
-Henning Diedrich - 4 Feb 2013
-
-**Running on a suitable EC2 configuration (see details below), with our new VoltDB Erlang driver we achieved 877,519 transactions per second.**
-
-I am Henning Diedrich, CEO of [Eonblast Corporation](http://www.eonblast.com) a games company. I would like to introduce the new Erlang VoltDB driver we created, a piece of software that allows two genre-defining technologies to work together: VoltDB and Erlang.
-
-The Driver
---------------
-
-I first came to VoltDB on the hunt for a better database for heavy duty online-game servers. I experienced first hand what a pain it was to try to scale MySQL and found **VoltDB** uniquely suitable for the requirements of more complex game worlds. Better than any other database in fact.
-
-I had also looked for a better language than Java for programming servers and for that, **Erlang** had caught my attention. To be able to use them together, I started creating the Erlang driver for VoltDB.
-
-Work for this started three years ago and I donated a first version of the driver to VoltDB at their request in 2010. It was perfectly usable but out of the box only provided for synchronous connections. In 2012 VoltDB decided to sponsor the creation of a bigger and badder version. Now the real deal has arrived.
-
-The benchmark described below was made with the new, asynchronous driver. It is pure Erlang, full of parallel microprocesses, blazingly fast and fit for VoltDB 3. It incorporates almost all of the previous, robust driver version. And on my quest to ensure reliable, consistently high throughput, I was able to draw from my experience maintaining an Erlang **MySQL** driver, Emysql. The connection pooling and call queueing is modeled after the ones used in this reliable workhorse, which was originally designed at Electronic Arts. They enable the Erlang driver to absorb access peaks, and to distribute load across VoltDB server nodes.
-
-To come up with a useful benchmark script I could employ the lessons learned from the Node.js benchmark I did for VoltDB a while ago, see http://blog.voltdb.com/695k-tps-nodejs-and-voltdb/. This time around I knew which numbers I would be looking for and what double checks I should have in place to put the cloud cluster to good use.
-
-The internal structure of the driver has been implemented as would be expected: your program's microprocesses use the functions the driver exposes to send a message to a dedicated connection process, which handles the socket work. After the request is sent, the initiating process is either blocked in a *synchronous* receive (this, of course, does *not* block all your *other* processes) or goes on to to use its time as it pleases, should you choose the *asynchronous* mode. The answer from the server arrives in your processes' mailbox. 
-
-There are many options that you can use. E.g. the 'monitored' mode, where a worker process is created that handles the sending of the request, thereby shielding your initiating process from any hiccups in the driver. You can *fire and forget*, for writes where you don't care to hear that they succeeded. Or *blowout* if you don't even care to hear about failure.
-
-The Benchmark Application
--------------------------------------
-
-The benchmark is based on the VoltDB voter example, which comes with every VoltDB distribution. It 'validates and stores phoned-in votes for talent show contestants'. In the original example setup, there is a web page that displays the results for illustration, updated every 400ms. You'll find it in the `examples/voter` directory of your *VoltDB* installation.
-
-The benchmark starts out with a preparational phase, where the database is filled with 6 contestants' names and then one million write transactions are fired towards the server, per CPU core, that each register a 'vote' for one of the contestant, picked at random. In the end, the votes won by each contestants are displayed, using a materialized view and a VoltDB ad-hoc query.
-
-The benchmark source is under etc/bench of the *driver* home directory, where you'll also find a detailed README.md that explains the multiple was to run the benchmark and make it fit your setup. For a (slow) test run on localhost, it's basically:
-
-    $ git clone git://github.com/VoltDB/voltdb.git voltdb
-    $ git clone git://github.com/VoltDB/voltdb-client-erlang.git erlvolt
-    $ cd voltdb/examples/voter && ./run.sh &
-    $ cd && cd erlvolt && make bench
-
-That should give you a screen like this:
-
- metal:~ hd$ cd voltdb/examples/voter && ./run.sh &
- [1] 62084
- metal:~ hd$ Initializing VoltDB...
-
- _    __      ____  ____  ____ 
- | |  / /___  / / /_/ __ \/ __ )
- | | / / __ \/ / __/ / / / __  |
- | |/ / /_/ / / /_/ /_/ / /_/ / 
- |___/\____/_/\__/_____/_____/
-
- --------------------------------
-
- WARN: Running 3.0 preview (iv2 mode). NOT SUPPORTED IN PRODUCTION.
- Build: 3.0 voltdb-3.0-beta2-110-g178a1e6 Community Edition
- Connecting to VoltDB cluster as the leader...
- Appointing HSId 0:0 as leader for partition 0
- Appointing HSId 0:1 as leader for partition 1
- MP 0:6 for partition 16383 finished leader promotion. Took 104 ms.
- WARN: Mailbox is not registered for site id -4
- Initializing initiator ID: 0, SiteID: 0:13
- WARN: Running without redundancy (k=0) is not recommended for production use.
- Server completed initialization.
-
- cd && cd ErlVolt2 && make bench
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_app.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_conn.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_conn_mgr.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_profiler.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_sup.erl
- erlc -W -I ../include  +native -smp  -o ../ebin erlvolt_wire.erl
- erlc -W -I ../../include  +native -smp  -o ../../ebin bench.erl
-
- Erlvolt Bench 0.9 (client 'VSD')
- -------------------------------------------------------------------------------------------------------------------------------------
- Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, 'n/a' stats/sec
- Hosts: localhost:21212 localhost:21212 
- connect ...
- preparation ...
- calls ... ........................................................................................................................................
- cool down ... 
- check writes ... ok
- results ...  votes:     100,000 (6 contestants)
- ....Jessie Alloway:      16,811
- ...Tabatha Gehling:      16,661
- ....Jessie Eichman:      16,643
- .....Alana Bregman:      16,634
- .....Edwina Burnam:      16,632
- ......Kelly Clauss:      16,619
- close pool ...
- Client 'VSD', voter, 100,000 calls, steady, 200 workers, delay n/a, direct, queue n/a, slots n/a, limit n/a, verbose, 'n/a' stats/sec
- -------------------------------------------------------------------------------------------------------------------------------------
- Client 'VSD' overall: 3,657 T/sec throughput, 0.00% fails, total transactions: 100,000, fails: 0, total time: 27.338sec 
- Erlvolt 0.3.0, bench started 2013-01-31 22:09:27, ended 2013-01-31 22:09:54, database: +100,000 new votes
- [+++]
- metal:ErlVolt2 hd$ 
-
-
-For further instructions, e.g. how to best run the benchmark in the cloud, please see etc/bench/README.me, or verbatim doc/BENCHMARK-README.html, in your driver home folder.
-
-
-The Benchmark Results
---------------------------------
-
-When run on a single core (-smb +S 1), with a 12-node VoltDB server cluster listening on the other side, the Erlang driver showed throughput of 26,500 transactions per second (TPS) and more. When fully utilizing a 16-core cluster instance as client node, it routinely reached throughput of 260,000 TPS.
-
-Using 8 client nodes connected to a 12-node VoltDB cluster, each client node executed an average of 109,689 transactions per second for a total of 877,519 TPS.
-
-Since this benchmark was about the driver, not the server, I made no attempts to tune the server cluster. After a lot of experimenting, I believe that the lower performance per client core for bigger server clusters, would reflect the network limitations of the EC2 cloud, even for cluster instance where the hope would be that a benchmark would not end up network-bound.
-
-Part of the goal for the benchmark was testing how the driver would hold up under load and that turned out very well. The driver does not crash from really heavy overload and it copes well with 'backpressure' when the server does not allow further requests for being at capacity. However, the fastest benchmarks result when not overloading the server.
-
-
-The Environment
------------------------
-
-I started a 20-node Amazon EC2 cc2.xlarge cluster broken up into 8 Erlang client and 12 VoltDB server nodes. The m3.2xlarge provide the following, as described by the Amazon EC2 Instance Types page:
-
-### M3 Double Extra Large Instance
-
-* 30 GiB memory
-* 26 EC2 Compute Units (8 virtual cores with 3.25 EC2 Compute Units each)
-* 64-bit platform
-* I/O Performance: High
-* API name: m3.2xlarge
-
-These nodes were configured with:
-
-* Ubuntu Server 12.04 LTS for Cluster Instances AMI
-* Oracle JDK 1.7
-* Erlang 15
-* VoltDB Enterprise Edition 3.0 RC
-
-Each of the five server nodes was set to six partitions, so I had 30 partitions across the cluster.
-
-
-The Transactions
------------------------
-
-The clients "firehose" the VoltDB cluster by calling Voter's `vote()` stored procedure continuously. This procedure performes not only one write but, depending on how you count, 4 to 6 operations:
-
-* It retrieves the caller's location (a select)
-* Verifies that the caller has not exceeded his/her vote maximum (a select)
-* Verifies that the caller was voting for a valid contestant (a select)
-* And if yes to all of the above, a vote is cast on behalf of that caller (an insert)
-
-On top of this, each insert also triggers an update to two different materialized views.
-
-Consequently, the 877,000 TPS performed 3.5 million SQL operations per second, i.e. three selects and one insert. 
-
-Observations & Notes
------------------------------
-
-The most important number from this, to my mind, is the 26,500 transactions per second per CPU core that I saw. This will allow you to make rough estimates on the amount of hardware you may need on the business server side (the VoltDB 'client' side). Your client will usually have more work to do than simply swamp the server, as the benchmark does. So you have an upper limit here and can feel your way down from there.
-
-We decided for the Amazon Elastic Cloud for the benchmark in the hopes that this would result into the most transparent setup. A local cluster of eight "bare metal" nodes would certainly perform better than the EC2 instance, and be way more economic if you used them on a daily basis. But our throughput numbers would be hard to reproduce independently.
-
-As it is, you could try the exact same benchmark yourself, easily. VoltDB and the new driver can be downloaded from http://voltdb.com/community/downloads.php. The README.md of the driver, and its etc/bench/README.md have more instructions on how to use the driver and how to make benchmarks. To find experimental new versions of the driver as well as fast bug fixes, try https://github.com/VoltDB/voltdb-client-erlang. The VoltDB community edition is also on github, at https://github.com/VoltDB/voltdb.
-
-/hd 4 feb 13
View
92 doc/CHANGES.html
@@ -9,18 +9,90 @@
<h1>Changes</h1>
-<p><strong>Release: 'Erlvolt 0.3.1/beta'</strong> <br/>
-<strong>Author: H. Diedrich</strong> <br/>
-<strong>Production: Eonblast Corporation</strong> <br/>
-<strong>Copyright: (c) 2013 VoltDB, Inc</strong> <br/>
-<strong>Licence: MIT</strong> <br/>
-<strong>Date: Feb 02 2013</strong> </p>
+<p><strong>Release: 'Erlvolt 0.3.3'</strong>
+<strong>Author: H. Diedrich</strong>
+<strong>Production: Eonblast Corporation</strong>
+<strong>Copyright: (c) 2013 VoltDB, Inc</strong>
+<strong>Licence: MIT</strong>
+<strong>Date: Feb 11 2013</strong></p>
+<p>0.3.3 11 Feb 2013 hd</p>
-<h2>Erlvolt 0.3 </h2>
-<p>* Asynchronous driver </p>
+<pre><code> * Compatibility
+ * Ease of Build
-<h2>Erlvolt 0.1 </h2>
-<p>* Synchronous driver </p>
+ + add: R16 compatibility
+ + add: VoltDB 3 samples compatibility
+ + fix: make dialyzer
+ + add: make make-test
+ + fix: empty table catch
+ + fix: status value
+ + fix: parallel.erl sample
+ + alt: cleanup
+</code></pre>
+<p>0.3.02 03 Feb 2013 hd</p>
+
+<pre><code> * Asynchronous Release
+ * 877k Benchmark version
+ * Major extensions
+
+ + add: asynchronous procedure calls
+ + add: call queue manager
+ + add: monitored mode
+ + add: benchmarks
+ + add: new samples
+ + add: new unit tests
+ + add: dialyzer checked
+ + add: optional profiler
+ + add: minute call options
+ + add: more documentation
+</code></pre>
+
+<p>0.3.01 08 Jul 2012 hd</p>
+
+<pre><code> + add: auth response codes and output in login()
+ + fix: tiny int array element count encoding
+ + add: service name as parameter instead of hard coded string
+ + add: updated comment for roundtrip time value in invocation response
+ + alt: reworked Makefile for tests
+</code></pre>
+
+<p>0.3.00 07 Jul 2012 hd</p>
+
+<pre><code> + add: Makefiles
+ + alt: dir structure, moved tests into test/, erlunit stripped to etc/
+ + add: fixed error/1,2 ambiguity in erlunit
+</code></pre>
+
+<p>0.2.01 15 Jun 2010 hd</p>
+
+<pre><code> + add: extensive tests for callback id list (test3.erl)
+ + alt: changes in heads and body of callProcedure, now w/callback
+ + ext: connection record replaces socket-only parameter
+ + add: close(Connection) added, and added to all samples.
+</code></pre>
+
+<p>0.1.03 11 Jun 2010 hd</p>
+
+<pre><code> + ext: default encoding of array, (binary) string and integer parameters
+ + alt: default parameter encoding attempt of any type as string dropped
+ + add: more parameter conversion tests
+</code></pre>
+
+<p>0.1.02 11 Jun 2010 hd</p>
+
+<pre><code> + fix: timestamps now interpreted as microseconds (thx Ning)
+ + License tags now termed precisely as they should
+</code></pre>
+
+<p>0.1.01 11 Jun 2010 hd</p>
+
+<pre><code> + Minor changes
+</code></pre>
+
+<p>0.1 11 Jun 2010 hd</p>
+
+<pre><code> * First public release
+</code></pre>
</body></html>
View
86 doc/CHANGES.md
@@ -1,18 +1,80 @@
Changes
=======
-**Release: 'Erlvolt 0.3.1/beta'**
-**Author: H. Diedrich**
-**Production: Eonblast Corporation**
-**Copyright: (c) 2013 VoltDB, Inc**
-**Licence: MIT**
-**Date: Feb 02 2013**
+**Release: 'Erlvolt 0.3.3'**
+**Author: H. Diedrich**
+**Production: Eonblast Corporation**
+**Copyright: (c) 2013 VoltDB, Inc**
+**Licence: MIT**
+**Date: Feb 11 2013**
+0.3.3 11 Feb 2013 hd
-Erlvolt 0.3
------------
-* Asynchronous driver
+ * Compatibility
+ * Ease of Build
-Erlvolt 0.1
------------
-* Synchronous driver
+ + add: R16 compatibility
+ + add: VoltDB 3 samples compatibility
+ + fix: make dialyzer
+ + add: make make-test
+ + fix: empty table catch
+ + fix: status value
+ + fix: parallel.erl sample
+ + alt: cleanup
+
+0.3.02 03 Feb 2013 hd
+
+ * Asynchronous Release
+ * 877k Benchmark version
+ * Major extensions
+
+ + add: asynchronous procedure calls
+ + add: call queue manager
+ + add: monitored mode
+ + add: benchmarks
+ + add: new samples
+ + add: new unit tests
+ + add: dialyzer checked
+ + add: optional profiler
+ + add: minute call options
+ + add: more documentation
+
+0.3.01 08 Jul 2012 hd
+
+ + add: auth response codes and output in login()
+ + fix: tiny int array element count encoding
+ + add: service name as parameter instead of hard coded string
+ + add: updated comment for roundtrip time value in invocation response
+ + alt: reworked Makefile for tests
+
+0.3.00 07 Jul 2012 hd
+
+ + add: Makefiles
+ + alt: dir structure, moved tests into test/, erlunit stripped to etc/
+ + add: fixed error/1,2 ambiguity in erlunit
+
+0.2.01 15 Jun 2010 hd
+
+ + add: extensive tests for callback id list (test3.erl)
+ + alt: changes in heads and body of callProcedure, now w/callback
+ + ext: connection record replaces socket-only parameter
+ + add: close(Connection) added, and added to all samples.
+
+0.1.03 11 Jun 2010 hd
+
+ + ext: default encoding of array, (binary) string and integer parameters
+ + alt: default parameter encoding attempt of any type as string dropped
+ + add: more parameter conversion tests
+
+0.1.02 11 Jun 2010 hd
+
+ + fix: timestamps now interpreted as microseconds (thx Ning)
+ + License tags now termed precisely as they should
+
+0.1.01 11 Jun 2010 hd
+
+ + Minor changes
+
+0.1 11 Jun 2010 hd
+
+ * First public release
View
1  etc/bench/Makefile
@@ -3,6 +3,7 @@ EBIN_DIR := ../../ebin
include ../../etc/include.mk
all: $(EBIN_DIR)/bench.beam
+ @:
%.beam: %.erl
$(ERLC) $(ERLC_FLAGS) -o $(EBIN_DIR) $<
View
10 etc/bench/README.html
@@ -9,14 +9,14 @@
<h1>Benchmarks</h1>
-<p><strong>voltdb-client-erlang Erlvolt 0.3.0</strong></p>
+<p><strong>voltdb-client-erlang Erlvolt 0.3</strong> </p>
-<p><strong>Release: 'Erlvolt 0.3.0'</strong> <br/>
+<p><strong>Release: 'Erlvolt 0.3.2'</strong> <br/>
<strong>Author: H. Diedrich</strong> <br/>
<strong>Production: Eonblast Corporation</strong> <br/>
<strong>Copyright: (c) 2013 VoltDB, Inc</strong> <br/>
<strong>Licence: MIT</strong> <br/>
-<strong>Date: Jan 31 2013</strong></p>
+<strong>Date: 31 Jan 2013</strong></p>
<h2>Quick Start</h2>
@@ -30,7 +30,7 @@
<h2>Quick Read</h2>
-<p>For reference benchmarks done in the EC2 cloud, see doc/BENCHMARKS.md or html.</p>
+<p>For a reference benchmark done in the EC2 cloud, see doc/BENCHMARK1.md or html.</p>
<h2>Usage</h2>
@@ -380,5 +380,5 @@
<hr/>
-<p>/hd 3 feb 13</p>
+<p>/hd 31 jan 13</p>
</body></html>
View
10 etc/bench/README.md
@@ -1,14 +1,14 @@
Benchmarks
==========
-**voltdb-client-erlang Erlvolt 0.3.0**
+**voltdb-client-erlang Erlvolt 0.3**
-**Release: 'Erlvolt 0.3.0'**
+**Release: 'Erlvolt 0.3.2'**
**Author: H. Diedrich**
**Production: Eonblast Corporation**
**Copyright: (c) 2013 VoltDB, Inc**
**Licence: MIT**
-**Date: Jan 31 2013**
+**Date: 31 Jan 2013**
Quick Start
@@ -23,7 +23,7 @@ Start the Voter database and run a benchmark client on local host:
Quick Read
----------
-For reference benchmarks done in the EC2 cloud, see doc/BENCHMARKS.md or html.
+For a reference benchmark done in the EC2 cloud, see doc/BENCHMARK1.md or html.
Usage
-----
@@ -360,4 +360,4 @@ online: http://voltdb.com/downloads/documentation/GettingStarted.pdf.
-------------------------------------------------------------------------
-/hd 3 feb 13
+/hd 31 jan 13
View
17 etc/bench/bench.erl
@@ -267,7 +267,7 @@
prep_hello/1, call_hello/5, done_hello/2,
prep_voter/1, call_voter/5, done_voter/2,
voter_return_text/1]).
--import(erlvolt).
+
-include("erlvolt.hrl").
-author("H. Diedrich <hd2010@eonblast.com>").
@@ -368,7 +368,7 @@ start_delay_loop(T0,I,Verbosity) ->
client(ClientID, Bench, Prep, Call, Done, Mode, Rhythm, AVerbosity, Verbosity, DumpInterval, CallTarget, BurstSize, Delay, Slots, QueueSize, WaitTarget) ->
- DumpFrequency = case ?ERLVOLT_PROFILER_DUMP_FUNCTION of dummy -> 'n/a'; _ -> 1000 / DumpInterval end,
+ DumpFrequency = dump_frequency(DumpInterval),
Bursts = trunc(CallTarget / BurstSize),
BurstSizeUse = case Rhythm of steady -> workers; bursts -> bursts end,
@@ -548,7 +548,7 @@ client(ClientID, Bench, Prep, Call, Done, Mode, Rhythm, AVerbosity, Verbosity, D
catch
throw:{ open_failed, _, _}=Why ->
io:format("Failed to open server connection.~nIs the VoltDB server running and accessible?"),
- io:format("Error details: ~n ~w ~w ~n ~p", [throw, Why, erlang:get_stack()]),
+ io:format("Error details: ~n ~w ~w ~n ~p", [throw, Why, erlang:get_stacktrace()]),
exit({throw, Why})
end.
@@ -586,6 +586,15 @@ receipts(Calls,Oks,Fails) ->
exit(client_receive_timeout)
end.
+-ifdef(profile).
+dump_frequency(DumpInterval) ->
+ 1000 / DumpInterval.
+-else.
+dump_frequency(_) ->
+ "n/a".
+-endif.
+
+
%%%----------------------------------------------------------------------------
%%% Log to Screen
%%%----------------------------------------------------------------------------
@@ -862,7 +871,7 @@ print_time(Prompt, Time, Append, VerbositySetting, VerbosityThreshold) when Verb
io:format(Prompt ++ "~4..0B-~2..0B-~2..0B ~2..0B:~2..0B:~2..0B" ++ Append, [Y,M,D,H,I,S]);
print_time(_,_,_,_,_) ->
-
+
ok.
human_time(Now) ->
View
10 etc/test/depr/Makefile
@@ -0,0 +1,10 @@
+include ../etc/include.mk
+
+all: $(EBIN_FILES)
+
+debug:
+ $(MAKE) DEBUG=-DDEBUG
+
+clean:
+ @rm -rf $(EBIN_FILES)
+
View
1,482 etc/test/depr/erlunit/erlunit.erl
@@ -0,0 +1,1482 @@
+%%%----------------------------------------------------------------------------
+%%% File : erlunit.erl
+%%% Description : Test functions - import this file and use its functions.
+%%% Version : 0.2.8.2/alpha
+%%% Status : alpha
+%%% Copyright : (c) 2010 Eonblast Corporation http://www.eonblast.com
+%%% License : MIT - see below
+%%% Author : H. Diedrich <hd2010@eonblast.com>
+%%% Created : 18 Apr 2010
+%%% Changed : 15 May 2010 - see CHANGES
+%%% Tested on : Erlang R13B01
+%%%----------------------------------------------------------------------------
+%%%
+%%% This Module contains test functions to test other modules.
+%%%
+%%% Usage, see sample.erl. Basically -
+%%%
+%%% either: or: or:
+%%% erlunit:start() | Test = erlunit:start(), | erlunit:start()
+%%% erlunit:equal(1, 1), | Test ! { equal, 1, 1 }, | ?ERLUNIT_EQUAL(1,1),
+%%% ... | ... | ...
+%%% erlunit:execute(). | erlunit:execute(). | erlunit:execute().
+%%%
+%%% There are also suites, names for tests and concurrent execution.
+%%%
+%%%----------------------------------------------------------------------------
+%%%
+%%% Start source inspection in sample.erl.
+%%%
+%%% There are Erlang masters on erlang-questions, this here source is
+%%% not written by one. Beware of copying mistakes if you are learning.
+%%% There may be a slight advantage to that, the code is kind of plain.
+%%%
+%%% Mail to hd2010@eonblast.com with questions and suggestions, I will
+%%% be quite happy to answer. - Henning
+%%%
+%%% This bit is dedicated to Joe, who had me smile now and then reading
+%%% his book Programming Erlang. Thanks, Joe! You are the man.
+%%%
+%%% Thanks to Stefan Marr, Fred Hebert and Richard O'Keefe.
+%%%
+%%%----------------------------------------------------------------------------
+%
+% Copyright (c) 2010 Eonblast Corporation http://www.eonblast.com
+%
+% Permission is hereby granted, free of charge, to any person obtaining a copy
+% of this software and associated documentation files (the "Software"), to deal
+% in the Software without restriction, including without limitation the rights
+% to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+% copies of the Software, and to permit persons to whom the Software is
+% furnished to do so, subject to the following conditions:
+%
+% The above copyright notice, including link, and this permission notice shall
+% be included in all copies or substantial portions of the Software.
+%
+% THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+% IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+% FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+% AUTHORS OR COPYRIGHT HOLDER BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+% LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+% OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+% THE SOFTWARE.
+%
+%%%----------------------------------------------------------------------------
+
+-module(erlunit).
+-vsn("0.2.8.2/alpha").
+-author("H. Diedrich <hd2010@eonblast.com>").
+-license("MIT - http://www.opensource.org/licenses/mit-license.php").
+-copyright("(c) 2010 Eonblast Corporation http://www.eonblast.com").
+
+%%%----------------------------------------------------------------------------
+
+-export([start/0, start/1, execute/0, stats/2]).
+-export([suite/1, suite/2]).
+-export([true/1, not_true/1, false/1, not_false/1, pass/1, fail/1]).
+-export([true/2, not_true/2, false/2, not_false/2, pass/2, fail/2]).
+-export([true/3, not_true/3, false/3, not_false/3, pass/3, fail/3]).
+-export([true/4, not_true/4, false/4, not_false/4, pass/4, fail/4]).
+-export([exits/1, throws/1, error/1]).
+-export([exits/2, throws/2, error/2]).
+-export([exits/3, throws/3, error/3]).
+-export([exits/4, throws/4, error/4]).
+-export([exact/2, equal/2, not_equal/2, bigger/2, lesser/2]).
+-export([exact/3, equal/3, not_equal/3, bigger/3, lesser/3]).
+-export([exact/5, equal/5, not_equal/5, bigger/5, lesser/5]).
+
+-export([echo/1, echo/2]).
+-export([banner/1, banner/2, ascii_banner/0, ascii_banner/1, center/2]).
+-export([strong_banner/1, strong_banner/2]). % legacy
+-export([vecho/2, vecho/3]).
+-export([alive/1,delimited/1]).
+
+-export([glist/1, glist_add/3, glist_get/2, glist_get/3, glist_drop/2, glist_loop/0, glist_loop/3]).
+
+-compile([{nowarn_unused_function, [passed/3, failed/3]}]).
+-compile({no_auto_import,[error/1, error/2]}).
+
+
+%%%----------------------------------------------------------------------------
+
+-define(VERSION, "0.2.8.2/alpha").
+-define(LIBRARY, "Erlunit").
+-define(COPYRIGHT, "(c) 2010 Eonblast Corporation http://www.eonblast.com").
+
+% -define(PROMPT, "\e[1;30merlunit:\e[0m ").
+-define(PROMPT, "erlunit: ").
+-define(INDENT, " ").
+
+-define(USRERR, "This is an error in the way you use erlunit, or an error in erlunit itself.").
+-define(PRGERR, "This is an error in erlunit itself.").
+-define(INVERT, "This is an inverted suite. Fails count for Passes, for testing the tests.").
+
+-define(DEFAULT_SUITE_NAME, "Default Suite").
+
+-define(V1, false). % verbosity settings
+% not used: -define(V2, false). % higler level enabled
+% not used: -define(V3, false). % means more details.
+
+-define(D3, false). % Debug verbosity:
+-define(D4, false). % Numbers mean different areas, not levels.
+-define(D5, false). % They are called out as hint in error messages.
+
+-define(LINES, true). % governs display of lines in output.
+
+
+%%%****************************************************************************
+%%% INDIVIDUAL CHECKS
+%%%****************************************************************************
+%%%
+%%% This is repetive to avoid the hiding of details coming with macro use and
+%%% more complicated function calls that anonymous function would entail.
+%%%
+%%% These function can be called by the main process or a suite process.
+%%%
+%%%---------------------------------------------------------------------checks-
+%%% true - check if an expression returns true
+%%%----------------------------------------------------------------------------
+%%%
+%%% For true/0 see (*). That is used for a different purpose.
+
+true(msg) -> "Check for true";
+
+true(A) -> true(A, true(msg)).
+
+true(A, Message) -> true(whereis(suite), A, Message).
+
+true(Suite, A, Message) when is_pid(Suite) -> true(Suite, A, Message, "", "").
+
+true(A, Message, Module, Line) -> true(whereis(suite), A, Message, Module, Line).
+
+true(Suite, A, Message, Module, Line) when is_pid(Suite) ->
+
+ AA = payload(Suite, Message, A),
+
+ if AA ->
+ passed(Suite, Message, "evaluates to ~w", [AA]);
+ true ->
+ failed(Suite, Message, "evaluates to ~w, should be true but is not | ~w ~w", [AA, Module, Line])
+ end.
+
+%%% checks
+%%%----------------------------------------------------------------------------
+%%% not_true - in Erlang, this is not necessarily 'false'
+%%%----------------------------------------------------------------------------
+%%%
+
+not_true(msg) -> "Check for not true";
+
+not_true(A) -> not_true(A, not_true(msg)).
+
+not_true(A, Message) -> not_true(whereis(suite), A, Message).
+
+not_true(Suite, A, Message) when is_pid(Suite) -> not_true(Suite, A, Message, "", "").
+
+not_true(A, Message, Module, Line) -> not_true(whereis(suite), A, Message, Module, Line).
+
+not_true(Suite, A, Message, Module, Line) when is_pid(Suite) ->
+
+ AA = payload(Suite, Message, A),
+
+ if AA =/= true ->
+ passed(Suite, Message, "evaluates to ~w, not true, as it should", [AA]);
+ true ->
+ failed(Suite, Message, "evaluates to ~w, but should not be true | ~w ~w", [AA, Module, Line])
+ end.
+
+%%% checks
+%%%----------------------------------------------------------------------------
+%%% false
+%%%----------------------------------------------------------------------------
+%%%
+
+false(msg) -> "Check for false";
+
+false(A) -> false(A, false(msg)).
+
+false(A, Message) -> false(whereis(suite), A, Message).
+
+false(Suite, A, Message) when is_pid(Suite) -> false(Suite, A, Message, "", "").
+
+false(A, Message, Module, Line) -> false(whereis(suite), A, Message, Module, Line).
+
+false(Suite, A, Message, Module, Line) when is_pid(Suite) ->
+
+ AA = payload(Suite, Message, A),
+
+ if AA == false ->
+ passed(Suite, Message, "evaluates to ~w", [AA]);
+ true ->
+ failed(Suite, Message, "evaluates to ~w, should be false but is not | ~w ~w", [AA, Module, Line])
+ end.
+
+%%% checks
+%%%----------------------------------------------------------------------------
+%%% not_false - in Erlang, this is not necessarily 'true'
+%%%----------------------------------------------------------------------------
+%%%
+
+
+not_false(msg) -> "Check for not false";
+
+not_false(A) -> not_false(A, not_false(msg)).
+
+not_false(A, Message) -> not_false(whereis(suite), A, Message).
+
+not_false(Suite, A, Message) when is_pid(Suite) -> not_false(Suite, A, Message, "", "").
+
+not_false(A, Message, Module, Line) -> not_false(whereis(suite), A, Message, Module, Line).
+
+not_false(Suite, A, Message, Module, Line) when is_pid(Suite) ->
+
+ AA = payload(Suite, Message, A),
+
+ if AA =/= false ->
+ passed(Suite, Message, "evaluates to ~w, not false, as it should", [AA]);
+ true ->
+ failed(Suite, Message, "evaluates to ~w, but should not be false | ~w ~w", [AA, Module, Line])
+ end.
+
+%%% checks
+%%%----------------------------------------------------------------------------
+%%% pass - ok means: Fun throws NO exception
+%%%----------------------------------------------------------------------------
+%%%
+
+pass(msg) -> "Check for passing without exception";
+
+pass(Fun) when is_function(Fun) -> pass(Fun, pass(msg)).
+
+pass(Fun, Message) when is_function(Fun) -> pass(whereis(suite), Fun, Message).
+
+pass(Suite, Fun, Message) when is_function(Fun) -> pass(Suite, Fun, Message, "", "").
+
+pass(Fun, Message, Module, Line) when is_function(Fun) -> pass(whereis(suite), Fun, Message, Module, Line).
+
+pass(Suite, Fun, Message, Module, Line) when is_function(Fun) ->
+
+ try
+ Fun(),
+ passed(Suite, Message, "passes ok")
+ catch
+ throw:Term ->
+ failed(Suite, Message, "throws exception (~w) but should pass ok | ~w ~w~n~p", [Term, Module, Line, erlang:get_stacktrace()]);
+ exit:Reason ->
+ failed(Suite, Message, "make exit (~w) but should pass ok | ~w ~w~n~p", [Reason, Module, Line, erlang:get_stacktrace()]);
+ error:Reason ->
+ failed(Suite, Message, "runs into error (~w) but should pass ok | ~w ~w~n~p", [Reason, Module, Line, erlang:get_stacktrace()])
+ end.
+
+%%% checks
+%%%----------------------------------------------------------------------------
+%%% fail - ok when Fun throws an exception
+%%%----------------------------------------------------------------------------
+%%%
+
+fail(msg) -> "Check for exception";
+
+fail(Fun) when is_function(Fun) -> fail(Fun, fail(msg)).
+
+fail(Fun, Message) when is_function(Fun) -> fail(whereis(suite), Fun, Message).
+
+fail(Suite, Fun, Message) when is_function(Fun) -> fail(Suite, Fun, Message, "", "").
+
+fail(Fun, Message, Module, Line) when is_function(Fun) -> fail(whereis(suite), Fun, Message, Module, Line).
+
+fail(Suite, Fun, Message, Module, Line) when is_function(Fun) ->
+
+ try
+ Result = Fun(),
+ failed(Suite, Message, "passes ok (~w) but should fail | ~w ~w~n~p", [Result, Module, Line, erlang:get_stacktrace()])
+ catch
+ throw:Term ->
+ passed(Suite, Message, "throws exception (~w), failing as it should", [Term]);
+ exit:Reason ->
+ passed(Suite, Message, "makes exit (~w), failing as it should", [Reason]);
+ error:Reason ->
+ passed(Suite, Message, "runs into error (~w), failing as it should", [Reason])
+ end.
+
+%%% checks
+%%%----------------------------------------------------------------------------
+%%% throws - ok when Fun throws an exception
+%%%----------------------------------------------------------------------------
+%%%
+
+
+throws(msg) -> "Check for throw";
+
+throws(Fun) when is_function(Fun) -> throws(Fun, throws(msg)).
+
+throws(Fun, Message) when is_function(Fun) -> throws(whereis(suite), Fun, Message).
+
+throws(Suite, Fun, Message) when is_function(Fun) -> throws(Suite, Fun, Message, "", "").
+
+throws(Fun, Message, Module, Line) when is_function(Fun) -> throws(whereis(suite), Fun, Message, Module, Line).
+
+throws(Suite, Fun, Message, Module, Line) when is_function(Fun) ->
+
+ try
+ Fun(),
+ failed(Suite, Message, "passes ok but should throw and fail | ~w ~w~n~p", [Module, Line, erlang:get_stacktrace()])
+ catch
+ throw:_Term ->
+ passed(Suite, Message, "throws exception, as it should");
+ exit:_Reason ->
+ failed(Suite, Message, "makes exit, but should throw and and fail | ~w ~w~n~p", [Module,Line, erlang:get_stacktrace()]);
+ error:_Reason ->
+ failed(Suite, Message, "runs into error, but should throw and fail | ~w ~w~n~p", [Module,Line, erlang:get_stacktrace()])
+ end.
+%%% checks
+%%%----------------------------------------------------------------------------
+%%% exits - ok when Fun calls exit
+%%%----------------------------------------------------------------------------
+%%%
+
+exits(msg) -> "Check for exit being called";
+
+exits(Fun) when is_function(Fun) -> exits(Fun, exits(msg)).
+
+exits(Fun, Message) when is_function(Fun) -> exits(whereis(suite), Fun, Message).
+
+exits(Suite, Fun, Message) when is_function(Fun) -> exits(Suite, Fun, Message, "", "").
+
+exits(Fun, Message, Module, Line) when is_function(Fun) -> exits(whereis(suite), Fun, Message, Module, Line).
+
+exits(Suite, Fun, Message, Module, Line) when is_function(Fun) ->
+
+ try
+ Fun(),
+ failed(Suite, Message, "passes ok but should throw and fail | ~w ~w~n~p", [Module,Line, erlang:get_stacktrace()])
+ catch
+ throw:_Term ->
+ failed(Suite, Message, "throws exception, as it should | ~w ~w~n~p", [Module,Line, erlang:get_stacktrace()]);
+ exit:_Reason ->
+ passed(Suite, Message, "makes exit, but should throw and and fail");
+ error:_Reason ->
+ failed(Suite, Message, "runs into error, but should throw and fail | ~w ~w~n~p", [Module,Line, erlang:get_stacktrace()])
+ end.
+%%% checks
+%%%----------------------------------------------------------------------------
+%%% error - ok when Fun runs into error
+%%%----------------------------------------------------------------------------
+%%%
+
+error(msg) -> "Check for having error";
+
+error(Fun) when is_function(Fun) -> error(Fun, error(msg)).
+
+error(Fun, Message) when is_function(Fun) -> error(whereis(suite), Fun, Message).
+
+error(Suite, Fun, Message) when is_function(Fun) -> error(Suite, Fun, Message, "", "").
+
+error(Fun, Message, Module, Line) when is_function(Fun) -> error(whereis(suite), Fun, Message, Module, Line).
+
+error(Suite, Fun, Message, Module, Line) when is_function(Fun) ->
+
+ try
+ Fun(),
+ failed(Suite, Message, "passes ok but should run into error | ~w ~w~n~p", [Module, Line, erlang:get_stacktrace()])
+ catch
+ throw:_Term ->
+ failed(Suite, Message, "throws exception, but should run into error | ~w ~w~n~p", [Module,Line, erlang:get_stacktrace()]);
+ exit:_Reason ->
+ failed(Suite, Message, "makes exit, but should run into error | ~w ~w~n~p", [Module,Line, erlang:get_stacktrace()]);
+ error:_Reason ->
+ passed(Suite, Message, "runs into error, as it should")
+ end.