dhcp-perf-guide.html 39 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. <html><head><meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1"><title>DHCP Performance Guide</title><link rel="stylesheet" type="text/css" href="bind10-guide.css"><meta name="generator" content="DocBook XSL Stylesheets V1.76.1"><meta name="description" content="BIND 10 is a framework that features Domain Name System (DNS) and Dynamic Host Configuration Protocol (DHCP) software with development managed by Internet Systems Consortium (ISC). This document describes various aspects of DHCP performance, measurements and tuning. It covers BIND 10 DHCP (codename Kea), existing ISC DHCP4 software, perfdhcp (a DHCP performance measurement tool) and other related topics."></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="book" title="DHCP Performance Guide"><div class="titlepage"><div><div><h1 class="title"><a name="idm25635296"></a>DHCP Performance Guide</h1></div><div><div class="author"><h3 class="author"><span class="firstname">Tomasz</span> <span class="surname">Mrugalski</span></h3></div></div><div><p class="releaseinfo">This is a companion document for BIND 10 version
  2. 20120712.</p></div><div><p class="copyright">Copyright © 2012 Internet Systems Consortium, Inc. ("ISC")</p></div><div><div class="abstract" title="Abstract"><p class="title"><b>Abstract</b></p><p>BIND 10 is a framework that features Domain Name System
  3. (DNS) and Dynamic Host Configuration Protocol (DHCP)
  4. software with development managed by Internet Systems Consortium (ISC).
  5. This document describes various aspects of DHCP performance,
  6. measurements and tuning. It covers BIND 10 DHCP (codename Kea),
  7. existing ISC DHCP4 software, perfdhcp (a DHCP performance
  8. measurement tool) and other related topics.</p></div></div></div><hr></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="preface"><a href="#idp31744">Preface</a></span></dt><dd><dl><dt><span class="section"><a href="#acknowledgements">1. Acknowledgements</a></span></dt></dl></dd><dt><span class="chapter"><a href="#intro">1. Introduction</a></span></dt><dt><span class="chapter"><a href="#dhcp4">2. ISC DHCP 4.x</a></span></dt><dt><span class="chapter"><a href="#kea">3. Kea</a></span></dt><dd><dl><dt><span class="section"><a href="#idp40176">3.1. Backend performance evaluation</a></span></dt><dt><span class="section"><a href="#mysql-backend">3.2. MySQL backend</a></span></dt><dd><dl><dt><span class="section"><a href="#idp64224">3.2.1. MySQL tweaks</a></span></dt></dl></dd><dt><span class="section"><a href="#sqlite-ubench">3.3. SQLite-ubench</a></span></dt><dd><dl><dt><span class="section"><a href="#sqlite-tweaks">3.3.1. SQLite tweaks</a></span></dt></dl></dd><dt><span class="section"><a href="#memfile-ubench">3.4. memfile-ubench</a></span></dt><dd><dl><dt><span class="section"><a href="#memfile-tweaks">3.4.1. memfile tweaks</a></span></dt></dl></dd><dt><span class="section"><a href="#idp104752">3.5. Basic performance measurements</a></span></dt><dt><span class="section"><a href="#idm38464">3.6. Optimized performance measurements</a></span></dt><dt><span class="section"><a href="#idp275344">3.7. Conclusions</a></span></dt><dt><span class="section"><a href="#idp281328">3.8. Possible further optimizations</a></span></dt></dl></dd><dt><span class="chapter"><a href="#perfdhcp">4. perfdhcp</a></span></dt></dl></div><div class="list-of-tables"><p><b>List of Tables</b></p><dl><dt>3.1. <a href="#idp108384">Synchronous results (basic)</a></dt><dt>3.2. <a href="#idp129440">Asynchronous results (basic)</a></dt><dt>3.3. <a href="#tbl-basic-perf-results">Estimated basic performance</a></dt><dt>3.4. <a href="#idp204944">Synchronous results (optimized)</a></dt><dt>3.5. <a href="#idp225424">Asynchronous results (optimized)</a></dt><dt>3.6. <a href="#tbl-optim-perf-results">Estimated optimized performance</a></dt></dl></div><div class="preface" title="Preface"><div class="titlepage"><div><div><h2 class="title"><a name="idp31744"></a>Preface</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#acknowledgements">1. Acknowledgements</a></span></dt></dl></div><div class="section" title="1. Acknowledgements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="acknowledgements"></a>1. Acknowledgements</h2></div></div></div><p>ISC would like to acknowledge generous support for
  9. BIND 10 development of DHCPv4 and DHCPv6 components provided
  10. by <a class="ulink" href="http://www.comcast.com/" target="_top">Comcast</a>.</p></div></div><div class="chapter" title="Chapter 1. Introduction"><div class="titlepage"><div><div><h2 class="title"><a name="intro"></a>Chapter 1. Introduction</h2></div></div></div><p>
  11. This document is in the early stages of development. It is
  12. expected to grow significantly in the near future. It will
  13. cover topics like database backend perfomance measurements,
  14. tools, and the pros an cons of various optimization techniques.
  15. </p></div><div class="chapter" title="Chapter 2. ISC DHCP 4.x"><div class="titlepage"><div><div><h2 class="title"><a name="dhcp4"></a>Chapter 2. ISC DHCP 4.x</h2></div></div></div><p>
  16. TODO: Write something about ISC DHCP4 here.
  17. </p></div><div class="chapter" title="Chapter 3. Kea"><div class="titlepage"><div><div><h2 class="title"><a name="kea"></a>Chapter 3. Kea</h2></div></div></div><div class="toc"><p><b>Table of Contents</b></p><dl><dt><span class="section"><a href="#idp40176">3.1. Backend performance evaluation</a></span></dt><dt><span class="section"><a href="#mysql-backend">3.2. MySQL backend</a></span></dt><dd><dl><dt><span class="section"><a href="#idp64224">3.2.1. MySQL tweaks</a></span></dt></dl></dd><dt><span class="section"><a href="#sqlite-ubench">3.3. SQLite-ubench</a></span></dt><dd><dl><dt><span class="section"><a href="#sqlite-tweaks">3.3.1. SQLite tweaks</a></span></dt></dl></dd><dt><span class="section"><a href="#memfile-ubench">3.4. memfile-ubench</a></span></dt><dd><dl><dt><span class="section"><a href="#memfile-tweaks">3.4.1. memfile tweaks</a></span></dt></dl></dd><dt><span class="section"><a href="#idp104752">3.5. Basic performance measurements</a></span></dt><dt><span class="section"><a href="#idm38464">3.6. Optimized performance measurements</a></span></dt><dt><span class="section"><a href="#idp275344">3.7. Conclusions</a></span></dt><dt><span class="section"><a href="#idp281328">3.8. Possible further optimizations</a></span></dt></dl></div><p>
  18. </p><div class="section" title="3.1. Backend performance evaluation"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp40176"></a>3.1. Backend performance evaluation</h2></div></div></div><p>
  19. Kea will support several different database backends, using
  20. both popular databases (like MySQL or SQLite) and
  21. custom-developed solutions (such as an in-memory database).
  22. To aid in the choice of backend, the BIND 10
  23. source code features a set of performance microbenchmarks.
  24. Written in C/C++, these are small tools that simulate expected
  25. DHCP server behaviour and evaluate the performance of
  26. considered databases. As implemented, the benchmarks are not really
  27. simulating DHCP operation, but rather use set of primitives
  28. that can be used by a real server. For this reason, they are called
  29. micro-benchmarks.
  30. </p><p>Although there are many operations and data types that
  31. server could store in a database, the most frequently used data
  32. type is lease information. Although the information held for IPv4
  33. and IPv6 leases differs slightly, it is expected that the performance
  34. differences will be minimal between IPv4 and IPv6 lease operations.
  35. Therefore each test uses the lease4 table (in which IPv4 leases are stored)
  36. for performance measurements.
  37. </p><p>All benchmarks are implemented as single threaded applications
  38. that take advantage of a single database connection.</p><p>
  39. Those benchmarks are stored in tests/tools/dhcp-ubench directory of the
  40. BIND 10 source tree. This directory contains simplified prototypes for
  41. the various database back-ends that are planned or considered as a
  42. possibly for BIND10 DHCP. These benchmarks are expected to evolve into
  43. useful tools that will allow users to measure performance in their
  44. specific environment.
  45. </p><p>
  46. Currently the following benchmarks are implemented:
  47. </p><div class="itemizedlist"><ul class="itemizedlist" type="disc"><li class="listitem"><p>In memory + flat file</p></li><li class="listitem"><p>SQLite</p></li><li class="listitem"><p>MySQL</p></li></ul></div><p>
  48. </p><p>
  49. As the benchmarks require additional (sometimes heavy) dependencies, they
  50. are not built by default. Actually, their build system is completely
  51. separate from that of the rest of BIND 10. It will be eventually merged
  52. with the main BIND 10 build system.
  53. </p><p>
  54. All benchmarks will follow the same pattern:
  55. </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>Prepare operation (connect to a database, create a file etc.)</p></li><li class="listitem"><p>Measure timestamp 0</p></li><li class="listitem"><p>Commit new lease4 record (repeated N times)</p></li><li class="listitem"><p>Measure timestamp 1</p></li><li class="listitem"><p>Search for random lease4 record (repeated N times)</p></li><li class="listitem"><p>Measure timestamp 2</p></li><li class="listitem"><p>Update existing lease4 record (repeated N times)</p></li><li class="listitem"><p>Measure timestamp 3</p></li><li class="listitem"><p>Delete existing lease4 record (repeated N times)</p></li><li class="listitem"><p>Measure timestamp 4</p></li><li class="listitem"><p>Print out statistics, based on N and measured timestamps.</p></li></ol></div><p>
  56. Although this approach does not attempt to simulate actual DHCP server
  57. operation that has mix of all steps, it answers the
  58. questions about basic database strengths and weak points. In particular
  59. it can show what is the impact of specific database optimizations, such as
  60. changing engine, optimizing for writes/reads etc.
  61. </p><p>
  62. The framework attempts to do the same amount of work for every
  63. backend thus allowing fair complarison between them.
  64. </p></div><div class="section" title="3.2. MySQL backend"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="mysql-backend"></a>3.2. MySQL backend</h2></div></div></div><p>The MySQL backend requires the MySQL client development libraries. It uses
  65. the mysql_config tool (similar to pkg-config) to discover required
  66. compilation and linking options. To install required packages on Ubuntu,
  67. use the following command:
  68. </p><pre class="screen">$ <strong class="userinput"><code>sudo apt-get install mysql-client mysql-server libmysqlclient-dev</code></strong></pre><p>
  69. Make sure that MySQL server is running. Make sure that you have your setup
  70. configured so there is a user that is able to modify used database.</p><p>Before running tests, you need to initialize your database. You can
  71. use mysql.schema script for that purpose.</p><p><span class="emphasis"><em>WARNING: It will drop existing
  72. Kea database. Do not run this on your production server. </em></span></p><p>Assuming your
  73. MySQL user is "kea", you can initialize your test database by:
  74. </p><pre class="screen">$ <strong class="userinput"><code>mysql -u kea -p &lt; mysql.schema</code></strong></pre><p>
  75. </p><p>After the database is initialized, you are ready to run the test:
  76. </p><pre class="screen">$ <strong class="userinput"><code>./mysql_ubench</code></strong></pre><p>
  77. or
  78. </p><pre class="screen">$ <strong class="userinput"><code>./mysql_ubench &gt; results-mysql.txt</code></strong></pre><p>
  79. Redirecting output to a file is important, because for each operation
  80. there is a single character printed to show progress. If you have a slow
  81. terminal, this may considerably affect test performance. On the other hand,
  82. printing something after each operation is required as poor database settings
  83. may slow down operations to around 20 per second. (The observant user is expected
  84. to note that the initial dots are printed too slowly and abort the test.)</p><p>Currently all default parameters are hardcoded. Default values can be
  85. overridden using command line switches. Although all benchmarks take
  86. the same list of parameters, some of them are specific to a given backend.
  87. To get a list of supported parameters, run the benchmark with the "-h" option:
  88. </p><pre class="screen">$ <strong class="userinput"><code>./mysql_ubench -h</code></strong></pre><p>
  89. </p><p>Synchronous operation requires database backend to
  90. physically store changes to disk before proceeding. This
  91. property ensures that no data is lost in case of the server
  92. failure. Unfortunately, it slows operation
  93. considerably. Asynchronous mode allows database to write data at
  94. a later time (usually controlled by the database engine on OS
  95. disk buffering mechanism).</p><div class="section" title="3.2.1. MySQL tweaks"><div class="titlepage"><div><div><h3 class="title"><a name="idp64224"></a>3.2.1. MySQL tweaks</h3></div></div></div><p>To modify the default mysql_ubench parameters, command line
  96. switches can be used. The currently supported switches are
  97. (default values specified in brackets):
  98. </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>-f name - name of the database ("kea")</p></li><li class="listitem"><p>-m hostname - name of the database host ("localhost")</p></li><li class="listitem"><p>-u user - MySQL username ("root")</p></li><li class="listitem"><p>-p password - MySQL password ("secret")</p></li><li class="listitem"><p>-n num - number of iterations (100)</p></li><li class="listitem"><p>-s yes|no - should the operations be performed in a synchronous (yes)
  99. or asynchronous (no) manner (yes)</p></li><li class="listitem"><p>-v yes|no - verbose mode. Should the test print out progress? (yes)</p></li><li class="listitem"><p>-c yes|no - precompiled statements. Should the SQL statements be precompiled? (yes)</p></li></ol></div><p>
  100. </p><p>One parameter that has huge impact on performance is the choice of backend engine.
  101. You can get a list of engines of your MySQL implementation by using
  102. </p><pre class="screen">&gt; <strong class="userinput"><code>show engines;</code></strong></pre><p>
  103. in your mysql client. Two notable engines are MyISAM and InnoDB. mysql_ubench uses
  104. use MyISAM for synchronous mode and InnoDB for asynchronous. Please use
  105. '-s yes|no' to choose whether you want synchronous or asynchronous operations.</p><p>Another parameter that affects performance are precompiled statements.
  106. In a basic approach, the actual SQL query is passed as a text string that is
  107. then parsed by the database engine. Alternative is a so called precompiled
  108. statement. In this approach the SQL query is compiled an specific values are being
  109. bound to it. In the next iteration the query remains the same, only bound values
  110. are changing (e.g. searching for a different address). Usage of basic or precompiled
  111. statements is controlled with '-c no|yes'.</p></div></div><div class="section" title="3.3. SQLite-ubench"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="sqlite-ubench"></a>3.3. SQLite-ubench</h2></div></div></div><p>The SQLite backend requires both the sqlite3 development and run-time packages. Their
  112. names may vary from system to system, but on Ubuntu 12.04 they are called
  113. sqlite3 libsqlite3-dev. To install them, use the following command:
  114. </p><pre class="screen">&gt; <strong class="userinput"><code>sudo apt-get install sqlite3 libsqlite3-dev</code></strong></pre><p>
  115. Before running the test the database has to be created. Use the following command for that:
  116. </p><pre class="screen">&gt; <strong class="userinput"><code>cat sqlite.schema | sqlite3 sqlite.db</code></strong></pre><p>
  117. A new database called sqlite.db will be created. That is the default name used
  118. by sqlite_ubench test. If you prefer other name, make sure you update
  119. sqlite_ubench.cc accordingly.</p><p>Once the database is created, you can run tests:
  120. </p><pre class="screen">&gt; <strong class="userinput"><code>./sqlite_ubench</code></strong></pre><p>
  121. or
  122. </p><pre class="screen">&gt; <strong class="userinput"><code>./sqlite_ubench &gt; results-sqlite.txt</code></strong></pre><p>
  123. </p><div class="section" title="3.3.1. SQLite tweaks"><div class="titlepage"><div><div><h3 class="title"><a name="sqlite-tweaks"></a>3.3.1. SQLite tweaks</h3></div></div></div><p>To modify default sqlite_ubench parameters, command line
  124. switches can be used. The currently supported switches are
  125. (default values specified in brackets):
  126. </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>-f filename - name of the database file ("sqlite.db")</p></li><li class="listitem"><p>-n num - number of iterations (100)</p></li><li class="listitem"><p>-s yes|no - should the operations be performed in a synchronous (yes)
  127. or asynchronous (no) manner (yes)</p></li><li class="listitem"><p>-v yes|no - verbose mode. Should the test print out progress? (yes)</p></li><li class="listitem"><p>-c yes|no - precompiled statements. Should the SQL statements be precompiled? (yes)</p></li></ol></div><p>
  128. </p><p>SQLite can run in asynchronous or synchronous mode. This
  129. mode can be controlled by using "synchronous" parameter. It is set
  130. using the SQLite command:</p><p><span class="command"><strong>PRAGMA synchronous = ON|OFF</strong></span></p><p>Another tweakable feature is journal mode. It can be
  131. turned to several modes of operation. Its value can be
  132. modified in SQLite_uBenchmark::connect(). See
  133. http://www.sqlite.org/pragma.html#pragma_journal_mode for
  134. detailed explanantion.</p><p>sqlite_bench supports precompiled statements. Please use
  135. '-c no|yes' to define which should be used: basic SQL query (no) or
  136. precompiled statement (yes).</p></div></div><div class="section" title="3.4. memfile-ubench"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="memfile-ubench"></a>3.4. memfile-ubench</h2></div></div></div><p>The memfile backend is a
  137. custom backend that somewhat mimics operation of ISC DHCP4. It
  138. implements in-memory storage using standard C++ and boost
  139. mechanisms (std::map and boost::shared_ptr&lt;&gt;). All
  140. database changes are also written to a lease file, which is
  141. strictly write-only. This approach takes advantage of the fact
  142. that file append operation is faster than modifications introduced
  143. in the middle of the file (as it often requires moving all data
  144. after modified point, effectively requiring writing large parts of
  145. the whole file, not just changed fragment).</p><p>There are no preparatory steps required for memfile benchmark.
  146. The only requirement is the ability to create and write specified lease
  147. file (dhcpd.leases in the current directory). The tests can be run
  148. as follows:
  149. </p><pre class="screen">&gt; <strong class="userinput"><code>./memfile_ubench</code></strong></pre><p>
  150. or
  151. </p><pre class="screen">&gt; <strong class="userinput"><code>./memfile_ubench &gt; results-memfile.txt</code></strong></pre><p>
  152. </p><div class="section" title="3.4.1. memfile tweaks"><div class="titlepage"><div><div><h3 class="title"><a name="memfile-tweaks"></a>3.4.1. memfile tweaks</h3></div></div></div><p>To modify default memfile_ubench parameters, command line
  153. switches can be used. Currently supported switches are
  154. (default values specified in brackets):
  155. </p><div class="orderedlist"><ol class="orderedlist" type="1"><li class="listitem"><p>-f filename - name of the database file ("dhcpd.leases")</p></li><li class="listitem"><p>-n num - number of iterations (100)</p></li><li class="listitem"><p>-s yes|no - should the operations be performend in a synchronous (yes)
  156. or asynchronous (no) manner (yes)</p></li><li class="listitem"><p>-v yes|no - verbose mode. Should the test print out progress? (yes)</p></li></ol></div><p>
  157. </p><p>memfile can run in asynchronous or synchronous mode. This
  158. mode can be controlled by using sync parameter. It uses
  159. fflush() and fsync() in synchronous mode to make sure that
  160. data is not buffered and physically stored on disk.</p></div></div><div class="section" title="3.5. Basic performance measurements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp104752"></a>3.5. Basic performance measurements</h2></div></div></div><p>This section contains sample results for backend performance measurements,
  161. taken using microbenchmarks. Tests were conducted on reasonably powerful machine:
  162. </p><pre class="screen">
  163. CPU: Quad-core Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz (8 logical cores)
  164. HDD: 1,5TB Seagate Barracuda ST31500341AS 7200rpm, ext4 partition
  165. OS: Ubuntu 12.04, running kernel 3.2.0-26-generic SMP x86_64
  166. compiler: g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
  167. MySQL version: 5.5.24
  168. SQLite version: 3.7.9sourceid version is 2011-11-01 00:52:41 c7c6050ef060877ebe77b41d959e9df13f8c9b5e</pre><p>
  169. </p><p>The benchmarks were run without using precompiled statements.
  170. The code was compiled with the -O0 flag (no code optimizations).
  171. Each run was executed once.</p><p>Two series of measures were made, synchronous and
  172. asynchronous. As those modes offer radically different
  173. performances, synchronous mode was conducted for one
  174. thousand repetitions and asynchronous mode was conducted for
  175. one hundred thousand repetitions.</p><div class="table"><a name="idp108384"></a><p class="title"><b>Table 3.1. Synchronous results (basic)</b></p><div class="table-contents"><table summary="Synchronous results (basic)" border="1"><colgroup><col align="center" class="Backend"><col align="center" class="Num"><col align="center" class="Create"><col align="center" class="Search"><col align="center" class="Update"><col align="center" class="Delete"></colgroup><thead><tr><th align="center">Backend</th><th align="center">Operations</th><th align="center">Create [s]</th><th align="center">Search [s]</th><th align="center">Update [s]</th><th align="center">Delete [s]</th><th align="center">Average [s]</th></tr></thead><tbody><tr><td align="center">MySQL</td><td align="center">1,000</td><td align="center">31.604</td><td align="center"> 0.117</td><td align="center">27.964</td><td align="center">27.695</td><td align="center">21.845</td></tr><tr><td align="center">SQLite</td><td align="center">1,000</td><td align="center">61.421</td><td align="center"> 0.033</td><td align="center">59.477</td><td align="center">56.034</td><td align="center">44.241</td></tr><tr><td align="center">memfile</td><td align="center">1,000</td><td align="center">38.224</td><td align="center"> 0.001</td><td align="center">38.041</td><td align="center">38.017</td><td align="center">28.571</td></tr></tbody></table></div></div><br class="table-break"><p>The following parameters were measured for asynchronous mode.
  176. MySQL and SQLite were run with one hundred thousand repetitions.</p><div class="table"><a name="idp129440"></a><p class="title"><b>Table 3.2. Asynchronous results (basic)</b></p><div class="table-contents"><table summary="Asynchronous results (basic)" border="1"><colgroup><col align="center" class="Backend"><col align="center" class="Num"><col align="center" class="Create"><col align="center" class="Search"><col align="center" class="Update"><col align="center" class="Delete"></colgroup><thead><tr><th align="center">Backend</th><th align="center">Operations</th><th align="center">Create [s]</th><th align="center">Search [s]</th><th align="center">Update [s]</th><th align="center">Delete [s]</th><th align="center">Average [s]</th></tr></thead><tbody><tr><td align="center">MySQL</td><td align="center">100,000</td><td align="center">10.585</td><td align="center">10.386</td><td align="center">10.062</td><td align="center"> 8.890</td><td align="center"> 9.981</td></tr><tr><td align="center">SQLite</td><td align="center">100,000</td><td align="center"> 3.710</td><td align="center"> 3.159</td><td align="center"> 2.865</td><td align="center"> 2.439</td><td align="center"> 3.044</td></tr><tr><td align="center">memfile</td><td align="center">100,000</td><td align="center"> 1.300</td><td align="center"> 0.039</td><td align="center"> 1.307</td><td align="center"> 1.278</td><td align="center"> 0.981</td></tr></tbody></table></div></div><br class="table-break"><p>The presented performance results can be converted into operations per second metrics.
  177. It should be noted that due to large differences between various operations (sometimes
  178. over three orders of magnitude), it is difficult to create a simple, readable chart with
  179. that data.</p><div class="table"><a name="tbl-basic-perf-results"></a><p class="title"><b>Table 3.3. Estimated basic performance</b></p><div class="table-contents"><table summary="Estimated basic performance" border="1"><colgroup><col align="center" class="Backend"><col align="center" class="Create"><col align="center" class="Search"><col align="center" class="Update"><col align="center" class="Delete"><col align="center" class="Average"></colgroup><thead><tr><th align="center">Backend</th><th align="center">Create [oper/s]</th><th align="center">Search [oper/s]</th><th align="center">Update [oper/s]</th><th align="center">Delete [oper/s]</th><th align="center">Average [oper/s]</th></tr></thead><tbody><tr><td align="center">MySQL (async)</td><td align="center">9447.47</td><td align="center">9627.97</td><td align="center">9938.00</td><td align="center">11248.34</td><td align="center">10065.45</td></tr><tr><td align="center">SQLite (async)</td><td align="center">26951.59</td><td align="center">31654.29</td><td align="center">34899.70</td><td align="center">40993.59</td><td align="center">33624.79</td></tr><tr><td align="center">memfile (async)</td><td align="center">76944.27</td><td align="center">2542588.35</td><td align="center">76504.54</td><td align="center">78269.25</td><td align="center">693576.60</td></tr><tr><td align="center">MySQL (sync)</td><td align="center">31.64</td><td align="center">8575.45</td><td align="center">35.76</td><td align="center">36.11</td><td align="center">2169.74</td></tr><tr><td align="center">SQLite (sync)</td><td align="center">16.28</td><td align="center">20045.37</td><td align="center">16.81</td><td align="center">17.85</td><td align="center">7524.08</td></tr><tr><td align="center">memfile (sync)</td><td align="center">26.16</td><td align="center">1223990.21</td><td align="center">26.29</td><td align="center">26.30</td><td align="center">306017.24</td></tr></tbody></table></div></div><br class="table-break"><div class="mediaobject"><img src="performance-results-graph1.png"><div class="caption"><p>Graphical representation of the basic performance results
  180. presented in table <a class="xref" href="#tbl-basic-perf-results" title="Table 3.3. Estimated basic performance">Table 3.3, &#8220;Estimated basic performance&#8221;</a>.</p></div></div></div><div class="section" title="3.6. Optimized performance measurements"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idm38464"></a>3.6. Optimized performance measurements</h2></div></div></div><p>This section contains sample results for backend performance measurements,
  181. taken using microbenchmarks. Tests were conducted on reasonably powerful machine:
  182. </p><pre class="screen">
  183. CPU: Quad-core Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz (8 logical cores)
  184. HDD: 1,5TB Seagate Barracuda ST31500341AS 7200rpm, ext4 partition
  185. OS: Ubuntu 12.04, running kernel 3.2.0-26-generic SMP x86_64
  186. compiler: g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
  187. MySQL version: 5.5.24
  188. SQLite version: 3.7.9sourceid version is 2011-11-01 00:52:41 c7c6050ef060877ebe77b41d959e9df13f8c9b5e</pre><p>
  189. </p><p>The benchmarks were run with precompiled statements enabled.
  190. The code was compiled with the -Ofast flag (optimize compilation for speed).
  191. Each run was repeated three times and measured values were averaged.</p><p>Again the benchmarks were run in two series, synchronous and
  192. asynchronous. As those modes offer radically different
  193. performances, synchronous mode was conducted for one
  194. thousand repetitions and asynchronous mode was conducted for
  195. one hundred thousand repetitions.</p><div class="table"><a name="idp204944"></a><p class="title"><b>Table 3.4. Synchronous results (optimized)</b></p><div class="table-contents"><table summary="Synchronous results (optimized)" border="1"><colgroup><col align="center" class="Backend"><col align="center" class="Num"><col align="center" class="Create"><col align="center" class="Search"><col align="center" class="Update"><col align="center" class="Delete"></colgroup><thead><tr><th align="center">Backend</th><th align="center">Operations</th><th align="center">Create [s]</th><th align="center">Search [s]</th><th align="center">Update [s]</th><th align="center">Delete [s]</th><th align="center">Average [s]</th></tr></thead><tbody><tr><td align="center">MySQL</td><td align="center">1,000</td><td align="center">27.887</td><td align="center"> 0.106</td><td align="center">28.223</td><td align="center">27.696</td><td align="center">20.978</td></tr><tr><td align="center">SQLite</td><td align="center">1,000</td><td align="center">61.299</td><td align="center"> 0.015</td><td align="center">59.648</td><td align="center">61.098</td><td align="center">45.626</td></tr><tr><td align="center">memfile</td><td align="center">1,000</td><td align="center">39.564</td><td align="center"> 0.001</td><td align="center">39.543</td><td align="center">39.326</td><td align="center">29.608</td></tr></tbody></table></div></div><br class="table-break"><p>The following parameters were measured for asynchronous mode.
  196. MySQL and SQLite were run with one hundred thousand repetitions.</p><div class="table"><a name="idp225424"></a><p class="title"><b>Table 3.5. Asynchronous results (optimized)</b></p><div class="table-contents"><table summary="Asynchronous results (optimized)" border="1"><colgroup><col align="center" class="Backend"><col align="center" class="Num"><col align="center" class="Create"><col align="center" class="Search"><col align="center" class="Update"><col align="center" class="Delete"></colgroup><thead><tr><th align="center">Backend</th><th align="center">Operations</th><th align="center">Create [s]</th><th align="center">Search [s]</th><th align="center">Update [s]</th><th align="center">Delete [s]</th><th align="center">Average [s]</th></tr></thead><tbody><tr><td align="center">MySQL</td><td align="center">100,000</td><td align="center">8.507</td><td align="center">9.698</td><td align="center">7.785</td><td align="center">8.326</td><td align="center">8.579</td></tr><tr><td align="center">SQLite</td><td align="center">100,000</td><td align="center"> 1.562</td><td align="center"> 0.949</td><td align="center"> 1.513</td><td align="center"> 1.502</td><td align="center"> 1.382</td></tr><tr><td align="center">memfile</td><td align="center">100,000</td><td align="center">1.302</td><td align="center">0.038</td><td align="center">1.306</td><td align="center">1.263</td><td align="center">0.977</td></tr></tbody></table></div></div><br class="table-break"><p>The presented performance results can be converted into operations per second metrics.
  197. It should be noted that due to large differences between various operations (sometime
  198. over three orders of magnitude), it is difficult to create a simple, readable chart with
  199. the data.</p><div class="table"><a name="tbl-optim-perf-results"></a><p class="title"><b>Table 3.6. Estimated optimized performance</b></p><div class="table-contents"><table summary="Estimated optimized performance" border="1"><colgroup><col align="center" class="Backend"><col align="center" class="Create"><col align="center" class="Search"><col align="center" class="Update"><col align="center" class="Delete"><col align="center" class="Average"></colgroup><thead><tr><th align="center">Backend</th><th align="center">Create [oper/s]</th><th align="center">Search [oper/s]</th><th align="center">Update [oper/s]</th><th align="center">Delete [oper/s]</th><th align="center">Average [oper/s]</th></tr></thead><tbody><tr><td align="center">MySQL (async)</td><td align="center">11754.84</td><td align="center">10311.34</td><td align="center">12845.35</td><td align="center">12010.24</td><td align="center">11730.44</td></tr><tr><td align="center">SQLite (async)</td><td align="center">64005.90</td><td align="center">105391.29</td><td align="center">66075.51</td><td align="center">66566.43</td><td align="center">75509.78</td></tr><tr><td align="center">memfile (async)</td><td align="center">76832.16</td><td align="center">2636018.56</td><td align="center">76542.50</td><td align="center">79188.81</td><td align="center">717145.51</td></tr><tr><td align="center">MySQL (sync)</td><td align="center">35.86</td><td align="center">9461.10</td><td align="center">35.43</td><td align="center">36.11</td><td align="center">2392.12</td></tr><tr><td align="center">SQLite (sync)</td><td align="center">16.31</td><td align="center">67036.11</td><td align="center">16.76</td><td align="center">16.37</td><td align="center">16771.39</td></tr><tr><td align="center">memfile (sync)</td><td align="center">25.28</td><td align="center">3460207.61</td><td align="center">25.29</td><td align="center">25.43</td><td align="center">865070.90</td></tr></tbody></table></div></div><br class="table-break"><div class="mediaobject"><img src="performance-results-graph2.png" alt="Optimized performance measurements"><div class="caption"><p>Graphical representation of the optimized performance
  200. results presented in table <a class="xref" href="#tbl-optim-perf-results" title="Table 3.6. Estimated optimized performance">Table 3.6, &#8220;Estimated optimized performance&#8221;</a>.</p></div></div></div><div class="section" title="3.7. Conclusions"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp275344"></a>3.7. Conclusions</h2></div></div></div><p>
  201. Improvements gained by introducing support for precompiled
  202. statements in MySQL is somewhat disappointing - between 6 and
  203. 29%. On the other hand, the improvement in SQLite is
  204. surprisingly high - the efficiency is more than doubled.
  205. </p><p>
  206. Compiled statements do not have any measureable impact on
  207. synchronous operations. That is as expected, because the major
  208. bottleneck is the disk performance.
  209. </p><p>
  210. Compilation flags yield surprisingly high improvements for C++
  211. STL code. The memfile backend is in some operations is almost
  212. twice as fast.
  213. </p><p>
  214. If synchronous operation is required, the current performance
  215. results are likely to be deemed inadequate. The limiting
  216. factor here is a disk access time. Even migrating to high
  217. performance 15,000 rpm disk is expected to only roughly double
  218. number of leases per second, compared to the current results.
  219. The reason is that to write a file to disk, at least two disk
  220. sector writes
  221. are required: the new content and i-node modification of the
  222. file. The easiest way to boost synchronous performance is to
  223. switch to SSD disks. Memory-backed RAM disks are also a viable
  224. solution. However, care should be taken to properly engineer
  225. backup strategy for such RAM disks.
  226. </p><p>
  227. While the custom made backend (memfile) provides the best
  228. perfomance, it carries over all the limitations existing in
  229. the ISC DHCP4 code: there are no external tools to query or
  230. change database, the maintenance requires deep knowledge etc.
  231. Those flaws are not shared by usage of a proper database
  232. backend, like MySQL and SQLite. They both offer third party
  233. tools for administrative tasks, they are well documented and
  234. maintained. However, SQLite support for concurrent access is
  235. limiting in certain cases. Since all three investigated
  236. backends more than meet expected performance results, it is
  237. recommended to use MySQL as a first concrete database backend.
  238. Should this choice be rejected for any reason, the second
  239. recommended choice is SQLite.
  240. </p><p>
  241. It should be emphaisized that obtained measurements indicate
  242. only database performance and they cannot be directly
  243. translated to expected leases per second or queries per second
  244. performance by an actual server. The DHCP server must do much
  245. more than just query the database to properly process client's
  246. message. The provided results should be considered as only rough
  247. estimates. They can also be used for relative comparisons
  248. between backends.
  249. </p></div><div class="section" title="3.8. Possible further optimizations"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="idp281328"></a>3.8. Possible further optimizations</h2></div></div></div><p>
  250. For basic measurements the code was compiled with -g -O0
  251. flags. For optimized measurements the benchmarking code was
  252. compiled with -Ofast (optimize for speed). In both cases, the
  253. same backend (MySQL or SQLite) library was used. It may be
  254. useful to recompile the libraries (or the whole server in case
  255. of MySQL) with -Ofast.
  256. </p><p>
  257. There are many MySQL parameters that various sources recommend
  258. to improve performance. They were not investigated further.
  259. </p><p>
  260. Currently all operations are conducted on one by one
  261. basis. Each operation is treated as a separate
  262. transaction. Grouping N operations together will potentially
  263. bring almost N fold increase in synchronous operations. Such a
  264. feature is present in ISC DHCP4 and is called cache-threshold.
  265. Extension for this benchmark in this regard should be
  266. considered. That affects only write operations (insert,
  267. update and delete). Read operations (search) are expected to
  268. be barely affected.
  269. </p><p>
  270. Multi-threaded or multi-process benchmark may be considered in
  271. the future. It may be somewhat difficult as only some backends
  272. support concurrent access.
  273. </p></div></div><div class="chapter" title="Chapter 4. perfdhcp"><div class="titlepage"><div><div><h2 class="title"><a name="perfdhcp"></a>Chapter 4. perfdhcp</h2></div></div></div><p>
  274. TODO: Write something about perfdhcp here.
  275. </p></div></div></body></html>