Browse Source

[2040] Command line options implemented for DHCP microbenchmarks

Tomek Mrugalski 13 years ago
parent
commit
72c153820e

+ 75 - 2
tests/tools/dhcp-ubench/benchmark.cc

@@ -31,8 +31,71 @@ uBenchmark::uBenchmark(uint32_t iterations, const std::string& dbname,
 
 }
 
-bool uBenchmark::parseCmdline(int args, const char* argv[]) {
-    return false;
+void uBenchmark::usage() {
+    cout << "This is a benchmark designed to measure expected performance" << endl;
+    cout << "of several backends. This backend identifies itself as:" << endl;
+    printInfo();
+
+    cout << endl << "Possible command-line parameters:" << endl;
+    cout << " -h - help (you are reading this)" << endl;
+    cout << " -m hostname - specifies MySQL server to connect (MySQL backend only)" << endl;
+    cout << " -u username - specifies MySQL user name (MySQL backend only)" << endl;
+    cout << " -p password - specifies MySQL passwod (MySQL backend only)" << endl;
+    cout << " -f name - database or filename (MySQL, SQLite and memfile)" << endl;
+    cout << " -n integer - number of test repetitions (MySQL, SQLite and memfile)" << endl;
+    cout << " -s yes|no - synchronous/asynchronous operation (MySQL, SQLite and memfile)" << endl;
+    cout << " -v yes|no - verbose mode (MySQL, SQLite and memfile)" << endl;
+
+    exit(EXIT_FAILURE);
+}
+
+bool uBenchmark::parseCmdline(int argc, char* const argv[]) {
+    int ch;
+
+    while ((ch = getopt(argc, argv, "hm:u:p:f:n:s:v:")) != -1) {
+        switch (ch) {
+        case 'h':
+            usage();
+        case 'm':
+            Hostname_ = string(optarg);
+            break;
+        case 'u':
+            User_ = string(optarg);
+            break;
+        case 'p':
+            Passwd_ = string(optarg);
+            break;
+        case 'f':
+            DBName_ = string(optarg);
+            break;
+        case 'n':
+            Num_ = strtol(optarg, NULL, 10);
+            if (Num_ <= 0) {
+                cerr << "Failed to iterations (-n option)." << endl;
+                usage();
+            }
+            break;
+        case 's':
+            if (!strcasecmp(optarg, "yes") || !strcmp(optarg,"1")) {
+                Sync_ = true;
+            } else {
+                Sync_ = false;
+            }
+            break;
+        case 'v':
+            if (!strcasecmp(optarg, "yes") || !strcmp(optarg,"1")) {
+                Verbose_ = true;
+            } else {
+                Verbose_ = false;
+            }
+            break;
+        case ':':
+        default:
+            usage();
+        }
+    }
+
+    return true;
 }
 
 void uBenchmark::failure(const char* operation) {
@@ -62,6 +125,16 @@ void uBenchmark::print_clock(const std::string& operation, uint32_t num,
 
 int uBenchmark::run() {
 
+    cout << "Starting test. Parameters: " << endl
+         << "Number of iterations :" << Num_ << endl
+         << "Sync/async           :" << (Sync_?"sync":"async") << endl
+         << "Verbose              :" << (Verbose_?"verbose":"quiet") << endl
+         << "Database name        :" << DBName_ << endl
+         << "MySQL hostname       :" << Hostname_ << endl
+         << "MySQL username       :" << User_ << endl
+         << "MySQL password       :" << Passwd_ << endl << endl;
+
+
     srandom(time(NULL));
 
     try {

+ 3 - 1
tests/tools/dhcp-ubench/benchmark.h

@@ -42,9 +42,11 @@ public:
 
     int run();
 
-    bool parseCmdline(int args, const char* argv[]);
+    bool parseCmdline(int args, char* const argv[]);
 
 protected:
+    void usage();
+
     uint32_t Num_; // number of operations (e.g. insert lease num times)
 
     bool Sync_;  // synchronous or asynchonous mode?

File diff suppressed because it is too large
+ 160 - 0
tests/tools/dhcp-ubench/dhcp-perf-guide.html


+ 68 - 34
tests/tools/dhcp-ubench/dhcp-perf-guide.xml

@@ -100,12 +100,23 @@
         source code features set of performance microbenchmarks.
         These are small tools written in C/C++ that simulate expected
         DHCP server behaviour and evaluate the performance of
-        considered databases.
+        considered databases. As implemented benchmarks are not really
+        simulating DHCP operation, but rather use set of primitives
+        that can be used by a real server, they are called
+        micro-benchmarks.
+      </para>
+
+      <para>Although there are many operations and data types that
+      server could store in a database, the most frequently used data
+      type is lease information. Although lease information for IPv4
+      and IPv6 differs slightly, it is expected that the performance
+      differences will be minimal between IPv4 and IPv6 lease operations.
+      Therefore each test uses lease4 table for performance measurements.
       </para>
 
       <para>
         Those benchmarks are stored in tests/tools/dhcp-ubench
-        directory.  This directory contains simplified prototypes for
+        directory. This directory contains simplified prototypes for
         various DB back-ends that are planned or considered as a
         backend engine for BIND10 DHCP.  Athough trivial now, they are
         expected to evolve into useful tools that will allow users to
@@ -191,29 +202,32 @@
       may slow down operations to around 20 per second. Observant user is expected
       to note that initial dots are printed too slowly and abort the test.</para>
 
-      <para>Currently all parameters are hardcoded. To modify them, one needs to
-      modify source code and recompile. Fortunately, that is quite easy.
-      To modify MySQL parameters, see main() method at the end of mysql_ubench.c
-      file. That is the plase where one can modify MySQL connection
-      parameters (MySQL server hostname, user and password and database name).</para>
+      <para>Currently all default parameters are hardcoded. Default values can be
+      overwritten using command line switches. Although all benchmarks take
+      the same list of parameters, some of them are specific to a given backend
+      type. To get a list of supported parameters, run your benchmark with -h option:
+
+      <screen>$ <userinput>./mysql_ubench -h</userinput>
+This is a benchmark designed to measure expected performance
+of several backends. This particular version identifies itself
+as following:
+MySQL client version is 5.5.24
+
+Possible command-line parameters:
+ -h - help (you are reading this)
+ -m hostname - specifies MySQL server to connect (MySQL backend only)
+ -u username - specifies MySQL user name (MySQL backend only)
+ -p password - specifies MySQL passwod (MySQL backend only)
+ -f name - database or filename (MySQL, SQLite and memfile)
+ -n integer - number of test repetitions (MySQL, SQLite and memfile)
+ -s yes|no - synchronous/asynchronous operation (MySQL, SQLite and memfile)
+ -v yes|no - verbose mode (MySQL, SQLite and memfile)
+</screen>
+
+      </para>
 
       <section>
         <title>MySQL tweaks</title>
-        <para>To reconfigure mysql_ubench parameters, a modification to the source
-        code and recompilation is required. All parameters are listed in main()
-        function in mysql_ubench.cc file, near the end of the file. Currently supported
-        parameter are (default values specified in brackets):
-        <orderedlist>
-          <listitem><para>hostname - name of the host to connect to ("localhost")</para></listitem>
-          <listitem><para>user - MySQL username ("root")</para></listitem>
-          <listitem><para>passwd - MySQL password ("secret")</para></listitem>
-          <listitem><para>dbname - MySQL database name ("kea")</para></listitem>
-          <listitem><para>num - number of iterations (100)</para></listitem>
-          <listitem><para>sync - should the operations be performend in synchronous (true)
-          or asynchronous (false) manner (true)</para></listitem>
-          <listitem><para>verbose - should the test print out progress? (true)</para></listitem>
-        </orderedlist>
-        </para>
 
         <para>One parameter that has huge impact on performance is a a backend engine.
         You can get a list of engines of your MySQL implementation by using
@@ -249,16 +263,15 @@
 
       <section id="sqlite-tweaks">
         <title>SQLite tweaks</title>
-        <para>To reconfigure sqlite_ubench parameters, a modification to the source
-        code and recompilation is required. All parameters are listed in main()
-        function in sqlite_ubench.cc file, near the end of the file. Currently supported
-        parameter are (default values specified in brackets):
+        <para>To modify default sqlite_ubench parameters, command line
+        switches can be used. Currently supported parameters are
+        (default values specified in brackets):
         <orderedlist>
-          <listitem><para>filename - name of the database file ("sqlite.db")</para></listitem>
-          <listitem><para>num - number of iterations (100)</para></listitem>
-          <listitem><para>sync - should the operations be performend in synchronous (true)
-          or asynchronous (false) manner (true)</para></listitem>
-          <listitem><para>verbose - should the test print out progress? (true)</para></listitem>
+          <listitem><para>-f filename - name of the database file ("sqlite.db")</para></listitem>
+          <listitem><para>-n num - number of iterations (100)</para></listitem>
+          <listitem><para>-s yes|no - should the operations be performend in synchronous (yes)
+          or asynchronous (no) manner (yes)</para></listitem>
+          <listitem><para>-v yes|no - verbose mode. Should the test print out progress? (yes)</para></listitem>
         </orderedlist>
         </para>
 
@@ -276,11 +289,32 @@
 
     <section id="memfile-ubench">
       <title>memfile-ubench</title>
-      <para> TODO </para>
+      <para>Memfile backend is custom developed prototype backend that
+      somewhat mimics operation of ISC DHCP4. It uses in-memory
+      storage using standard C++ and boost mechanisms (std::map and
+      boost::shared_ptr&gt;&lt;). All database changes are also
+      written to a lease file. That file is strictly write-only. This
+      approach takes advantage of the fact that simple append is faster
+      than edition with potential whole file relocation.</para>
 
       <section id="memfile-tweaks">
-        <title>SQLite tweaks</title>
-        <para> ... </para>
+        <title>memfile tweaks</title>
+        <para>To modify default memfile_ubench parameters, command line
+        switches can be used. Currently supported parameters are
+        (default values specified in brackets):
+        <orderedlist>
+          <listitem><para>-f filename - name of the database file ("dhcpd.leases")</para></listitem>
+          <listitem><para>-n num - number of iterations (100)</para></listitem>
+          <listitem><para>-s yes|no - should the operations be performend in synchronous (yes)
+          or asynchronous (no) manner (yes)</para></listitem>
+          <listitem><para>-v yes|no - verbose mode. Should the test print out progress? (yes)</para></listitem>
+        </orderedlist>
+        </para>
+
+        <para>memfile can run in asynchronous or synchronous mode. This
+        mode can be controlled by using sync parameter. It uses
+        fflush() and fsync() in synchronous mode to make sure that
+        data is not buffered and physically stored on disk.</para>
       </section>
     </section>
 

+ 4 - 2
tests/tools/dhcp-ubench/memfile_ubench.cc

@@ -292,11 +292,11 @@ void memfile_uBenchmark::deleteLease4Test() {
 }
 
 void memfile_uBenchmark::printInfo() {
-    cout << "Using memory db + write-only file." << endl;
+    cout << "Memory db (using std::map) + write-only file." << endl;
 }
 
 
-int main(int argc, const char * argv[]) {
+int main(int argc, char * const argv[]) {
 
     const char * filename = "dhcpd.leases";
     uint32_t num = 100;
@@ -305,6 +305,8 @@ int main(int argc, const char * argv[]) {
 
     memfile_uBenchmark bench(filename, num, sync, verbose);
 
+    bench.parseCmdline(argc, argv);
+
     int result = bench.run();
 
     return (result);

+ 10 - 11
tests/tools/dhcp-ubench/mysql_ubench.cc

@@ -50,9 +50,6 @@ void MySQL_uBenchmark::connect() {
         cout << "MySQL library init successful." << endl;
     }
 
-    cout << "hostname=" << Hostname_ << ", user=" << User_
-         << "pass=" << Passwd_ << " db=" << DBName_ << endl;
-
     if (!mysql_real_connect(Conn_, Hostname_.c_str(), User_.c_str(),
                             Passwd_.c_str(), DBName_.c_str(), 0, NULL, 0)) {
         failure("connecting to MySQL server");
@@ -262,18 +259,20 @@ void MySQL_uBenchmark::printInfo() {
 }
 
 
-int main(int argc, const char * argv[]) {
+int main(int argc, char * const argv[]) {
 
-    const char * hostname ="localhost";
-    const char * user = "root";
-    const char * passwd = "secret";
-    const char * dbname = "kea";
-    uint32_t num = 100;
-    bool sync = true;
-    bool verbose = true;
+    const char * hostname ="localhost"; // -m (MySQL server)
+    const char * user = "root";  // -u
+    const char * passwd = "secret"; // -p
+    const char * dbname = "kea"; // -f
+    uint32_t num = 100; // -n
+    bool sync = true;  // -s
+    bool verbose = true; // -v
 
     MySQL_uBenchmark bench(hostname, user, passwd, dbname, num, sync, verbose);
 
+   bench.parseCmdline(argc, argv);
+
     int result = bench.run();
 
     return (result);

+ 3 - 1
tests/tools/dhcp-ubench/sqlite_ubench.cc

@@ -255,7 +255,7 @@ void SQLite_uBenchmark::printInfo() {
 
 
 
-int main(int argc, const char * argv[]) {
+int main(int argc, char * const argv[]) {
 
     const char * filename = "sqlite.db";
     uint32_t num = 100;
@@ -264,6 +264,8 @@ int main(int argc, const char * argv[]) {
 
     SQLite_uBenchmark bench(filename, num, sync, verbose);
 
+    bench.parseCmdline(argc, argv);
+
     int result = bench.run();
 
     return (result);