论坛首页 综合技术论坛

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

浏览 59882 次
该帖已经被评为良好帖
作者 正文
   发表时间:2007-08-01  
Trustno1 写道
是OTP库问题不是erlang本身的问题.
问题应该出在prim_inet里面.
...
不过你应该不用改动代码,直接使用async_accept/2即可跳过这段.

的确,直接用prim_inet:async_accept/2就没有这些调用了,一次accept变成这样了:
clock_gettime(CLOCK_MONOTONIC, {1293204, 894416432}) = 0
gettimeofday({1185954733, 787267}, NULL) = 0
accept(8, {sa_family=AF_INET, sin_port=htons(37370), sin_addr=inet_addr("127.0.0.1")}, [16]) = 9
fcntl64(9, F_GETFL)                     = 0x2 (flags O_RDWR)
fcntl64(9, F_SETFL, O_RDWR|O_NONBLOCK)  = 0
write(0, "Socket #Port<0.122> connected\r\n", 31) = 31
clock_gettime(CLOCK_MONOTONIC, {1293204, 894949432}) = 0
accept(8, 0xbffff1c0, [28])             = -1 EAGAIN (Resource temporarily unavailable)
recv(9, 0xb7d03180, 1024, 0)            = -1 EAGAIN (Resource temporarily unavailable)
clock_gettime(CLOCK_MONOTONIC, {1293204, 895342432}) = 0
epoll_ctl(3, EPOLL_CTL_DEL, 8, {EPOLLIN, {u32=8, u64=8589934600}}) = 0
epoll_ctl(3, EPOLL_CTL_ADD, 8, {EPOLLIN, {u32=8, u64=8589934600}}) = 0
epoll_ctl(3, EPOLL_CTL_ADD, 9, {EPOLLIN, {u32=9, u64=8589934601}}) = 0
epoll_wait(3, 


{{EPOLLIN, {u32=9, u64=8589934601}}}, 256, 3575743) = 1
clock_gettime(CLOCK_MONOTONIC, {1293232, 316418432}) = 0
gettimeofday({1185954761, 209266}, NULL) = 0
recv(9, "11\r\n", 1024, 0)              = 4
clock_gettime(CLOCK_MONOTONIC, {1293232, 316673432}) = 0
epoll_wait(3, 

后面一半是prim_inet:recv调用。

mryufeng 写道

不单单是 setsockopt 或者 getsockopt有问题 这个倒好 因为是一次性的开销 毕竟一个连接才做一次你看下clock_gettime epoll_ctl也是无厘头的调用,这也问题不是很大,最大的问题是 read write反复调用这个才是大头 不过这个也可以用delay_send option来避免。所有这个erlang是有很多细节可以微调的,只有把这些问题都处理掉了,性能才会提升。


clock_gettime可能是receive或其它超时参数的负作用吧,虽然没设超时,但它并没有判断后减少这个调用。

上面这个epoll_ctl只是多了个del/add,也还说得过去,毕竟你的接收进程循环就是这么写的,如果你不想再accept,它还是放在epoll里面就多此一举了,增加了不必要的事件,如果不处理这些事件,但又让它停留在epoll里面,epoll_wait总是马上返回,这会让CPU占用非常高的。ACE的多线程reactor在处理一个socket的事件时,也会把这个socket从select/epoll中拿掉,防止多个线程操作同一个socket。这里情况稍有不同,实际上相当于是proactor的实现,需要读时发一个读请求,不需要时就把事件注册给取消掉了。
0 请登录后投票
   发表时间:2007-08-01  
delay_send option的作用是 注册socket的写事件 当调用inet:send的时候不是马上调用系统sendv发送数据 而是先放到队列里面 等socket可写的时候 集中发出去 这样对改善服务器的吞吐量有很大帮助。
0 请登录后投票
   发表时间: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库性能非常差?
0 请登录后投票
   发表时间:2007-08-01  
Python的I/O可能是所有的动态语言中最高的.
0 请登录后投票
   发表时间: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版本并没有使用这个。
0 请登录后投票
   发表时间:2007-08-02  
erlang的file io设计还是有点意思的 他把所有的io请求发送到ioserver进程去 在那里排队等候处理。 这样的话要提高io性能就不是很难 自己实现个aio的driver就好了 有空的时候实现下 比对下io性能的提高。大家可以用pman仔细观测下erlang的几个核心进程,对系统会有更深的了解。
0 请登录后投票
   发表时间:2007-08-02  
>>erlang的file io设计还是有点意思的 他把所有的io请求发送到ioserver进程去 在那里排队等候处理

源自exokernel的设计思路?
0 请登录后投票
   发表时间:2007-08-02  
不知道哪里的设计思路 erlang最喜欢作的事情就是在emulator里面做机制 然后把数据搞到erl process里面去, 以后就可以用库或者工具来扩展功能 最典型的就是他的trace机制 非常灵活。单一个trace功能就是涉及到erl_trace.c->dist.c->erl_bif_trace.c->erlang:trace->dbg->
ttb->et 一层一层做上去 好强大。
0 请登录后投票
   发表时间: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  




  • 描述: yaws:
  • 大小: 84.7 KB
  • 描述: httpd性能图:
  • 大小: 87.4 KB
0 请登录后投票
   发表时间:2007-08-21  
Apache自己的线程机制本身就是很差的.很多企业应用都是自己改写了这部份.
0 请登录后投票
论坛首页 综合技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics