dhcp-perf-guide.xml 43 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065
  1. <?xml version="1.0" encoding="UTF-8"?>
  2. <!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.2//EN"
  3. "http://www.oasis-open.org/docbook/xml/4.2/docbookx.dtd" [
  4. <!ENTITY mdash "&#x2014;" >
  5. <!ENTITY % version SYSTEM "version.ent">
  6. %version;
  7. ]>
  8. <!--
  9. - Copyright (C) 2012 Internet Systems Consortium, Inc. ("ISC")
  10. -
  11. - Permission to use, copy, modify, and/or distribute this software for any
  12. - purpose with or without fee is hereby granted, provided that the above
  13. - copyright notice and this permission notice appear in all copies.
  14. -
  15. - THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
  16. - REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
  17. - AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
  18. - INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
  19. - LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
  20. - OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
  21. - PERFORMANCE OF THIS SOFTWARE.
  22. -->
  23. <?xml-stylesheet href="bind10-guide.css" type="text/css"?>
  24. <book>
  25. <bookinfo>
  26. <title>DHCP Performance Guide</title>
  27. <!-- <subtitle>Various aspects of DHCP Performance in BIND 10</subtitle> -->
  28. <copyright>
  29. <year>2012</year>
  30. <holder>Internet Systems Consortium, Inc. ("ISC")</holder>
  31. </copyright>
  32. <author>
  33. <firstname>Tomasz</firstname>
  34. <surname>Mrugalski</surname>
  35. </author>
  36. <author>
  37. <firstname>Marcin</firstname>
  38. <surname>Siodelski</surname>
  39. </author>
  40. <abstract>
  41. <para>BIND 10 is a framework that features Domain Name System
  42. (DNS) suite and Dynamic Host Configuration Protocol (DHCP)
  43. servers with development managed by Internet Systems Consortium (ISC).
  44. This document describes various aspects of DHCP performance,
  45. measurements and tuning. It covers BIND 10 DHCP (codename Kea),
  46. existing ISC DHCP4 software, perfdhcp (a DHCP performance
  47. measurement tool) and other related topics.</para>
  48. </abstract>
  49. <releaseinfo>This is a companion document for BIND 10 version
  50. &__VERSION__;.</releaseinfo>
  51. </bookinfo>
  52. <preface>
  53. <title>Preface</title>
  54. <section id="acknowledgements">
  55. <title>Acknowledgements</title>
  56. <para>ISC would like to acknowledge generous support for
  57. BIND 10 development of DHCPv4 and DHCPv6 components provided
  58. by <ulink url="http://www.comcast.com/">Comcast</ulink>.</para>
  59. </section>
  60. </preface>
  61. <chapter id="intro">
  62. <title>Introduction</title>
  63. <para>
  64. This document is in its early stages of development. It is
  65. expected to grow significantly in a near future. It will
  66. cover topics like database backend perfomance measurements,
  67. pros an cons of various optimization techniques and
  68. tools.
  69. </para>
  70. </chapter>
  71. <chapter id="dhcp4">
  72. <title>ISC DHCP 4.x</title>
  73. <para>
  74. TODO: Write something about ISC DHCP4 here.
  75. </para>
  76. </chapter>
  77. <chapter id="kea">
  78. <title>Kea</title>
  79. <para>
  80. </para>
  81. <section>
  82. <title>Backend performance evaluation</title>
  83. <para>
  84. Kea will support several different database backends, using
  85. both popular databases (like MySQL or SQLite) and
  86. custom-developed solutions (like in-memory database). BIND 10
  87. source code features set of performance microbenchmarks.
  88. These are small tools written in C/C++ that simulate expected
  89. DHCP server behaviour and evaluate the performance of
  90. considered databases. As implemented benchmarks are not really
  91. simulating DHCP operation, but rather use set of primitives
  92. that can be used by a real server, they are called
  93. micro-benchmarks.
  94. </para>
  95. <para>Although there are many operations and data types that
  96. server could store in a database, the most frequently used data
  97. type is lease information. Although lease information for IPv4
  98. and IPv6 differs slightly, it is expected that the performance
  99. differences will be minimal between IPv4 and IPv6 lease operations.
  100. Therefore each test uses lease4 table for performance measurements.
  101. </para>
  102. <para>All benchmarks are implemented as single threaded applications
  103. that take advantage of a single database connection.</para>
  104. <para>
  105. Those benchmarks are stored in tests/tools/dhcp-ubench
  106. directory. This directory contains simplified prototypes for
  107. various DB back-ends that are planned or considered as a
  108. backend engine for BIND10 DHCP. Athough trivial now, they are
  109. expected to evolve into useful tools that will allow users to
  110. measure performance in their specific environment.
  111. </para>
  112. <para>
  113. Currently the following benchmarks are implemented:
  114. <itemizedlist>
  115. <listitem><para>in memory+flat file</para></listitem>
  116. <listitem><para>SQLite</para></listitem>
  117. <listitem><para>MySQL</para></listitem>
  118. </itemizedlist>
  119. </para>
  120. <para>
  121. As they require additional (sometimes heavy) dependencies, they are not
  122. built by default. Actually, their build system is completely separated.
  123. It will be eventually merged with the main BIND10 makefile system, but
  124. that is a low priority for now.
  125. </para>
  126. <para>
  127. All benchmarks will follow the same pattern:
  128. <orderedlist>
  129. <listitem><para>prepare operation (connect to a database, create a file etc.)</para></listitem>
  130. <listitem><para>Measure timestamp 0</para></listitem>
  131. <listitem><para>Commit new lease4 (repeated X times)</para></listitem>
  132. <listitem><para>Measure timestamp 1</para></listitem>
  133. <listitem><para>Search for random lease4 (repeated X times)</para></listitem>
  134. <listitem><para>Measure timestamp 2</para></listitem>
  135. <listitem><para>Update existing lease4 (repeated X times)</para></listitem>
  136. <listitem><para>Measure timestamp 3</para></listitem>
  137. <listitem><para>Delete existing lease4 (repeated X times)</para></listitem>
  138. <listitem><para>Measure timestamp 4</para></listitem>
  139. <listitem><para>Print out statistics, based on X and measured timestamps.</para></listitem>
  140. </orderedlist>
  141. Although this approach does not attempt to simulate actual DHCP server
  142. operation that has mix of all steps intervening, it answers the
  143. questions about basic database strenghts and weak points. In particular
  144. it can show what is the impact of specific DB optimizations, like
  145. changing engine, optimizing for writes/reads etc.
  146. </para>
  147. <para>
  148. The framework attempts to do the same amount of operations for every
  149. backend thus allowing fair complarison between them.
  150. </para>
  151. </section>
  152. <section id="mysql-backend">
  153. <title>MySQL backend</title>
  154. <para>MySQL backend requires MySQL client development libraries. It uses
  155. mysql_config tool (that works similar to pkg-config) to discover required
  156. compilation and linking options. To install required packages on Ubuntu,
  157. use the following command:
  158. <screen>$ <userinput>sudo apt-get install mysql-client mysql-server libmysqlclient-dev</userinput></screen>
  159. Make sure that MySQL server is running. Make sure that you have your setup
  160. configured so there is a user that is able to modify used database.</para>
  161. <para>Before running tests, you need to initialize your database. You can
  162. use mysql.schema script for that purpose. WARNING: It will drop existing
  163. Kea database. Do not run this on your production server. Assuming your
  164. MySQL user is kea, you can initialize your test database by:
  165. <screen>$ <userinput>mysql -u kea -p &lt; mysql.schema</userinput></screen>
  166. </para>
  167. <para>After database is initialized, you are ready to run the test:
  168. <screen>$ <userinput>./mysql_ubench</userinput></screen>
  169. or
  170. <screen>$ <userinput>./mysql_ubench &gt; results->mysql.txt</userinput></screen>
  171. Redirecting output to a file is important, because for each operation
  172. there is a single character printed to show progress. If you have a slow
  173. terminal, this may considerably affect test perfromance. On the other hand,
  174. printing something after each operation is required, as poor DB setting
  175. may slow down operations to around 20 per second. Observant user is expected
  176. to note that initial dots are printed too slowly and abort the test.</para>
  177. <para>Currently all default parameters are hardcoded. Default values can be
  178. overwritten using command line switches. Although all benchmarks take
  179. the same list of parameters, some of them are specific to a given backend
  180. type. To get a list of supported parameters, run your benchmark with -h option:
  181. <screen>$ <userinput>./mysql_ubench -h</userinput>
  182. This is a benchmark designed to measure expected performance
  183. of several backends. This particular version identifies itself
  184. as following:
  185. MySQL client version is 5.5.24
  186. Possible command-line parameters:
  187. -h - help (you are reading this)
  188. -m hostname - specifies MySQL server to connect (MySQL backend only)
  189. -u username - specifies MySQL user name (MySQL backend only)
  190. -p password - specifies MySQL passwod (MySQL backend only)
  191. -f name - database or filename (MySQL, SQLite and memfile)
  192. -n integer - number of test repetitions (MySQL, SQLite and memfile)
  193. -s yes|no - synchronous/asynchronous operation (MySQL, SQLite and memfile)
  194. -v yes|no - verbose mode (MySQL, SQLite and memfile)
  195. -c yes|no - should compiled statements be used (MySQL only)
  196. </screen>
  197. </para>
  198. <section>
  199. <title>MySQL tweaks</title>
  200. <para>One parameter that has huge impact on performance is a a backend engine.
  201. You can get a list of engines of your MySQL implementation by using
  202. <screen>&gt; <userinput>show engines;</userinput></screen>
  203. in your mysql client. Two notable engines are MyISAM and InnoDB. mysql_ubench will
  204. use MyISAM for synchronous mode and InnoDB for asynchronous.</para>
  205. </section>
  206. </section>
  207. <section id="sqlite-ubench">
  208. <title>SQLite-ubench</title>
  209. <para>SQLite backend requires both sqlite3 development and run-time package. Their
  210. names may vary from system to system, but on Ubuntu 12.04 they are called
  211. sqlite3 libsqlite3-dev. To install them, use the following command:
  212. <screen>&gt; <userinput>sudo apt-get install sqlite3 libsqlite3-dev</userinput></screen>
  213. Before running the test the database has to be created. Use the following command for that:
  214. <screen>&gt; <userinput>cat sqlite.schema | sqlite3 sqlite.db</userinput></screen>
  215. A new database called sqlite.db will be created. That is the default name used
  216. by sqlite_ubench test. If you prefer other name, make sure you update
  217. sqlite_ubench.cc accordingly.</para>
  218. <para>Once the database is created, you can run tests:
  219. <screen>&gt; <userinput>./sqlite_ubench</userinput></screen>
  220. or
  221. <screen>&gt; <userinput>./sqlite_ubench > results-sqlite.txt</userinput></screen>
  222. </para>
  223. <section id="sqlite-tweaks">
  224. <title>SQLite tweaks</title>
  225. <para>To modify default sqlite_ubench parameters, command line
  226. switches can be used. Currently supported parameters are
  227. (default values specified in brackets):
  228. <orderedlist>
  229. <listitem><para>-f filename - name of the database file ("sqlite.db")</para></listitem>
  230. <listitem><para>-n num - number of iterations (100)</para></listitem>
  231. <listitem><para>-s yes|no - should the operations be performend in synchronous (yes)
  232. or asynchronous (no) manner (yes)</para></listitem>
  233. <listitem><para>-v yes|no - verbose mode. Should the test print out progress? (yes)</para></listitem>
  234. <listitem><para>-c yes|no - compiled statements. Should the SQL statements be precompiled?</para></listitem>
  235. </orderedlist>
  236. </para>
  237. <para>SQLite can run in asynchronous or synchronous mode. This
  238. mode can be controlled by using sync parameter. It is set
  239. using (PRAGMA synchronous = ON or OFF).</para>
  240. <para>Another tweakable feature is journal mode. It can be
  241. turned to several modes of operation. Its value can be
  242. modified in SQLite_uBenchmark::connect(). See
  243. http://www.sqlite.org/pragma.html#pragma_journal_mode for
  244. detailed explanantion.</para>
  245. </section>
  246. </section>
  247. <section id="memfile-ubench">
  248. <title>memfile-ubench</title>
  249. <para>Memfile backend is custom developed prototype backend that
  250. somewhat mimics operation of ISC DHCP4. It uses in-memory
  251. storage using standard C++ and boost mechanisms (std::map and
  252. boost::shared_ptr&lt;&gt;). All database changes are also
  253. written to a lease file. That file is strictly write-only. This
  254. approach takes advantage of the fact that simple append is faster
  255. than edition with potential whole file relocation.</para>
  256. <section id="memfile-tweaks">
  257. <title>memfile tweaks</title>
  258. <para>To modify default memfile_ubench parameters, command line
  259. switches can be used. Currently supported parameters are
  260. (default values specified in brackets):
  261. <orderedlist>
  262. <listitem><para>-f filename - name of the database file ("dhcpd.leases")</para></listitem>
  263. <listitem><para>-n num - number of iterations (100)</para></listitem>
  264. <listitem><para>-s yes|no - should the operations be performend in synchronous (yes)
  265. or asynchronous (no) manner (yes)</para></listitem>
  266. <listitem><para>-v yes|no - verbose mode. Should the test print out progress? (yes)</para></listitem>
  267. </orderedlist>
  268. </para>
  269. <para>memfile can run in asynchronous or synchronous mode. This
  270. mode can be controlled by using sync parameter. It uses
  271. fflush() and fsync() in synchronous mode to make sure that
  272. data is not buffered and physically stored on disk.</para>
  273. </section>
  274. </section>
  275. <section>
  276. <title>Performance measurements</title>
  277. <para>This section contains sample results for backend performance measurements,
  278. taken using microbenchmarks. Tests were conducted on reasonably powerful machine:
  279. <screen>
  280. CPU: Quad-core Intel(R) Core(TM) i7-2600K CPU @ 3.40GHz (8 logical cores)
  281. HDD: 1,5TB Seagate Barracuda ST31500341AS 7200rpm (used only one of them), ext4 partition
  282. OS: Ubuntu 12.04, running kernel 3.2.0-26-generic SMP x86_64
  283. compiler: g++ (Ubuntu/Linaro 4.6.3-1ubuntu5) 4.6.3
  284. MySQL version: 5.5.24
  285. SQLite version: 3.7.9sourceid version is 2011-11-01 00:52:41 c7c6050ef060877ebe77b41d959e9df13f8c9b5e</screen>
  286. </para>
  287. <para>Benchmarks were run in two series: synchronous and
  288. asynchronous. As those modes offer radically different
  289. performances, synchronous mode was conducted for 1000 (one
  290. thousand) repetitions and asynchronous mode was conducted for
  291. 100000 (hundred thousand) repetitions.</para>
  292. <!-- raw results sync -->
  293. <table><title>Synchronous results</title>
  294. <tgroup cols='6' align='center' colsep='1' rowsep='1'>
  295. <colspec colname='Backend'/>
  296. <colspec colname='Num' />
  297. <colspec colname='Create'/>
  298. <colspec colname='Search'/>
  299. <colspec colname='Update'/>
  300. <colspec colname='Delete'/>
  301. <colspec colname='Average'/>
  302. <thead>
  303. <row>
  304. <entry>Backend</entry>
  305. <entry>Operations</entry>
  306. <entry>Create</entry>
  307. <entry>Search</entry>
  308. <entry>Update</entry>
  309. <entry>Delete</entry>
  310. <entry>Average</entry>
  311. </row>
  312. </thead>
  313. <tbody>
  314. <row>
  315. <entry>MySQL</entry>
  316. <entry>1000</entry>
  317. <entry>31.603978s</entry>
  318. <entry> 0.116612s</entry>
  319. <entry>27.964191s</entry>
  320. <entry>27.695209s</entry>
  321. <entry>21.844998s</entry>
  322. </row>
  323. <row>
  324. <entry>SQLite</entry>
  325. <entry>1000</entry>
  326. <entry>61.421356s</entry>
  327. <entry> 0.033283s</entry>
  328. <entry>59.476638s</entry>
  329. <entry>56.034150s</entry>
  330. <entry>44.241357s</entry>
  331. </row>
  332. <row>
  333. <entry>memfile</entry>
  334. <entry>1000</entry>
  335. <entry>41.711886s</entry>
  336. <entry> 0.000724s</entry>
  337. <entry>42.267578s</entry>
  338. <entry>42.169679s</entry>
  339. <entry>31.537467s</entry>
  340. </row>
  341. </tbody>
  342. </tgroup>
  343. </table>
  344. <para>Following parameters were measured for asynchronous mode.
  345. MySQL and SQLite were run with 100 thousand repetitions. Memfile
  346. was run for 1 million repetitions due to much larger performance.</para>
  347. <!-- raw results async -->
  348. <table><title>Asynchronous results</title>
  349. <tgroup cols='6' align='center' colsep='1' rowsep='1'>
  350. <colspec colname='Backend'/>
  351. <colspec colname='Num' />
  352. <colspec colname='Create'/>
  353. <colspec colname='Search'/>
  354. <colspec colname='Update'/>
  355. <colspec colname='Delete'/>
  356. <colspec colname='Average'/>
  357. <thead>
  358. <row>
  359. <entry>Backend</entry>
  360. <entry>Operations</entry>
  361. <entry>Create [s]</entry>
  362. <entry>Search [s]</entry>
  363. <entry>Update [s]</entry>
  364. <entry>Delete [s]</entry>
  365. <entry>Average [s]</entry>
  366. </row>
  367. </thead>
  368. <tbody>
  369. <row>
  370. <entry>MySQL</entry>
  371. <entry>100000</entry>
  372. <entry>10.584842s</entry>
  373. <entry>10.386402s</entry>
  374. <entry>10.062384s</entry>
  375. <entry> 8.890197s</entry>
  376. <entry> 9.980956s</entry>
  377. </row>
  378. <row>
  379. <entry>SQLite</entry>
  380. <entry>100000</entry>
  381. <entry> 3.710356s</entry>
  382. <entry> 3.159129s</entry>
  383. <entry> 2.865354s</entry>
  384. <entry> 2.439406s</entry>
  385. <entry> 3.043561s</entry>
  386. </row>
  387. <row>
  388. <entry>memfile</entry>
  389. <entry>1000000 (sic!)</entry>
  390. <entry> 6.084131s</entry>
  391. <entry> 0.862667s</entry>
  392. <entry> 6.018585s</entry>
  393. <entry> 5.146704s</entry>
  394. <entry> 4.528022s</entry>
  395. </row>
  396. </tbody>
  397. </tgroup>
  398. </table>
  399. <para>Presented performance results can be computed into operations per second metrics.
  400. It should be noted that due to large differences between various operations (sometime
  401. over 3 orders of magnitude), it is difficult to create a simple, readable chart with
  402. that data.</para>
  403. <table id="tbl-perf-results"><title>Estimated performance</title>
  404. <tgroup cols='6' align='center' colsep='1' rowsep='1'>
  405. <colspec colname='Backend'/>
  406. <colspec colname='Create'/>
  407. <colspec colname='Search'/>
  408. <colspec colname='Update'/>
  409. <colspec colname='Delete'/>
  410. <colspec colname='Average'/>
  411. <thead>
  412. <row>
  413. <entry>Backend</entry>
  414. <entry>Create [oper/s]</entry>
  415. <entry>Search [oper/s]</entry>
  416. <entry>Update [oper/s]</entry>
  417. <entry>Delete [oper/s]</entry>
  418. <entry>Average [oper/s]</entry>
  419. </row>
  420. </thead>
  421. <tbody>
  422. <row>
  423. <entry>MySQL (async)</entry>
  424. <entry>9447.47</entry>
  425. <entry>9627.97</entry>
  426. <entry>9938.00</entry>
  427. <entry>11248.34</entry>
  428. <entry>10065.45</entry>
  429. </row>
  430. <row>
  431. <entry>SQLite (async)</entry>
  432. <entry>26951.59</entry>
  433. <entry>31654.29</entry>
  434. <entry>34899.70</entry>
  435. <entry>40993.59</entry>
  436. <entry>33624.79</entry>
  437. </row>
  438. <row>
  439. <entry>memfile (async)</entry>
  440. <entry>164362.01</entry>
  441. <entry>1159195.84</entry>
  442. <entry>166152.01</entry>
  443. <entry>194299.11</entry>
  444. <entry>421002.24</entry>
  445. </row>
  446. <row>
  447. <entry>MySQL (sync)</entry>
  448. <entry>31.64</entry>
  449. <entry>8575.45</entry>
  450. <entry>35.76</entry>
  451. <entry>36.11</entry>
  452. <entry>2169.74</entry>
  453. </row>
  454. <row>
  455. <entry>SQLite (sync)</entry>
  456. <entry>16.28</entry>
  457. <entry>20045.37</entry>
  458. <entry>16.81</entry>
  459. <entry>17.85</entry>
  460. <entry>7524.08</entry>
  461. </row>
  462. <row>
  463. <entry>memfile (sync)</entry>
  464. <entry>23.97</entry>
  465. <entry>1381215.47</entry>
  466. <entry>23.66</entry>
  467. <entry>23.71</entry>
  468. <entry>345321.70</entry>
  469. </row>
  470. </tbody>
  471. </tgroup>
  472. </table>
  473. <mediaobject>
  474. <imageobject>
  475. <imagedata fileref="performance-results-graph1.png" format="PNG"/>
  476. </imageobject>
  477. <textobject>
  478. <phrase>Performance measurements</phrase>
  479. </textobject>
  480. <caption>
  481. <para>Graphical representation of the performance results
  482. presented in table <xref linkend="tbl-perf-results" />.</para>
  483. </caption>
  484. </mediaobject>
  485. </section>
  486. <section>
  487. <title>Possible further optimizations</title>
  488. <para>
  489. For debugging purposes the code was compiled with -g -O0
  490. flags. While majority of the time was spent in backend
  491. functions (that was probably compiled with -O2 flags), the
  492. benchmark code could perform faster, when compiled with -O2,
  493. rather than -O0. That is expected to affect memfile benchmark.
  494. </para>
  495. <para>
  496. Currently all operations were conducted on one by one
  497. basis. Each operation was treated as a separate
  498. transaction. Grouping X operations together will potentially
  499. bring almost X fold increase in synchronous operations.
  500. Extension for this benchmark in this regard should be considered.
  501. That affects only write operations (insert, update and delete). Read
  502. operations (search) are expected to be barely affected.
  503. </para>
  504. <para>
  505. Multi-threaded or multi-process benchmark may be considered in
  506. the future. It may be somewhat difficult as only some backends
  507. support concurrent access.
  508. </para>
  509. </section>
  510. </chapter>
  511. <chapter id="perfdhcp">
  512. <title>perfdhcp</title>
  513. <section>
  514. <title>Purpose</title>
  515. <para>
  516. There is a growing need to evaluate performance of DHCP servers in
  517. different traffic conditions to understand their bottle necks.
  518. This helps to elimante bugs in existing DHCP software as well
  519. as make informed decisions regarding new DHCP software designs
  520. to significantly improve its performance. The perfdhcp tool has
  521. been created to fill the gap in performance measurement capabilities
  522. mostly. However, the number of implemented features and parameters
  523. exposed to the user make this tool useful for functional testing as
  524. well.
  525. </para>
  526. </section>
  527. <section id="perfdhcp-key-features">
  528. <title>Key features</title>
  529. <para>
  530. The perfdhcp exposes the number of command line parameters to
  531. control DHCP message exchanges. Currently they fall back to
  532. the following categories:
  533. <orderedlist>
  534. <listitem>
  535. <para>
  536. Rate control - control how many DHCP exchanges
  537. are initiated within a period of time. Tool can also simulate
  538. best effort conditions attempting to initiate as many DHCP
  539. packet exchanges within a unit of time as possible.
  540. </para>
  541. </listitem>
  542. <listitem>
  543. <para>
  544. Test exit specifiers - control the conditions when test
  545. completes including number of initiated exchanges, test period or
  546. maximum number of dropped packets.
  547. </para>
  548. </listitem>
  549. <listitem>
  550. <para>
  551. Packet templates - specify files containing packet templates that
  552. are used by perfdhcp to create custom DHCP messages instead of
  553. default. Tool also allows to specify number of values indicating
  554. offsets of variable values within a packet that are modified in
  555. flight by the tool.
  556. </para>
  557. </listitem>
  558. <listitem>
  559. <para>
  560. Reporting - for each test produce the set of performance data
  561. including achieved packet exchange rate (server performance).
  562. There is also a number of diagnostic selectors available that
  563. enable periodic (intermediate) reporting, packet timestamps
  564. printing and detailed information about perfdhcp internal
  565. states (for debugging).
  566. </para>
  567. </listitem>
  568. <listitem>
  569. <para>
  570. Different mode of operations - specify DHCP version used
  571. (v4 or v6), 2-way or 4-way exchanges, use Rapid Commit option
  572. for DHCPv6.
  573. </para>
  574. </listitem>
  575. <listitem>
  576. <para>
  577. IP layer options - specify local/remote address, local interface
  578. and local port to be used for communication with DHCP server.
  579. </para>
  580. </listitem>
  581. </orderedlist>
  582. </para>
  583. </section>
  584. <section id="perfdhcp-command-line">
  585. <title>Command line options</title>
  586. <para>
  587. The following command line options may be used with perfdhcp tool.
  588. This summary also presents its possible exit codes as well as
  589. error counters printed along when test is complete:
  590. <screen>$ <userinput>./perfdhcp -h</userinput>
  591. <![CDATA[perfdhcp [-hv] [-4|-6] [-r<rate>] [-t<report>] [-R<range>] [-b<base>]
  592. [-n<num-request>] [-p<test-period>] [-d<drop-time>] [-D<max-drop>]
  593. [-l<local-addr|interface>] [-P<preload>] [-a<aggressivity>]
  594. [-L<local-port>] [-s<seed>] [-i] [-B] [-c] [-1]
  595. [-T<template-file>] [-X<xid-offset>] [-O<random-offset]
  596. [-E<time-offset>] [-S<srvid-offset>] [-I<ip-offset>]
  597. [-x<diagnostic-selector>] [-w<wrapped>] [server]
  598. The [server] argument is the name/address of the DHCP server to
  599. contact. For DHCPv4 operation, exchanges are initiated by
  600. transmitting a DHCP DISCOVER to this address.
  601. For DHCPv6 operation, exchanges are initiated by transmitting a DHCP
  602. SOLICIT to this address. In the DHCPv6 case, the special name 'all'
  603. can be used to refer to All_DHCP_Relay_Agents_and_Servers (the
  604. multicast address FF02::1:2), or the special name 'servers' to refer
  605. to All_DHCP_Servers (the multicast address FF05::1:3). The [server]
  606. argument is optional only in the case that -l is used to specify an
  607. interface, in which case [server] defaults to 'all'.
  608. The default is to perform a single 4-way exchange, effectively pinging
  609. the server.
  610. The -r option is used to set up a performance test, without
  611. it exchanges are initiated as fast as possible.
  612. Options:
  613. -1: Take the server-ID option from the first received message.
  614. -4: DHCPv4 operation (default). This is incompatible with the -6 option.
  615. -6: DHCPv6 operation. This is incompatible with the -4 option.
  616. -a<aggressivity>: When the target sending rate is not yet reached,
  617. control how many exchanges are initiated before the next pause.
  618. -b<base>: The base mac, duid, IP, etc, used to simulate different
  619. clients. This can be specified multiple times, each instance is
  620. in the <type>=<value> form, for instance:
  621. (and default) mac=00:0c:01:02:03:04.
  622. -d<drop-time>: Specify the time after which a request is treated as
  623. having been lost. The value is given in seconds and may contain a
  624. fractional component. The default is 1 second.
  625. -E<time-offset>: Offset of the (DHCPv4) secs field / (DHCPv6)
  626. elapsed-time option in the (second/request) template.
  627. The value 0 disables it.
  628. -h: Print this help.
  629. -i: Do only the initial part of an exchange: DO or SA, depending on
  630. whether -6 is given.
  631. -I<ip-offset>: Offset of the (DHCPv4) IP address in the requested-IP
  632. option / (DHCPv6) IA_NA option in the (second/request) template.
  633. -l<local-addr|interface>: For DHCPv4 operation, specify the local
  634. hostname/address to use when communicating with the server. By
  635. default, the interface address through which traffic would
  636. normally be routed to the server is used.
  637. For DHCPv6 operation, specify the name of the network interface
  638. via which exchanges are initiated.
  639. -L<local-port>: Specify the local port to use
  640. (the value 0 means to use the default).
  641. -O<random-offset>: Offset of the last octet to randomize in the template.
  642. -P<preload>: Initiate first <preload> exchanges back to back at startup.
  643. -r<rate>: Initiate <rate> DORA/SARR (or if -i is given, DO/SA)
  644. exchanges per second. A periodic report is generated showing the
  645. number of exchanges which were not completed, as well as the
  646. average response latency. The program continues until
  647. interrupted, at which point a final report is generated.
  648. -R<range>: Specify how many different clients are used. With 1
  649. (the default), all requests seem to come from the same client.
  650. -s<seed>: Specify the seed for randomization, making it repeatable.
  651. -S<srvid-offset>: Offset of the server-ID option in the
  652. (second/request) template.
  653. -T<template-file>: The name of a file containing the template to use
  654. as a stream of hexadecimal digits.
  655. -v: Report the version number of this program.
  656. -w<wrapped>: Command to call with start/stop at the beginning/end of
  657. the program.
  658. -x<diagnostic-selector>: Include extended diagnostics in the output.
  659. <diagnostic-selector> is a string of single-keywords specifying
  660. the operations for which verbose output is desired. The selector
  661. keyletters are:
  662. * 'a': print the decoded command line arguments
  663. * 'e': print the exit reason
  664. * 'i': print rate processing details
  665. * 'r': print randomization details
  666. * 's': print first server-id
  667. * 't': when finished, print timers of all successful exchanges
  668. * 'T': when finished, print templates
  669. -X<xid-offset>: Transaction ID (aka. xid) offset in the template.
  670. DHCPv4 only options:
  671. -B: Force broadcast handling.
  672. DHCPv6 only options:
  673. -c: Add a rapid commit option (exchanges will be SA).
  674. The remaining options are used only in conjunction with -r:
  675. -D<max-drop>: Abort the test if more than <max-drop> requests have
  676. been dropped. Use -D0 to abort if even a single request has been
  677. dropped. If <max-drop> includes the suffix '%', it specifies a
  678. maximum percentage of requests that may be dropped before abort.
  679. In this case, testing of the threshold begins after 10 requests
  680. have been expected to be received.
  681. -n<num-request>: Initiate <num-request> transactions. No report is
  682. generated until all transactions have been initiated/waited-for,
  683. after which a report is generated and the program terminates.
  684. -p<test-period>: Send requests for the given test period, which is
  685. specified in the same manner as -d. This can be used as an
  686. alternative to -n, or both options can be given, in which case the
  687. testing is completed when either limit is reached.
  688. -t<report>: Delay in seconds between two periodic reports.
  689. Errors:
  690. - tooshort: received a too short message
  691. - orphans: received a message which doesn't match an exchange
  692. (duplicate, late or not related)
  693. - locallimit: reached to local system limits when sending a message.
  694. Exit status:
  695. The exit status is:
  696. 0 on complete success.
  697. 1 for a general error.
  698. 2 if an error is found in the command line arguments.
  699. 3 if there are no general failures in operation, but one or more
  700. exchanges are not successfully completed.
  701. ]]>
  702. </screen>
  703. </para>
  704. </section>
  705. <section id="starting-perfdhcp">
  706. <title>Starting perfdhcp</title>
  707. <para>
  708. In order to run performance test at least two separate systems
  709. have to be installed: client and server. The first one has to have
  710. perfdhcp tool installed, the latter has to have DHCP server
  711. running (v4 or v6). If only single system is available the client
  712. and server can be run on virtual machines (running on the same
  713. phisical system) but in this case performance data may be heavily
  714. impacted by the performance of VMs.
  715. </para>
  716. <para>
  717. The DHCP operates on low port numbers (67 for DHCPv4 relays and
  718. 547 for DHCPv6). Running perfdhcp with non-root priviliges will
  719. usually result in the error message similar to this:
  720. <screen><userinput>$./perfdhcp -4 -l eth3 -r 100 all</userinput>
  721. Error running perfdhcp: Failed to bind socket 3 to 172.16.1.2/port=67
  722. </screen>
  723. perfdhcp has the '-L' command line option that
  724. imposes use of custom local port. Thus the following command
  725. line will work:
  726. <screen><userinput>$./perfdhcp -4 -l eth3 -r 100 -L 10067 all</userinput></screen>
  727. but in the standard configuration no responses will be received
  728. from the ISC DHCP server because server responds to default relay
  729. port 67.
  730. Alternative way to overcome this issue is to run perfdhcp as root.
  731. </para>
  732. <para>
  733. Currently, perfdhcp is seen from the server perspective as relay agent.
  734. This simplifies its implementation (specifically there is no need to
  735. receive traffic sent to braodcast addresses). This imposes that IPv4
  736. address has to be set manually on the interface that will be used to
  737. communicate with the server. For example, if DHCPv4 server is listening
  738. on the interface connected to 172.16.1.0 subnet, interface on client
  739. machine has to have network address assigned from the same subnet
  740. on one of its interfaces connected to this subnet:
  741. <screen><userinput>#ifconfig eth3 172.16.1.2. netmask 255.255.255.0 up</userinput></screen>
  742. </para>
  743. </section>
  744. <section id="perfdhcp-commandline-examples">
  745. <title>perfdhcp command line examples</title>
  746. <para>
  747. In this section the perfdhcp command line examples
  748. are presented as a quick start guide for new users. For the
  749. detailed list of command line options refer to
  750. <xref linkend="perfdhcp-command-line"/>.
  751. </para>
  752. <section id="perfdhcp-basic-usage">
  753. <title>Example: basic usage</title>
  754. <para>
  755. If server is listening on interface with IPv4 address 172.16.1.1
  756. the simpliest perfdhcp command line will look like this:
  757. <screen><userinput>#./perfdhcp 172.16.1.1</userinput>
  758. ***Rate statistics***
  759. Rate: 206.345
  760. ***Statistics for: DISCOVER-OFFER***
  761. sent packets: 21641
  762. received packets: 350
  763. drops: 21291
  764. orphans: 0
  765. min delay: 9.022 ms
  766. avg delay: 143.100 ms
  767. max delay: 259.303 ms
  768. std deviation: 56.074 ms
  769. collected packets: 30
  770. ***Statistics for: REQUEST-ACK***
  771. sent packets: 350
  772. received packets: 268
  773. drops: 82
  774. orphans: 0
  775. min delay: 3.010 ms
  776. avg delay: 152.470 ms
  777. max delay: 258.634 ms
  778. std deviation: 56.936 ms
  779. collected packets: 0
  780. </screen>
  781. In this case perfdhcp will use remote address 172.16.1.1 as a
  782. destination address and will use suitable local interface for
  783. communication. Since, no rate control parameters have been specified
  784. it will be initiating DHCP exchanges with the maximum possible
  785. rate (it will try to initiate maximum number of exchanges per
  786. second and count number of completed exchanged). Due to server's
  787. performance constraints, many DHCP packets sent to server are likely
  788. to be dropped. The performance test will be running until it is
  789. not interrupted by the user (with ^C).
  790. </para>
  791. <para>
  792. The default performance statistics reported by perfdhcp have the
  793. following meaning:
  794. <itemizedlist>
  795. <listitem><para>Rate - number of packet exchanges (packet sent
  796. to the server and matching response received from the server)
  797. completed within a second.</para></listitem>
  798. <listitem><para>sent packets - total number of DHCP packets of
  799. a specific type sent to the server.</para></listitem>
  800. <listitem><para>received packets - total number of DHCP packets
  801. of specific type received from the server.</para></listitem>
  802. <listitem><para>drops - number of dropped packets for the
  803. particular exchange. Number of dropped packets is calculated as
  804. a difference between number of sent packets and number of
  805. response packets received from the server. It is likely that
  806. server sent the reponse but perfdhcp execution had ended before
  807. reponse arrived. In such case this packet will be assumed
  808. dropped.</para></listitem>
  809. <listitem><para>orphans - number of packets that have been
  810. received from the server and did not match any packet sent by
  811. perfdhcp. This may occur if received packet has been sent
  812. to some other host or if exchange time out has occured and
  813. has been been garbage collected.</para></listitem>
  814. <listitem><para>min delay - minimum delay that occured between
  815. sending the packet to the server and receiving reponse from
  816. it.</para></listitem>
  817. <listitem><para>avg delay - average delay between sending the
  818. packet of the specific type the server and receiving response
  819. from it.</para></listitem>
  820. <listitem><para>max delay - maximum delat that occured between
  821. sedning the packet to the server and receiveing response from
  822. it.</para></listitem>
  823. <listitem><para>std deviation - standard deviation of delay
  824. between sending the packet of a specific type to the server and
  825. receiving response from it.</para></listitem>
  826. <listitem><para>collected packets - number of garbage collected
  827. sent packets. Packets may get garbage collected when waiting time
  828. for server response exceeds value set with
  829. <![CDATA[-d<drop-time>]]>.</para></listitem>
  830. </itemizedlist>
  831. </para>
  832. <para>
  833. perfdhcp allows to run the test using specified interface:
  834. <screen><userinput>#./perfdhcp -l eth3</userinput></screen>
  835. or local address assigned to it:
  836. <screen><userinput>#./perfdhcp -l 172.16.1.2</userinput></screen>
  837. </para>
  838. </section>
  839. <section id="perfdhcp-rate-control">
  840. <title>Example: rate control</title>
  841. <para>
  842. In the examples above perfdhcp initiates new exchanges with best
  843. effort rate. In this case many packets is expected to be dropped by the
  844. server due to performance limitations. Many times it is desired to set
  845. the expected (reasonable) rate and verify if generated traffic is
  846. handled without packet dropes by DHCP server. The following command will
  847. make perfdhcp to initiate 300 4-way exchanges per second and test will
  848. last for 60 seconds:
  849. <screen><userinput>#./perfdhcp -l eth3 -p 60 -r 300</userinput>
  850. ***Rate statistics***
  851. Rate: 256.683 exchanges/second, expected rate: 300 exchanges/second
  852. ***Statistics for: DISCOVER-OFFER***
  853. sent packets: 17783
  854. received packets: 15401
  855. drops: 2382
  856. orphans: 0
  857. min delay: 0.109 ms
  858. avg delay: 75.756 ms
  859. max delay: 575.614 ms
  860. std deviation: 60.513 ms
  861. collected packets: 11
  862. ***Statistics for: REQUEST-ACK***
  863. sent packets: 15401
  864. received packets: 15317
  865. drops: 84
  866. orphans: 0
  867. min delay: 0.536 ms
  868. avg delay: 72.072 ms
  869. max delay: 576.749 ms
  870. std deviation: 58.189 ms
  871. collected packets: 0
  872. </screen>
  873. Note that in this example the packet drops have been significantly
  874. reduced thanks to setting reasonable rate. The non-zero number of
  875. packet drops and achived rate (256/s) below expected rate (300/s)
  876. indicate that server's measured performance is lower than 300 leases
  877. per second. Further rate decrease should eliminate most of the packet
  878. drops and bring achived rate close to expected rate:
  879. <screen><userinput>#./perfdhcp -l eth3 -p 60 -r 100 -R 30</userinput>
  880. ***Rate statistics***
  881. Rate: 99.8164 exchanges/second, expected rate: 100 exchanges/second
  882. ***Statistics for: DISCOVER-OFFER***
  883. sent packets: 5989
  884. received packets: 5989
  885. drops: 0
  886. orphans: 0
  887. min delay: 0.023 ms
  888. avg delay: 2.198 ms
  889. max delay: 181.760 ms
  890. std deviation: 9.429 ms
  891. collected packets: 0
  892. ***Statistics for: REQUEST-ACK***
  893. sent packets: 5989
  894. received packets: 5989
  895. drops: 0
  896. orphans: 0
  897. min delay: 0.473 ms
  898. avg delay: 2.355 ms
  899. max delay: 189.658 ms
  900. std deviation: 5.876 ms
  901. collected packets: 0
  902. </screen>
  903. Note that the last parameter (-R 30) configures perfdhcp to simulate
  904. traffic from distinct 30 clients.
  905. </para>
  906. </section>
  907. <section id="perfdhcp-templates">
  908. <title>Example: templates</title>
  909. <para>
  910. By default the DHCP messages are formed in-flight with default options.
  911. If desired, there is a way to define custom packet format with template
  912. files. Content in template files is encoded in hexadecimal format. The
  913. perfdhcp forms the packet by replacing parts of the binary stream read
  914. from the file with variable data such as elapsed time, HW address, DUID
  915. etc. The offsets where such variable data is placed is specific to the
  916. template file and have to be specified from the command line. Refer to
  917. <xref linkend="perfdhcp-command-line"/> to find out how to
  918. specify offsets for particular options and fields. With the following
  919. command line the DHCPv6 SOLICIT and REQUEST packets will be formed from
  920. solicit-example.hex and request6-example.hex packets:
  921. <screen><userinput>#./perfdhcp -6 -l eth3 -r 100 -R 20 -T templates/solicit-example.hex -T templates/request6-example.hex -O 21 -E 84 -S 22 -I 40 servers</userinput>
  922. ***Rate statistics***
  923. Rate: 99.5398 exchanges/second, expected rate: 100 exchanges/second
  924. ***Statistics for: SOLICIT-ADVERTISE***
  925. sent packets: 570
  926. received packets: 569
  927. drops: 1
  928. orphans: 0
  929. min delay: 0.259 ms
  930. avg delay: 0.912 ms
  931. max delay: 6.979 ms
  932. std deviation: 0.709 ms
  933. collected packets: 0
  934. ***Statistics for: REQUEST-REPLY***
  935. sent packets: 569
  936. received packets: 569
  937. drops: 0
  938. orphans: 0
  939. min delay: 0.084 ms
  940. avg delay: 0.607 ms
  941. max delay: 6.490 ms
  942. std deviation: 0.518 ms
  943. collected packets: 0
  944. </screen>
  945. where:
  946. <itemizedlist>
  947. <listitem><para>two occurences of -O 21 - DUID's last octet
  948. positions in SOLICIT and REQUEST respectively.</para></listitem>
  949. <listitem><para>-E 84 - elapsed time option position in
  950. REQUEST template</para></listitem>
  951. <listitem><para>-S 22 - server id position in REQUEST
  952. template</para></listitem>
  953. <listitem><para>-I 40 - IA_NA option position in REQUEST
  954. template</para></listitem>
  955. </itemizedlist>
  956. </para>
  957. </section>
  958. </section>
  959. </chapter>
  960. </book>