`
mryufeng
  • 浏览: 982211 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

质疑 apache和yaws的性能比较(必看)

阅读更多
http://www.sics.se/~joe/apachevsyaws.html 上比较yaws的性能 显示apache 4000就挂了 但是yaws 8w还在挺着。
见附件的图

但是你仔细看下他的测试方式

What do we measure and how?

We use a 16 node cluster running at SICS. We plot throughput vs. parallel load.

  • Machine 1 has a server (Apache or Yaws).
  • Machine 2 requests 20 KByte pages from machine 1. It does this in tight a loop requesting a new page as soon as it has received a page from the server. From this we derive a throughput figure, which is plotted in the horizontal scale on the graph. A typical value (800) means the throughput is 800 KBytes/sec.
  • Machines 3 to 16 generate load.

    Each machine starts a large number of parallel sessions.

    Each session makes a very slow request to fetch a one byte file from machine 1. This is done by sending very slow HTTP GET requests (we break up the GET requests and send them character at a time, with about ten seconds between each character)

这个比较是非常不公平的

apache的链接处理机制是 开线程或者进程来处理请求 按它的测试方法 你非常慢速的8w请求 导致apache开大量的线程来处理。而能开多少线程取决于操作系统的能力 这还是其次 大量的线程处理活跃的链接导致大量的thread content switch。 apache 挂了不奇怪。 而erlang的线程相大于c语言的一个数据结构 erl_process你开多少取决于你的内存 大量的但是慢速的链接刚好适合poll事件dispatch, 以epoll的能力(俺测试过epoll30w)能够轻松处理。 这个测试与其说测试web服务器的性能 不如说 测试服务器的进程生成能力。

俺的测试是这样的:.
./yaws --conf yaws.conf --erlarg "+K true +P 1024000"     #epoll 最多1024000个进程 内核都已经调优过

yaws.conf 的内容:

auth_log = false
max_num_cached_files = 8000
max_num_cached_bytes = 6000000

<server test_yaws=""></server>

大家都用 ab -c 1000 -n 1000000 http://192.168.0.98:8000/bomb.gif 来测
果然发现yaws的性能也是非常一般 大概也就是3K左右.

各位看下 strace 的结果就知道了:

accept(10, {sa_family=AF_INET, sin_port=htons(5644), sin_addr=inet_addr("192.168.0.97")}, [16]) = 11
fcntl64(11, F_GETFL)                    = 0x2 (flags O_RDWR)
fcntl64(11, F_SETFL, O_RDWR|O_NONBLOCK) = 0
getsockopt(10, SOL_TCP, TCP_NODELAY, [0], [4]) = 0
getsockopt(10, SOL_SOCKET, SO_KEEPALIVE, [0], [4]) = 0
getsockopt(10, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(10, SOL_IP, IP_TOS, [0], [4]) = 0
getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0
setsockopt(11, SOL_IP, IP_TOS, [0], 4)  = 0
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0
getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0
getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0
setsockopt(11, SOL_SOCKET, SO_KEEPALIVE, [0], 4) = 0
setsockopt(11, SOL_IP, IP_TOS, [0], 4)  = 0
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0
getsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], [4]) = 0
getsockopt(11, SOL_IP, IP_TOS, [0], [4]) = 0
setsockopt(11, SOL_TCP, TCP_NODELAY, [0], 4) = 0
setsockopt(11, SOL_SOCKET, SO_PRIORITY, [0], 4) = 0
recv(11, "GET /bomb.gif HTTP/1.0\r\nUser-Age"..., 8192, 0) = 100
getpeername(11, {sa_family=AF_INET, sin_port=htons(5644), sin_addr=inet_addr("192.168.0.97")}, [16]) = 0
clock_gettime(CLOCK_MONOTONIC, {110242, 326908594}) = 0
stat64("/var/www/html/bomb.gif", {st_mode=S_IFREG|0644, st_size=4096, ...}) = 0
access("/var/www/html/bomb.gif", R_OK)  = 0
access("/var/www/html/bomb.gif", W_OK)  = 0
clock_gettime(CLOCK_MONOTONIC, {110242, 327135982}) = 0
time(NULL)                              = 1185894828
clock_gettime(CLOCK_MONOTONIC, {110242, 327222643}) = 0
stat64("/etc/localtime", {st_mode=S_IFREG|0644, st_size=405, ...}) = 0
writev(11, [{NULL, 0}, {"HTTP/1.1 200 OK\r\nConnection: clo"..., 231}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"...
, 4096}], 3) = 4327
close(11

这里面充斥着大量的无用的昂贵的系统调用 (至少有20个*10us = 200us 的系统调用是无效的)
对文件的access 2 次  连文件的cache都没有  每次 打开文件  读文件 然后写到socket去 。

这个case是小文件(4k)的情况。 看下大文件(40k)的情况

open("/var/www/html/bomb.gif", O_RDONLY|O_LARGEFILE) = 19
read(19, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240
writev(16, [{NULL, 0}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240}], 2) = 10240
read(19, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240
writev(16, [{NULL, 0}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240}], 2) = 10240
read(19, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240
writev(16, [{NULL, 0}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240}], 2) = 10240
read(19, "\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240) = 10240
writev(16, [{NULL, 0}, {"\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 10240}], 2) = 7240
read(19, "", 10240)                     = 0
close(19)                               = 0
clock_gettime(CLOCK_MONOTONIC, {110574, 856508319}) = 0
epoll_ctl(3, EPOLL_CTL_DEL, 11, {0, {u32=11, u64=581990243524149259}}) = 0
epoll_ctl(3, EPOLL_CTL_DEL, 12, {0, {u32=12, u64=581990243524149260}}) = 0
epoll_ctl(3, EPOLL_CTL_ADD, 16, {EPOLLOUT, {u32=16, u64=581990243524149264}}) = 0
epoll_wait(3, {}, 256, 0)               = 0
clock_gettime(CLOCK_MONOTONIC, {110574, 856677411}) = 0
clock_gettime(CLOCK_MONOTONIC, {110574, 856729274}) = 0

大量的epoll_ctl 调用 clock_gettime的调用 足够让系统的速度变的非常慢。


比对下lighttpd的性能。 lighttpd用到了cache,用到了aio,还是完全用c语言小心编写, 他处理小文件大概是并发1w.  而yaws这个的处理方式打个3折我看差不多。

所以请各位大佬介绍erlang的性能时候不要 再用这个apache vs yaws的例子了 误导太多人了.

 

  • 大小: 55.2 KB
分享到:
评论
41 楼 panxiaof 2007-11-14  
ejabberd的并发性:
mxit.co.za, about 23000 users maximum online (test environment with benchmark tools had 29000 concurrent users), Known ejabberd Servers Page for more examples
40 楼 mryufeng 2007-08-28  
还有一个证据 tsung在作http压力测试的时候 intel centrino duo 4G 的机器  只能跑到2.5K 并发 cpu 180%.
39 楼 mryufeng 2007-08-22  
os的开销主要在ring3->ring0->ring3这个流程太复杂了 随便一个系统调用就几个us, nginx分析一个完整的http请求才1us左右 所以越来越感觉单线程 单进程 在很多时候需要高效处理的时候很有用。
38 楼 Trustno1 2007-08-22  
七猫 写道
non-deconstructive assign和gc对这个切换的影响不大吧。
OS的切换要保存的上下文太多了。

想象一下,一个清扫一次都要pause所有thread的GC会产生啥效果.
我的意识是说,即便是1:N的LWP如果存在GC,比如说让Java来实现erlang的特性,他的效率提高的也非常有限.
37 楼 七猫 2007-08-22  
non-deconstructive assign和gc对这个切换的影响不大吧。
OS的切换要保存的上下文太多了。
36 楼 Trustno1 2007-08-22  
七猫 写道
纯静态的意义也不大,我们的服务器使用的apache或者lighthttpd,机器的带宽正常的情况下都可以跑满带宽。


说到底,操作系统所谓的Process和Thread 也只不过是一个Context结构,用指针保存每个Stack Frame,然后按时间片切换Context.有任何区别吗?
区别还是有的,系统切换的代价比较高,而自己切换的效率比较高。


如果没有GC插一脚,的确没多大区别.有了GC,区别就是大大地了.
有没有GC本身也是没多大关系的,但是一旦有了non-deconstructive assign区别又是大大的.

35 楼 七猫 2007-08-22  
纯静态的意义也不大,我们的服务器使用的apache或者lighthttpd,机器的带宽正常的情况下都可以跑满带宽。


说到底,操作系统所谓的Process和Thread 也只不过是一个Context结构,用指针保存每个Stack Frame,然后按时间片切换Context.有任何区别吗?
区别还是有的,系统切换的代价比较高,而自己切换的效率比较高。
34 楼 七猫 2007-08-22  
要是纯静态页面可以去试试lighthttpd,ghttpd之类的,apache没有设计成为单进程,主要为了扩展性强。apache还有prefork模块,也是为了更好的稳定性。
33 楼 七猫 2007-08-22  
jabber协议是tcp协议,而且是基于xml的。
32 楼 mryufeng 2007-08-21  
不管长短链接 3-5千的并发 他要收发的包是基本固定的 而处理包的能力才是系统的本质
31 楼 pi1ot 2007-08-21  
mryufeng 写道
ejabberd人家就诚实号称并发3,5千 根据erlang的表现和即时通讯的数据特点 应该是很靠谱的。 


ejabberd虽说是即时通信server,但是我记得jabber协议本身是不依赖于长连接的。
30 楼 mryufeng 2007-08-21  
ejabberd人家就诚实号称并发3,5千 根据erlang的表现和即时通讯的数据特点 应该是很靠谱的。 
29 楼 chinapr 2007-08-21  
Apache自己的线程机制本身就是很差的.很多企业应用都是自己改写了这部份.
28 楼 codeutil 2007-08-05  
转一下我同学的测试结果:

并发1000个用户的情况下,yaws cpu使用率100%
httpd cpu使用率15%


/usr/local/lib/erlang/erts-5.5.5/bin/beam.smp -P 102400 -K true -S 4 -A 512 -- -root /usr/local/lib/erlang -progname erl -- -home /root -noshell -noinput -pa /usr/local/lib/yaws/ebin -smp -run yaws -yaws id default

+P Number Sets the maximum number of concurrent processes for this system.Number must be in the range 16..134217727. Default is 32768.

 I/O threading (erl +A 256)
* SMP (erl -smp)
* kernel poll (erl +K true)




yaws -i -name yaws -erlarg "-kernel inet_dist_listen_min 4000 inet_dist_listen_max 4000" 




yaws -D --erlarg "+P 102400 +K true +S 4 +A 1024 -smp"
ab -c 1000 -n 50000  




27 楼 mryufeng 2007-08-02  
不知道哪里的设计思路 erlang最喜欢作的事情就是在emulator里面做机制 然后把数据搞到erl process里面去, 以后就可以用库或者工具来扩展功能 最典型的就是他的trace机制 非常灵活。单一个trace功能就是涉及到erl_trace.c->dist.c->erl_bif_trace.c->erlang:trace->dbg->
ttb->et 一层一层做上去 好强大。
26 楼 jigsaw 2007-08-02  
>>erlang的file io设计还是有点意思的 他把所有的io请求发送到ioserver进程去 在那里排队等候处理

源自exokernel的设计思路?
25 楼 mryufeng 2007-08-02  
erlang的file io设计还是有点意思的 他把所有的io请求发送到ioserver进程去 在那里排队等候处理。 这样的话要提高io性能就不是很难 自己实现个aio的driver就好了 有空的时候实现下 比对下io性能的提高。大家可以用pman仔细观测下erlang的几个核心进程,对系统会有更深的了解。
24 楼 qiezi 2007-08-01  
mryufeng 写道
最大的问题是 read write反复调用 这个才是大头 不过这个也可以用delay_send option来避免。 所有这个erlang是有很多细节可以微调的,只有把这些问题都处理掉了,性能才会提升。


的确,这些选项都很微妙啊,delay_send应该是要启用的,启用以后epoll的调用非常合理,除了clock_gettime以外。这些都要用strace跟踪确认,如果不是这个讨论,还真是难以发现这些小选项后面的隐情。

前段时间做了个简单的上传程序测试,当时说erlang这个进程方式比我用C++写的每连接一线程的方式性能高,后来发现测试有漏洞,大量进程的情况下那个erlang程序竟然比不过C++的,怎么优化也没什么提高,所以就没继续讨论了,羞愧。。。刚才把这个选项加上,发现这个上传程序比我写的那个每连接一线程的性能高10-20%左右,随着并发的增加,erlang程序的领先优势越来越多。性能差不多的是并发只有1个或2个的时候,这样看来erlang的IO性能也并不差。测试时发现IO wait比较高,上次看到一篇文章说这时候应该用AIO,性能还可以进一步提高,不知道erlang里面如何利用这个特性,搜索了一下otp代码,发现只有erts/emulator/sys/win32/sys.c里面有aio这个词,看样子linux版本并没有使用这个。
23 楼 Trustno1 2007-08-01  
Python的I/O可能是所有的动态语言中最高的.
22 楼 qiezi 2007-08-01  
http://muharem.wordpress.com/2007/07/31/erlang-vs-stackless-python-a-first-benchmark/

一篇Erlang和Stackless Python的性能比较,看样子Erlang没什么优势啊。也难怪,都是C开发的,为什么要有优势?可能在多CPU上Erlang会有优势吧。不过Erlang的IO库性能非常差?

相关推荐

    使用Erlang和Yaws开发REST式的服务

    Erlang是一种面向并发和分布式系统的语言,以其高可靠性而著称,而Yaws是由Claes Wikström用Erlang编写的高性能Web服务器,能够处理大量并发连接。 首先,Yaws提供了几种处理动态内容和构建REST服务的方式: 1. *...

    yaws:Yaws Web服务器

    这是Yaws,是用Erlang编写的动态内容的Web服务器。 准备构建 获取并安装一个Erlang系统( )。 要编译Yaws,需要Erlang / OTP 18.0或更高版本。 如果您已经从github克隆了源代码,并且想使用自动工具进行构建,请...

    yaws-开源

    5. **日志记录和性能监控**:Yaws具有详细的日志记录功能,可以帮助开发者分析和优化服务器性能。同时,它还提供了一套性能监控工具,便于管理员实时掌握服务器状态。 6. **自动压缩**:Yaws可以自动对发送给客户端...

    yaws:偏航(还有另一个网络抓取工具)

    yaws(Yet Another Web Scraper)是一种易于使用但功能强大的Node.js Web抓取工具,它支持多种常用的抓取技术,通过使用带有正则表达式的模式,通过导航DOM(JQuery样式)来定义对象。 它是一个进行中的工作,包括...

    yaws-json2:Yaws json2 库

    yaws-json2 yaws-json2 是来自网络服务器的编码器/解码器。安装在 rebar.config 中: { yaws_json2 , " .* " , { git , " git://github.com/myua/yaws-json2 " , { tag , " master " }}}用法使用yaws_json2:decode_...

    高性能网关设备与服务实践

    随着技术的进步,诸如Nginx、Lighttpd等优秀的基于事件驱动的Web服务器框架,以及Tornado、Django这样的Python非阻塞Web框架,甚至使用Erlang语言编写的Yaws和Cowboy轻量级Web框架,都已经能够很好地解决C10K问题。...

    常用的web服务器软件有哪些.doc

    首先,Apache和Internet Information Server (IIS)是市场份额最大的两款Web服务器。Apache是开源的,具有高度可定制性和丰富的模块支持,适用于各种操作系统。IIS则是微软提供的闭源服务器,主要应用于Windows环境,...

    Building Web Applications with Erlang.2012.英文

    在Yaws上启动Web服务、服务静态文件(Serving Static Files)、编译、加载和运行代码以及集群化Yaws(Clustering Yaws)是构建Erlang Web应用的关键步骤。 4. 在构建Web应用时,需要考虑系统架构(System ...

    building_web_applications_with_erlang.pdf

    - **编译、加载和运行代码**: 在Web应用中,编译、加载和运行代码是常规操作,Yaws提供了相应的机制来支持这一流程。 - **集群Yaws**: 为了提高Web应用的可用性和负载均衡,Yaws支持集群部署,使多个Yaws实例能够...

    Building Web Applications with Erlang

    Yaws是一个用Erlang编写的高性能Web服务器,它特别适用于处理静态文件的分发、编译和运行Erlang代码、以及在Erlang集群中的应用。使用Yaws,开发者可以轻松地启动一个Web服务,从静态文件服务到动态内容处理,再到...

    erlang调用java

    7. **性能和限制**:虽然`Jinterface`提供了一个方便的桥梁,但跨语言调用的性能相比同语言内部调用会有下降。此外,由于`Erlang`和`Java`的并发模型不同,需要考虑线程安全和资源管理等问题。 8. **优化和实践**:...

    Erlang-or-java.rar_erlang

    标题中的“Erlang-or-java.rar_erlang”表明这是一个关于Erlang和Java之间通信的示例项目。Erlang是一种面向并发、分布式、容错的编程语言,常用于构建高可用性和高并发性的系统,而Java则是一种广泛应用的通用编程...

    Erlang-game-server开发实践.zip

    Erlang有多种库如 cowboy 和 yaws 支持WebSocket,方便实现双向通信。 ### 8. 性能优化与监控 Erlang VM(BEAM)提供了诸如实时垃圾回收和运行时性能监控等工具。开发者可以通过这些工具优化代码性能,确保游戏...

    elli:简单,健壮和高性能的Erlang Web服务器

    然而,不同的服务器在性能、功能和灵活性方面各有特点,选择哪一款取决于具体项目需求。 总的来说,elli是一个针对HTTP API设计的Erlang Web服务器,它利用Erlang的语言特性提供了高并发、高可用的解决方案。如果你...

    otp_win_64_24.0.exe

    5. 应用框架:如Mnesia数据库系统、公共接口服务器(COS)和Web服务器(Yaws或Inets)等,方便开发特定用途的应用。 使用OTP Win64 24.0,开发者可以构建高性能、高并发的系统,同时享受Erlang语言提供的强大并发...

    轻量级Web服务器选择

    - **C语言**:许多轻量级Web服务器都是用C语言编写的,因为C语言能够提供更好的性能和较低的资源消耗。 - **Erlang**:Erlang是一种适合编写并发程序的语言,因此使用Erlang编写的Web服务器在处理高并发请求时表现...

    erlang websocket 练习

    在IT行业中,Erlang是一种面向并发的编程语言,它被广泛用于构建高可靠性、分布式系统,尤其是在电信和实时计算领域。WebSocket协议则是一种在Web上实现双向通信的协议,它允许服务器和客户端进行持久连接,从而实现...

    otp_win64_21.0.zip

    10. **Web开发**: Erlang可以通过 cowboy、YAWS 等框架进行Web开发,构建高性能的HTTP服务器和API。 总的来说,Erlang OTP 21.0的Windows 64位版本是一个强大的工具,适合构建分布式、高并发和容错的系统,尤其在...

Global site tag (gtag.js) - Google Analytics