TerarkDB 性能测试报告

AlpOquendo 8年前
   <p>本篇文章来自 Terark 官网,<a href="/misc/goto?guid=4959674052995712574">查看原文</a></p>    <p>TerarkDB 性能测试报告</p>    <blockquote>     <p>TerarkDB是一款功能丰富的数据库,具有优异的读性能和良好的写性能 — 因为使用的是自主研发的索引压缩和数据压缩技术(索引不是传统的B+树或者LSM,数据也不是块压缩)。</p>     <p>TerarkDB v0.13 近期刚刚发布,目前这个版本已经具有了比较完善的功能,为了更好地让大家了解我们的产品,我们内部进行了一些比较全面的性能评测。</p>     <p>本文包含三种场景: 数据小于内存, 数据略大于内存以及数据远大于内存, 后续我们会发布更多的测试报告。</p>    </blockquote>    <h2>目录</h2>    <ul>     <li>1.环境      <ul>       <li>1.1.服务器信息</li>       <li>1.2.比较对象</li>       <li>1.3.测试数据集</li>       <li>1.4.测试源代码</li>       <li>1.5.压缩率说明</li>      </ul> </li>     <li>2.Tests      <ul>       <li>2.1.随机读测试</li>       <li>2.2.随机写测试</li>       <li>2.3.读写混测</li>       <li>2.4 读延迟测试</li>      </ul> </li>    </ul>    <h2>1.环境</h2>    <h3>1.1.服务器信息</h3>    <table>     <thead>      <tr>       <th>指标</th>       <th>描述</th>      </tr>     </thead>     <tbody>      <tr>       <td>CPU</td>       <td>Intel(R) Xeon(R) CPU E5-2630 v3 @ 2.40GHz (2 x 8个物理核)</td>      </tr>      <tr>       <td>Memory</td>       <td>64 GB of DDR4 RAM</td>      </tr>      <tr>       <td>SSD</td>       <td><a href="/misc/goto?guid=4959674053088106701">Intel® SSD 520 Series (480GB, 2.5in SATA 6Gb/s, 25nm, MLC)</a></td>      </tr>      <tr>       <td>Linux Kernel</td>       <td>3.10.0-327.10.1.el7.x86_64</td>      </tr>     </tbody>    </table>    <h3>1.2.比较对象</h3>    <table>     <thead>      <tr>       <th>产品名称</th>       <th>版本</th>       <th>公司</th>      </tr>     </thead>     <tbody>      <tr>       <td>rocksdb</td>       <td>v4.4</td>       <td>非死book</td>      </tr>      <tr>       <td>wiredtiger</td>       <td>v2.8.0</td>       <td>MongoDB</td>      </tr>      <tr>       <td>hyperleveldb</td>       <td>v1.2.2</td>       <td> </td>      </tr>      <tr>       <td>leveldb</td>       <td>v1.18</td>       <td>Google</td>      </tr>     </tbody>    </table>    <h3>1.3.测试数据集</h3>    <p><a href="/misc/goto?guid=4959674053178037920">Amazon movie data (~8 million reviews)</a>, 平均每条数据长度大约 1K</p>    <p>原始数据格式</p>    <pre>  product/productId: B00006HAXW  review/userId: A1RSDE90N6RSZF  review/profileName: Joseph M. Kotow  review/helpfulness: 9/9  review/score: 5.0  review/time: 1042502400  review/summary: Pittsburgh - Home of the OLDIES  review/text: I have all of the doo wop DVD's and this one is as good or better than the  1st ones. Remember once these performers are gone, we'll never get to see them again.  Rhino did an excellent job and if you like or love doo wop and Rock n Roll you'll LOVE  this DVD !!  </pre>    <p>元数据(列名)</p>    <ul>     <li>因为 TerarkDB 有 Schema,不需要在每条记录中额外保存元数据(列名)</li>     <li>为公平起见,对其它数据库,仅在列(字段)之间插入一个分隔符,不保存列名</li>    </ul>    <p>数据集大小</p>    <p><code>movies</code>数据集的总大小约为 <code>9GB</code>, 记录数大约为 <code>800万条</code></p>    <h3>1.4.测试用例源代码</h3>    <p><a href="/misc/goto?guid=4959674053268244674">Github仓库</a></p>    <h3>1.5.Compression Ratio</h3>    <ul>     <li>TerarkDB 使用自己研发的压缩算法进行数据压缩</li>     <li>其他数据库使用块压缩,块大小为 4KB,压缩算法设置为 <code>snappy</code></li>     <li>我们使用 随机写 的测试用例,对写入并压缩后的数据尺寸进行对比</li>    </ul>    <p><img alt="compression_ratio.png" src="https://simg.open-open.com/show/c37f5733defb5b82b77ae3c64853e5f6.png"></p>    <h2>2.Tests</h2>    <blockquote>     <p>所有的读操作,都是单条记录随机查询。所有的写操作,也都是单条记录随机插入或更新。</p>    </blockquote>    <h3>2.1.Random Read</h3>    <ul>     <li>所有的数据会预先写入文件系统</li>     <li>所有的数据库写入操作均启用压缩,配置 rocksdb/leveldb/wiredtiger 使用 <code>snappy</code> 算法</li>     <li>TerarkDB使用我们自己专有的压缩算法,不需要块压缩,其他数据库均使用4KB的默认块大小(Block Size)</li>    </ul>    <p>2.1.1.数据小于内存</p>    <p>在这种情况下我们的内存足够大,可以把所有的数据装入内存,同时 TerarkDB 不需要专有缓存,但其它数据库需要专有缓存(主要用来缓存对块压缩解压后的数据),我们为这些数据库设置专有缓存设置为3GB。</p>    <p>同时这项测试我们不限制操作系统对内存的使用(总内存64GB),数据量远小于内存,操作系统可以把所有数据缓存起来。</p>    <p><img alt="read_in_memory.png" src="https://simg.open-open.com/show/742f4cd6965132a44e6713e9350edb03.png"></p>    <p>我们可以看到TerarkDB在这种情况下要好于其他数据库:</p>    <ul>     <li>TerarkDB 使用自主研发的数据压缩算法,可以直接提取单条记录,不需要传统数据库的块压缩/解压</li>     <li>TerarkDB 使用自主研发的Succinct压缩型数据结构作为索引,使用更少的内存,并且搜索速度更快</li>    </ul>    <p>2.1.2.数据略大于内存</p>    <p>当数据量无法全部载入内存的情况下,我们需要把数据存储在物理磁盘上(我们此处使用 SSD 作为存储介质)。</p>    <ul>     <li>操作系统可以使用的的物理内存限制为8GB</li>     <li>我们为其他数据库设置了1GB的专用缓存用来装载热数据</li>     <li>所有数据库进行了预热(TerarkDB开启mmap populate, 其他数据库进行一轮预读)</li>    </ul>    <p><img alt="read_on_disk_8g.png" src="https://simg.open-open.com/show/aeb490e2619a57d20f521c5aae914609.png"></p>    <p>这种情况下,TerarkDB 的优势更明显 :</p>    <ul>     <li>除了 TerarkDB 以外,其他的数据库均需要使用块压缩,在随机读的情况下,即便有缓存支持,但毕竟缓存的大小有限,不可能把所有数据装入缓存,这就会导致频繁的磁盘I/O,降低读性能</li>     <li>TerarkDB 的压缩率比较高,压缩后的数据可以全部装入内存,同时 TerarkDB 可以直接访问压缩后的数据,使 TerarkDB 的优势更加明显</li>     <li>其他数据库由于使用了专有缓存,当读取的数据远远超出缓存容量,会造成大量的数据换入和换出,增加了额外的资源开销</li>    </ul>    <p>2.1.3.数据远大于内存</p>    <ul>     <li>操作系统内存限制为3G</li>     <li>为其他数据库设置256M的专用缓存</li>     <li>所有数据库进行了预热(TerarkDB开启mmap populate, 其他数据库进行一轮预读)</li>    </ul>    <p><img alt="read_on_disk_3g_populate.png" src="https://simg.open-open.com/show/a9efacb4cb1e190e3e8e7d5f52ee74c9.png"></p>    <p>由于TerarkDB比其他数据库的数据高出太多,下面这幅图使用对数坐标,更便于查看数量级(请观察纵坐标轴)</p>    <p><img alt="read_on_disk_3g_populate_log.png" src="https://simg.open-open.com/show/389228c92bd284edf2248c7e53717590.png"></p>    <h3>2.2.Random Write</h3>    <ul>     <li>写入时所有的数据库均开启压缩,并且默认块压缩的大小为 4KB(TerarkDB不需要块压缩)</li>     <li>所有的写 Buffer 都设置为256M</li>     <li>写入时分别使用 1/3/6 个线程同时进行操作</li>    </ul>    <p>2.2.1.数据小于内存</p>    <p>随机写测试和随机读(Random Read)测试的环境类似:</p>    <ul>     <li>存储介质使用内存文件系统(即数据先预读到内存文件系统中,以加快测试速度)</li>     <li>操作系统内存不做限制</li>     <li>除了 TerarkDB, 为其他数据库设置 3GB 的专用缓存</li>    </ul>    <p><img alt="write_in_memory.png" src="https://simg.open-open.com/show/84ad1a6b35d4a3f5637db56982b5f739.png"></p>    <p>2.2.2.数据略大于内存</p>    <p>与随机读测试的环境类似:</p>    <ul>     <li>操作系统的总内存限制为 8GB</li>     <li>除了 TerarkDB ,其他数据库的专用缓存设置为1GB</li>     <li>数据存储介质采用 SSD</li>     <li>写 buffer 设置为 256M</li>    </ul>    <p><img alt="write_on_disk_8g.png" src="https://simg.open-open.com/show/c38c2b25b10513d22055a26cd830a64f.png"></p>    <p>在SSD上的测试结果,更真实的反应了磁盘I/O对性能的影响:</p>    <ul>     <li>TerarkDB 采用索引和数据分离的方式进行写操作,能够将数据的写入方式在一定程度上转换成顺序写</li>    </ul>    <p>2.2.3.数据远大于内存</p>    <ul>     <li>操作系统内存限制为3G</li>     <li>为其他数据库设置256M的专用缓存</li>    </ul>    <p><img alt="write_on_disk_3g_populate.png" src="https://simg.open-open.com/show/cccedfa8d4ea945b9d278d101d27f0e4.png"></p>    <h3>2.3.Read-Write Mixed</h3>    <ul>     <li>TerarkDB 主要应用于少量写大量读的场景</li>     <li>测试一共使用8个线程,其中每个线程内部随机读写,95% / 99%的时间在进行读操作</li>     <li>写操作全部启用压缩,块压缩的大小是 4KB</li>     <li>首先让其他数据库进行一轮随机读(warm up), 填充专用缓存</li>    </ul>    <p>2.3.1. 数据量小于内存</p>    <ul>     <li>存储介质使用内存文件系统(即数据先预读到内存文件系统中,以加快测试速度)</li>     <li>操作系统内存不做限制</li>     <li>除了 TerarkDB ,其他数据库的专用缓存设置为3GB</li>    </ul>    <p><img alt="read_write_in_memory.png" src="https://simg.open-open.com/show/e4139c05e7d332d9bb456f9fa61a7d06.png"></p>    <p>2.3.2. 数据略大于内存</p>    <ul>     <li>存储介质改为 SSD</li>     <li>操作系统内存限制为8GB</li>     <li>其他数据库的专用缓存设置为1GB</li>     <li>分别测试 99% Read 和 95% Read</li>    </ul>    <p><img alt="read_write_on_disk_8g.png" src="https://simg.open-open.com/show/61a06601b8e350da318c3f42744841b1.png"></p>    <p>2.3.3.数据远大于内存</p>    <ul>     <li>操作系统内存限制为3G</li>     <li>为其他数据库设置256M的专用缓存</li>     <li>所有数据库进行了预热(TerarkDB开启mmap populate, 其他数据库进行一轮预读)</li>    </ul>    <p><img alt="read_write_on_disk_3g_99_95.png" src="https://simg.open-open.com/show/67a41e7fafb0d76d9d1d03ae546f1ba1.png"></p>    <p>同样,由于数量级相差较大,我们通过对数坐标看一下数据:</p>    <p><img alt="read_write_on_disk_3g_99_95_log.png" src="https://simg.open-open.com/show/d829715f04b65804541c2aa4c7716b53.png"></p>    <h3>2.4 Read Latency Test</h3>    <p>该测试中数据集依然是<a href="/misc/goto?guid=4959674053178037920">9G的电影点评数据</a>,仅测试的 Read Query 延迟,测试中无 Write 操作。</p>    <p>因为 TerarkDB 的压缩率很高,系统内存3G就可以装下全部数据(实际上压缩后的数据只有2.1G,但测试程序本身要占大约750M内存),所以以下3组对比中,TerarkDB都是在3G内存的条件下测试的。对于rocksdb和wiredtiger,我们分别在8G,4G和3G内存的条件下进行了测试。所有测试中,我们均使用了8个线程。</p>    <p>2.4.1. 数据略大于内存</p>    <ul>     <li>8G物理内存(TerarkDB是3G)</li>     <li>其他数据库有512M专用缓存</li>    </ul>    <p><img alt="mem8g_read_latency.png" src="https://simg.open-open.com/show/1c52cfe6eeeb9ffe46a69fedf47b9d7e.png"></p>    <table>     <thead>      <tr>       <th>Average</th>       <th>Median</th>       <th>99th Percentile</th>       <th>StdDev</th>      </tr>     </thead>     <tbody>      <tr>       <td>rocksdb</td>       <td>40.86</td>       <td>24</td>       <td>300</td>      </tr>      <tr>       <td>wiredtiger</td>       <td>58.82</td>       <td>41</td>       <td>450</td>      </tr>      <tr>       <td>terarkdb</td>       <td>6.66</td>       <td>6</td>       <td>25</td>      </tr>     </tbody>    </table>    <p>- 横坐标表示延迟,数字的单位是微秒,坐标比例是近似<code>对数</code>的<br> - 仔细观察横坐标的数字可以发现 TerarkDB 的延迟要低得多<br> - 纵坐标表示区间内累计Query数的所占总Query数的百分比<br> - Point(<em><code>X, Y%</code></em>) 表示 <em>延迟低于 <code>X</code>微秒的Query数</em> 占 <em>总Query数</em> 的 <em><code>Y%</code></em><br> - 数据结果,越快到达100%,说明 Query 延迟表现越好(延迟越低)<br> - 在当前情况下,内存对所有数据库都够用,所以曲线较为平滑<br> - TerarkDB的Latency均值,中值,标准差,99分位值都有明显优势,Latency很稳定。</p>    <p>2.4.2. 数据远大于内存</p>    <ul>     <li>3G物理内存</li>     <li>其他数据库有256M的专有缓存</li>    </ul>    <p><img alt="mem3g_read_latency.png" src="https://simg.open-open.com/show/f0b603a66606ff7fa4a81e77cfae5e8d.png"></p>    <table>     <thead>      <tr>       <th>Average</th>       <th>Median</th>       <th>99th Percentile</th>       <th>StdDev</th>      </tr>     </thead>     <tbody>      <tr>       <td>rocksdb</td>       <td>1338.88</td>       <td>1210</td>       <td>5000</td>      </tr>      <tr>       <td>wiredtiger</td>       <td>273.06</td>       <td>353</td>       <td>600</td>      </tr>      <tr>       <td>terarkdb</td>       <td>6.67</td>       <td>6</td>       <td>25</td>      </tr>     </tbody>    </table>    <ul>     <li>其他数据库有两段斜向上的曲线,分别表示读取的数据命中内存以及没有命中内存两种情况下的延迟,中间那条直线基本上是缓存是否命中的分界点</li>     <li>TerarkDB的延迟要低得多,TerarkDB的Latency均值,中值,标准差,99分位值都有明显优势,Latency很稳定</li>     <li>在这种情况下,虽然总内存只有3G,但是我们的压缩率比较高,压缩后的数据完全可以装入内存,所以不会出现Cache未命中的情况</li>    </ul>    <p>2.4.3 我们还测试了 rocksdb 和 wiredtiger 在4G内存条件下的指标:</p>    <p><img alt="mem4g_read_latency.png" src="https://simg.open-open.com/show/48f05b7ea66fd1ee692cbbec005935f8.png"></p>    <table>     <thead>      <tr>       <th>Average</th>       <th>Median</th>       <th>99th Percentile</th>       <th>StdDev</th>      </tr>     </thead>     <tbody>      <tr>       <td>rocksdb</td>       <td>964.21</td>       <td>970.36</td>       <td>2500</td>      </tr>      <tr>       <td>wiredtiger</td>       <td>204.85</td>       <td>56.25</td>       <td>600</td>      </tr>      <tr>       <td>terarkdb</td>       <td>6.67</td>       <td>6</td>       <td>25</td>      </tr>     </tbody>    </table>    <p>- 我们可以看到,在 4G 内存的情况下,RocksDB 和 WiredTiger 出现缓存命中的操作比率升高了(中间一段水平直线)</p>    <p> </p>    <p>来自: <a href="/misc/goto?guid=4959674053356128503" rel="nofollow">http://blog.csdn.net/whinah/article/details/51545839</a></p>    <p> </p>