22import os .path
33import sys
44import time
5+ from optparse import OptionParser
6+ from greplin import scales
7+
58dirname = os .path .dirname (os .path .abspath (__file__ ))
69sys .path .append (dirname )
710sys .path .append (os .path .join (dirname , '..' ))
1619handler .setFormatter (logging .Formatter ("%(asctime)s [%(levelname)s] %(name)s: %(message)s" ))
1720log .addHandler (handler )
1821
22+ have_libev = False
1923supported_reactors = [AsyncoreConnection ]
2024try :
2125 from cassandra .io .libevreactor import LibevConnection
26+ have_libev = True
2227 supported_reactors .append (LibevConnection )
2328except ImportError , exc :
2429 log .warning ("Not benchmarking libev reactor: %s" % (exc ,))
2530
2631KEYSPACE = "testkeyspace"
2732TABLE = "testtable"
28- NUM_QUERIES = 10000
2933
3034def setup ():
3135
@@ -63,11 +67,12 @@ def teardown():
6367
6468
6569def benchmark (run_fn ):
66- for conn_class in supported_reactors :
70+ options , args = parse_options ()
71+ for conn_class in options .supported_reactors :
6772 setup ()
6873 log .info ("==== %s ====" % (conn_class .__name__ ,))
6974
70- cluster = Cluster ([ '127.0.0.1' ] )
75+ cluster = Cluster (options . hosts , metrics_enabled = options . enable_metrics )
7176 cluster .connection_class = conn_class
7277 session = cluster .connect (KEYSPACE )
7378
@@ -83,11 +88,63 @@ def benchmark(run_fn):
8388 log .debug ("Beginning inserts..." )
8489 start = time .time ()
8590 try :
86- run_fn (session , query , values , NUM_QUERIES )
91+ run_fn (session , query , values , options . num_ops )
8792 end = time .time ()
8893 finally :
8994 teardown ()
9095
9196 total = end - start
9297 log .info ("Total time: %0.2fs" % total )
93- log .info ("Average throughput: %0.2f/sec" % (NUM_QUERIES / total ))
98+ log .info ("Average throughput: %0.2f/sec" % (options .num_ops / total ))
99+ if options .enable_metrics :
100+ stats = scales .getStats ()['cassandra' ]
101+ log .info ("Connection errors: %d" , stats ['connection_errors' ])
102+ log .info ("Write timeouts: %d" , stats ['write_timeouts' ])
103+ log .info ("Read timeouts: %d" , stats ['read_timeouts' ])
104+ log .info ("Unavailables: %d" , stats ['unavailables' ])
105+ log .info ("Other errors: %d" , stats ['other_errors' ])
106+ log .info ("Retries: %d" , stats ['retries' ])
107+
108+ request_timer = stats ['request_timer' ]
109+ log .info ("Request latencies:" )
110+ log .info (" min: %0.4fs" , request_timer ['min' ])
111+ log .info (" max: %0.4fs" , request_timer ['max' ])
112+ log .info (" mean: %0.4fs" , request_timer ['mean' ])
113+ log .info (" stddev: %0.4fs" , request_timer ['stddev' ])
114+ log .info (" median: %0.4fs" , request_timer ['median' ])
115+ log .info (" 75th: %0.4fs" , request_timer ['75percentile' ])
116+ log .info (" 95th: %0.4fs" , request_timer ['95percentile' ])
117+ log .info (" 98th: %0.4fs" , request_timer ['98percentile' ])
118+ log .info (" 99th: %0.4fs" , request_timer ['99percentile' ])
119+ log .info (" 99.9th: %0.4fs" , request_timer ['999percentile' ])
120+
121+
122+ def parse_options ():
123+ parser = OptionParser ()
124+ parser .add_option ('-H' , '--hosts' , default = '127.0.0.1' ,
125+ help = 'cassandra hosts to connect to (comma-separated list) [default: %default]' )
126+ parser .add_option ('-t' , '--threads' , type = 'int' , default = 1 ,
127+ help = 'number of threads [default: %default]' )
128+ parser .add_option ('-n' , '--num-ops' , type = 'int' , default = 10000 ,
129+ help = 'number of operations [default: %default]' )
130+ parser .add_option ('--asyncore-only' , action = 'store_true' , dest = 'asyncore_only' ,
131+ help = 'only benchmark with asyncore connections' )
132+ parser .add_option ('--libev-only' , action = 'store_true' , dest = 'libev_only' ,
133+ help = 'only benchmark with libev connections' )
134+ parser .add_option ('-m' , '--metrics' , action = 'store_true' , dest = 'enable_metrics' ,
135+ help = 'enable and print metrics for operations' )
136+ options , args = parser .parse_args ()
137+
138+ options .hosts = options .hosts .split (',' )
139+
140+ if options .libev_only :
141+ if not have_libev :
142+ log .error ("libev is not available" )
143+ sys .exit (1 )
144+ options .supported_reactors = [LibevConnection ]
145+ elif options .asyncore_only :
146+ options .supported_reactors = [AsyncoreConnection ]
147+ else :
148+ options .supported_reactors = supported_reactors
149+
150+ return options , args
0 commit comments