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) {
 void uBenchmark::failure(const char* operation) {
@@ -62,6 +125,16 @@ void uBenchmark::print_clock(const std::string& operation, uint32_t num,
 
 
 int uBenchmark::run() {
 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));
     srandom(time(NULL));
 
 
     try {
     try {

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

@@ -42,9 +42,11 @@ public:
 
 
     int run();
     int run();
 
 
-    bool parseCmdline(int args, const char* argv[]);
+    bool parseCmdline(int args, char* const argv[]);
 
 
 protected:
 protected:
+    void usage();
+
     uint32_t Num_; // number of operations (e.g. insert lease num times)
     uint32_t Num_; // number of operations (e.g. insert lease num times)
 
 
     bool Sync_;  // synchronous or asynchonous mode?
     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.
         source code features set of performance microbenchmarks.
         These are small tools written in C/C++ that simulate expected
         These are small tools written in C/C++ that simulate expected
         DHCP server behaviour and evaluate the performance of
         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>
 
 
       <para>
       <para>
         Those benchmarks are stored in tests/tools/dhcp-ubench
         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
         various DB back-ends that are planned or considered as a
         backend engine for BIND10 DHCP.  Athough trivial now, they are
         backend engine for BIND10 DHCP.  Athough trivial now, they are
         expected to evolve into useful tools that will allow users to
         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
       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>
       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>
       <section>
         <title>MySQL tweaks</title>
         <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.
         <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
         You can get a list of engines of your MySQL implementation by using
@@ -249,16 +263,15 @@
 
 
       <section id="sqlite-tweaks">
       <section id="sqlite-tweaks">
         <title>SQLite tweaks</title>
         <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>
         <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>
         </orderedlist>
         </para>
         </para>
 
 
@@ -276,11 +289,32 @@
 
 
     <section id="memfile-ubench">
     <section id="memfile-ubench">
       <title>memfile-ubench</title>
       <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">
       <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>
     </section>
     </section>
 
 

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

@@ -292,11 +292,11 @@ void memfile_uBenchmark::deleteLease4Test() {
 }
 }
 
 
 void memfile_uBenchmark::printInfo() {
 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";
     const char * filename = "dhcpd.leases";
     uint32_t num = 100;
     uint32_t num = 100;
@@ -305,6 +305,8 @@ int main(int argc, const char * argv[]) {
 
 
     memfile_uBenchmark bench(filename, num, sync, verbose);
     memfile_uBenchmark bench(filename, num, sync, verbose);
 
 
+    bench.parseCmdline(argc, argv);
+
     int result = bench.run();
     int result = bench.run();
 
 
     return (result);
     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 << "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(),
     if (!mysql_real_connect(Conn_, Hostname_.c_str(), User_.c_str(),
                             Passwd_.c_str(), DBName_.c_str(), 0, NULL, 0)) {
                             Passwd_.c_str(), DBName_.c_str(), 0, NULL, 0)) {
         failure("connecting to MySQL server");
         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);
     MySQL_uBenchmark bench(hostname, user, passwd, dbname, num, sync, verbose);
 
 
+   bench.parseCmdline(argc, argv);
+
     int result = bench.run();
     int result = bench.run();
 
 
     return (result);
     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";
     const char * filename = "sqlite.db";
     uint32_t num = 100;
     uint32_t num = 100;
@@ -264,6 +264,8 @@ int main(int argc, const char * argv[]) {
 
 
     SQLite_uBenchmark bench(filename, num, sync, verbose);
     SQLite_uBenchmark bench(filename, num, sync, verbose);
 
 
+    bench.parseCmdline(argc, argv);
+
     int result = bench.run();
     int result = bench.run();
 
 
     return (result);
     return (result);