Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Commiting initial setup script, benchmark script, and docs

  • Loading branch information...
commit 97cddda2dec12303a71104720b7a8aeb836af4f1 1 parent f568385
@felixge authored
Showing with 222 additions and 0 deletions.
  1. +37 −0 README.textile
  2. +171 −0 insert-bench.php
  3. +14 −0 setup.sh
View
37 README.textile
@@ -0,0 +1,37 @@
+h1. Important
+
+As much as you would probably like to ignore your rational mind, head over to my published results, and just take those values as truth. Do not. Or at least don't blame me for any of the architectural results.
+
+I am currently working on these benchmarks to get first-hand data about the scaling properties of CouchDB. Specifically I care about disk usage (to figure out when sharding will be required) and replication speed. However, along the way I am also collecting potentially other useful information, but keep in mind that my test methodology will clearly focus on disk usage and replication characteristics.
+
+If you want to get some more insights into evaluating CouchDB and other #nosql databases, I highly recommend those 2 articles by Jan Lehnardt (@janl):
+
+http://jan.prima.de/~jan/plok/archives/175-Benchmarks-You-are-Doing-it-Wrong.html
+http://jan.prima.de/~jan/plok/archives/176-Caveats-of-Evaluating-Databases.html
+
+h1. Setup
+
+I have choosen to run all tests on Amazon EC2 with c1.medium instances. The reason is simply that this will be my production environment, but it has also the benefit that others can easily verify / compare my results.
+
+So far I have been using ami-0d729464 (Ubuntu 9.04 Jaunty, see "alestic.com":http://alestic.com/). But any other Ubuntu >= 8.04 version should do as well.
+
+Once you have fired up the instance, you can install the latest CouchDB SVN:HEAD version by simply running:
+
+./setup.sh
+
+h1. Running the tests
+
+Just pick any of the .php benchmark files available, then run:
+
+time php insert-bench.php | tee my-results.log
+
+This will show you the real-time output of the script as well as store all results in "my-results.log" so you can share them with the world.
+
+h1. Help extending this suite!
+
+If you need more data than what is currently reported, just fork this project on GitHub and I'll integrate your changes. I'm cool with any languages, I just use PHP as again this is what I use in production and what I know the best.
+
+Feedback & questions can be sent to felix@debuggable.com. I'm @felixge on twitter.
+
+Thanks for checking this out,
+-- Felix Geisendörfer
View
171 insert-bench.php
@@ -0,0 +1,171 @@
+<?php
+
+$config = array(
+ 'method' => 'bulk_insert',
+ 'insertCounts' => array(
+ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
+ 10,
+ 50,
+ 100,
+ 500,
+ 1000,
+ 2500,
+ 5000,
+ 7500,
+ 10000,
+ 25000,
+ 50000,
+ 100000,
+ 250000,
+ 500000,
+ 750000,
+ 1000000,
+ )
+);
+
+$db = new CouchDb();
+foreach ($config['insertCounts'] as $docCount) {
+ // Re-create the database for each attempt
+ $db->send('delete', '/benchmark_db');
+ $db->send('put', '/benchmark_db');
+
+
+ echo sprintf("-> %s %d docs:\n", $method, $docCount);
+
+ switch ($config['method']) {
+ case 'bulk_insert':
+ $insertStart = microtime(true);
+ $docsWritten = 0;
+ while ($docsWritten < $docCount) {
+ $insertAtOnce = ($docCount - $docsWritten > 1000)
+ ? 1000
+ : $docCount - $docsWritten;
+
+ $docs = array();
+ for ($i = 0; $i < $insertAtOnce; $i++) {
+ $docs[] = array(
+ '_id' => CouchDb::uuid(),
+ 'foo' => 'bar'
+ );
+ }
+ $db->send('post', '/benchmark_db/_bulk_docs', compact('docs'));
+ $docsWritten = $docsWritten + $insertAtOnce;
+ echo '.';
+ }
+ $insertEnd = microtime(true);
+ break;
+ case 'single_insert':
+ $insertStart = microtime(true);
+ for ($i = 0; $i < $docCount; $i++) {
+ $db->send('put', sprintf('/benchmark_db/%s', CouchDb::uuid()), array(
+ 'foo' => 'bar',
+ ));
+ }
+ $insertEnd = microtime(true);
+ echo '.';
+ break;
+ }
+
+ clearstatcache();
+ $beforeCompact = array(
+ 'stats' => $db->send('get', '/benchmark_db'),
+ 'fileSize' => filesize('/usr/local/var/lib/couchdb/benchmark_db.couch'),
+ );
+
+ $compactStart = microtime(true);
+ $r = $db->send('post', '/benchmark_db/_compact');
+ while ($status = $db->send('get', '/benchmark_db')) {
+ if (!$status['compact_running']) {
+ break;
+ }
+ echo 'x';
+ usleep(1000000);
+ }
+ $compactEnd = microtime(true);
+
+ clearstatcache();
+ $afterCompact = array(
+ 'stats' => $db->send('get', '/benchmark_db'),
+ 'fileSize' => filesize('/usr/local/var/lib/couchdb/benchmark_db.couch'),
+ );
+
+ echo "\n\n";
+ echo sprintf(
+ "doc count (before compact): %s\n".
+ "doc count (after compact): %s\n".
+ "insert time: %s sec\n".
+ "insert time / doc: %s ms\n".
+ "compact time: %s sec\n".
+ "compact time / doc: %s ms\n".
+ "disk size (before compact): %s bytes\n".
+ "disk size (after compact): %s bytes\n".
+ ".couch size (before compact): %s bytes\n".
+ ".couch size (after compact): %s bytes\n".
+ ".couch size / doc (before compact): %s bytes\n".
+ ".couch size / doc (after compact): %s bytes\n\n",
+
+ $beforeCompact['stats']['doc_count'],
+ $afterCompact['stats']['doc_count'],
+ round($insertEnd - $insertStart, 4),
+ ($beforeCompact['stats']['doc_count'])
+ ? round((($insertEnd - $insertStart) * 1000) / $beforeCompact['stats']['doc_count'], 2)
+ : 'n/a',
+ round($compactEnd - $compactStart, 4),
+ ($beforeCompact['stats']['doc_count'])
+ ? round((($compactEnd - $compactStart) * 1000) / $beforeCompact['stats']['doc_count'], 2)
+ : 'n/a',
+ $beforeCompact['stats']['disk_size'],
+ $afterCompact['stats']['disk_size'],
+ $beforeCompact['fileSize'],
+ $afterCompact['fileSize'],
+ ($beforeCompact['stats']['doc_count'])
+ ? round($beforeCompact['fileSize'] / $beforeCompact['stats']['doc_count'], 2)
+ : 'n/a',
+ ($afterCompact['stats']['doc_count'])
+ ? round($afterCompact['fileSize'] / $afterCompact['stats']['doc_count'], 2)
+ : 'n/a'
+ );
+}
+
+class CouchDb {
+ public $config = array(
+ 'host' => 'localhost',
+ 'port' => 5984
+ );
+
+ public function __construct($config = array()) {
+ $this->config = $config + $this->config;
+ }
+
+ public function send($method, $resource, $document = array()) {
+ $url = sprintf(
+ 'http://%s:%s%s',
+ $this->config['host'],
+ $this->config['port'],
+ $resource
+ );
+
+ $curlOptions = array(
+ CURLOPT_RETURNTRANSFER => true,
+ CURLOPT_CUSTOMREQUEST => strtoupper($method),
+ );
+
+ if (!empty($document)) {
+ $curlOptions[CURLOPT_POSTFIELDS] = json_encode($document);
+ }
+
+
+ $curl = curl_init($url);
+ curl_setopt_array($curl, $curlOptions);
+ $r = curl_exec($curl);
+
+ return json_decode($r, true);
+ }
+
+ public static function uuid() {
+ return substr(sha1(uniqid(mt_rand(), true)), 0, 32);
+
+ }
+}
+
+?>
View
14 setup.sh
@@ -0,0 +1,14 @@
+# This is pretty much just copied from the CouchDB wiki and will setup CouchDB from the latest SVN:HEAD
+# see http://wiki.apache.org/couchdb/Getting_started_with_Amazon_EC2
+
+# All I did was adding php5-cli + php5-curl
+
+sudo apt-get update && sudo apt-get -y upgrade
+sudo apt-get install -y erlang libmozjs-dev libicu-dev libcurl4-gnutls-dev make subversion automake autoconf libtool help2man
+sudo apt-get install -y php5-cli php5-curl
+svn checkout http://svn.apache.org/repos/asf/couchdb/trunk couchdb
+cd couchdb
+./bootstrap && ./configure && make && sudo make install
+sudo adduser --system --home /usr/local/var/lib/couchdb --no-create-home --shell /bin/bash --group --gecos 'CouchDB account' couchdb
+sudo chown -R couchdb.couchdb /usr/local/var/{lib,log}/couchdb
+sudo -i -u couchdb couchdb
Please sign in to comment.
Something went wrong with that request. Please try again.