evpp性能测试: 与muduo进行吞吐量测试

Posted zieckey

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了evpp性能测试: 与muduo进行吞吐量测试相关的知识,希望对你有一定的参考价值。

By zieckey

简介

muduo是最近几年中国开源界里产生的优秀作品。它是由业内大牛陈硕实现的。详细介绍,请参考其博客介绍http://blog.csdn.net/solstice/article/details/5848547

本次测试是参考陈硕的博客文章muduo与libevent2吞吐量对比,该文章的结论是:muduo吞吐量平均比libevent218% 以上。

由于https://github.com/Qihoo360/evpp本身是基于libevent2实现的,因此我们希望将https://github.com/Qihoo360/evppmuduo放到一起做一次全面的性能测试。本文是关于这两个库在吞吐量方面的测试。

测试对象

  1. evpp-v0.2.4 based on libevent-2.0.21
  2. muduo-v1.0.9

测试环境

  1. Linux CentOS 6.2, 2.6.32-220.7.1.el6.x86_64
  2. Intel(R) Xeon(R) CPU E5-2630 v2 @ 2.60GHz
  3. gcc version 4.8.2 20140120 (Red Hat 4.8.2-15) (GCC)

测试方法

依据 boost.asio 性能测试 http://think-async.com/Asio/LinuxPerformanceImprovements 的办法,用 ping pong 协议来测试吞吐量。

简单地说,ping pong 协议是客户端和服务器都实现 echo 协议。当 TCP 连接建立时,客户端向服务器发送一些数据,服务器会 echo 回这些数据,然后客户端再 echo 回服务器。这些数据就会像乒乓球一样在客户端和服务器之间来回传送,直到有一方断开连接为止。这是用来测试吞吐量的常用办法。

muduo的测试代码在软件包内的路径为 examples/pingpong/,代码如https://github.com/chenshuo/muduo/tree/master/examples/pingpong所示。并使用BUILD_TYPE=release ./build.sh方式编译muduo的优化版本。

evpp的测试代码在软件包内的路径为benchmark/throughput/evpp,代码如https://github.com/Qihoo360/evpp/tree/master/benchmark/throughput/evpp所示。并使用 tools目录下的benchmark-build.sh

我们做了下面两项测试:

  1. 单线程测试,测试并发连接数为 1/10/100/1000/10000 时,消息大小分别为 4096 8192 81920 409600 时的吞吐量
  2. 多线程测试,并发连接数为 100 或 1000,服务器和客户端的线程数同时设为 2/3/4/6/8,ping pong 消息的大小为 16k bytes。测试用的 shell 脚本可从evpp的源码包中找到。

单线程测试结果数据

最终测试结论如下:

  1. 在吞吐量方面的性能总体来说,比较接近,各擅胜场
  2. 在单个消息较大时(>81K),evppmuduo整体上更快
  3. 在单个消息不太大时,并发数小于1000时,evpp占优
  4. 在单个消息不太大时,并发数大于1000时,muduo占优

测试中,单个消息较大时,evppmuduo整体上更快的结论,我们认为是与Buffer类的设计实现有关。evppBuffer类是自己人肉实现的内存管理,而muduoBuffer类的底层是用std::vector<char>实现的,我们推测muduo的这个实现性能方面稍差。本次吞吐量测试中,主要的开销是网络IO事件的触发回调和数据读写,当消息size不太大时,网络IO的事件触发耗费CPU更多;当消息size较大时,数据的读写和拷贝占用更多CPU。当然这只是一个推测,后面如果有时间或大家感兴趣,可以自行验证两个库的Buffer类的操作性能。

这个测试结果进一步推断,evpplibevent2更快(因为muduo吞吐量平均比libevent218% 以上),表面上看不符合逻辑,因为evpp的底层就是libevent2,但仔细分析发现,evpp只是用了libevent2核心的事件循环,并没有用libevent2中的evbuffer相关类和函数来读写网络数据,而是借鉴muduoGolang实现了自己独立的Buffer类来读写网络数据。

下面是具体的测试数据和图表。

NameMessage Size1 connection10 connections100 connections1000 connections10000 connections
evpp4096229.274631.611671.219495.566366.071
muduo4096222.117609.152631.119514.235365.959
evpp8192394.1621079.671127.09786.706645.866
muduo8192393.6831064.431103.02815.269670.503
evpp819201565.222079.771464.161323.091297.18
muduo819201567.9592180.4671432.0091267.1811159.278
evpp4096001950.792363.681528.971290.171039.96
muduo4096001887.0572213.8131305.8991131.3831043.612

我们用https://github.com/zieckey/gochart这个图表绘制工具将上述数据绘制为图表。




多线程测试结果

测试结论如下:

  1. 在多线程场景下,evppmuduo两个库在吞吐量方面,的性能整体上来看没有明显区别,分阶段分别领先
  2. 100并发连接比1000并发连接测试,两个库的吞吐量都明显的高得多
  3. 在100并发连接测试下,随着线程数的增长,吞吐量基本上是线性增长。muduo库在中段领先于evpp,但在前期和后期又弱于evpp
  4. 在1000并发连接测试下,随着线程数的增长,前期基本上是线性增长,后期增长乏力。muduo库这方面表现尤其明显

更多的性能测试报告

The IO Event performance benchmark against Boost.Asio, 该测试表明在该场景下evpp比[asio]高 20%~50% 上下

The ping-pong benchmark against Boost.Asio, 该测试表明在该场景下evpp比[asio]高 5%~20%% 上下

The throughput benchmark against libevent2, 该测试表明在该场景下evpplibevent17%~130% 上下

The throughput benchmark against Boost.Asio, 该测试表明在该场景下evpp与[asio]的性能基本相当,互相没有明显优势

The throughput benchmark against Boost.Asio(中文), 该测试表明在该场景下evpp与[asio]的性能基本相当,互相没有明显优势

The throughput benchmark against muduo(中文), 该测试表明在该场景下evppmuduo的性能基本相当,互相没有明显优势

以上是关于evpp性能测试: 与muduo进行吞吐量测试的主要内容,如果未能解决你的问题,请参考以下文章

evpp性能测试: 与Boost.Asio进行吞吐量对比测试

evpp性能测试: 与Boost.Asio进行吞吐量对比测试

网络库压力测试:mongols VS evpp

evpp性能测试: 对无锁队列boost::lockfree::queue和moodycamel::ConcurrentQueue做一个性能对比测试

evpp性能测试: 对无锁队列boost::lockfree::queue和moodycamel::ConcurrentQueue做一个性能对比测试

Elasticsearch 压力测试