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

最快的http hello world服务器调优指南 (C20Khttp短链接请求/S每桌面CPU)

阅读更多
erl的虚拟机有2种方式 plain版本的和smp版本的。 smp版本由于锁的开销相比要比plain版本的慢很多。 而32位机器由于内存访问比64位的少,也会快出很多。所有我选择在32位的linux系统下调优这个httpd服务器。 这个服务器就是实现个简单的功能,在browser下返回hello world。 以下我们会先编译我们的优化版本的虚拟机,然后再分别测试R13B02的标准版本的和我们优化版的性能:

root@nd-desktop:/build_opt_plain# uname -a
Linux nd-desktop 2.6.31-14-generic #3 SMP Sun Nov 1 23:03:10 CST 2009 i686 GNU/Linux

#准备开发环境
root@nd-desktop:/# apt-get build-dep erlang

#下载otp R13B02-1源码包
root@nd-desktop:/# wget http://www.erlang.org/download/otp_src_R13B02-1.tar.gz

#解开patch包
root@nd-desktop:/# tar xzvf build_opt_plain.tgz

#解开源码包
root@nd-desktop:/# tar xzf otp_src_R13B02-1.tar.gz

#打补丁
root@nd-desktop:/# cd otp_src_R13B02-1
root@nd-desktop:/otp_src_R13B02-1# patch -p1 <../build_opt_plain/otp_src_R13B02-1_patch_by_yufeng
patching file erts/emulator/beam/erl_binary.h
patching file erts/emulator/beam/erl_process.c
patching file erts/emulator/beam/sys.h
patching file erts/emulator/drivers/common/inet_drv.c
patching file erts/preloaded/src/Makefile
patching file erts/preloaded/src/prim_inet.erl
patching file lib/asn1/src/Makefile
patching file lib/hipe/Makefile
patching file lib/parsetools/src/Makefile
root@nd-desktop:/otp_src_R13B02-1# ../build_opt_plain/build.plain
。。。
如果编译都没有任何错误的话, 就大功告成了。

好 现在我们开始性能比较:

#先加大文件句柄数
root@nd-desktop:/otp_src_R13B02-1# cd ../build_opt_plain
root@nd-desktop:/build_opt_plain# ulimit -n 99999

#标准发布版本
root@nd-desktop:/build_opt_plain# erlc ehttpd.erl
root@nd-desktop:/build_opt_plain# taskset -c 1 erl +K true +h 99999  +P 99999 -smp enable +S 2:1 -s ehttpd
Erlang R13B03 (erts-5.7.4) [source] [smp:2:1] [rq:2] [async-threads:0] [hipe] [kernel-poll:true]

ehttpd ready with 2 schedulers on port 8888
Eshell V5.7.4  (abort with ^G)
1>

#在另外的一台机器上发动ab测试
[root@localhost src]# ab -c 60 -n 100000 http://192.168.235.147:8888/
This is ApacheBench, Version 2.0.40-dev <$Revision: 1.146 $> apache-2.0
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Copyright 2006 The Apache Software Foundation, http://www.apache.org/

Benchmarking 192.168.235.147 (be patient)
Completed 10000 requests
Completed 20000 requests
Completed 30000 requests
Completed 40000 requests
Completed 50000 requests
Completed 60000 requests
Completed 70000 requests
Completed 80000 requests
Completed 90000 requests
Finished 100000 requests


Server Software:       
Server Hostname:        192.168.235.147
Server Port:            8888

Document Path:          /
Document Length:        12 bytes

Concurrency Level:      60
Time taken for tests:   8.925945 seconds
Complete requests:      100000
Failed requests:        0
Write errors:           0
Total transferred:      5100051 bytes
HTML transferred:       1200012 bytes
Requests per second:    11203.29 [#/sec] (mean)
Time per request:       5.356 [ms] (mean)
Time per request:       0.089 [ms] (mean, across all concurrent requests)
Transfer rate:          557.92 [Kbytes/sec] received

Connection Times (ms)
              min  mean[+/-sd] median   max
Connect:        0    1  65.7      0    3001
Processing:     0    3   1.5      4       7
Waiting:        0    2   1.8      4       6
Total:          0    4  65.8      4    3007
WARNING: The median and mean for the waiting time are not within a normal deviation
        These results are probably not that reliable.

Percentage of the requests served within a certain time (ms)
  50%      4
  66%      4
  75%      4
  80%      4
  90%      5
  95%      5
  98%      5
  99%      5
100%   3007 (longest request)

标准smp版本1个CPU的结果是: 11203.29 [#/sec] (mean)

#启用hipe的标准版本
root@nd-desktop:/build_opt_plain# erlc +native +"{hipe, [o3]}" ehttpd.erl
root@nd-desktop:/build_opt_plain# taskset -c 1 erl +K true +h 99999  +P 99999 -smp enable +S 2:1 -s ehttpd
Erlang R13B03 (erts-5.7.4) [source] [smp:2:1] [rq:2] [async-threads:0] [hipe] [kernel-poll:true]

ehttpd ready with 2 schedulers on port 8888
Eshell V5.7.4  (abort with ^G)
1>

标准smp hipe版本1个CPU结果是: 12390.32 [#/sec] (mean)


#我们的优化版本
root@nd-desktop:/build_opt_plain#  ../otp_src_R13B02-1/bin/erlc  ehttpd.erl
root@nd-desktop:/build_opt_plain# taskset -c 1   ../otp_src_R13B02-1/bin/erl +K true +h 99999  +P 99999   -s ehttpd
Erlang R13B02 (erts-5.7.3) [source] [rq:1] [hipe] [kernel-poll:true]

ehttpd ready with 1 schedulers on port 8888
Eshell V5.7.3  (abort with ^G)
1>

优化版本单个cpu: 19662.37 [#/sec] (mean)


#启用hipe的优化版本
root@nd-desktop:/build_opt_plain#  ../otp_src_R13B02-1/bin/erlc +native +"{hipe, [o3]}"  ehttpd.erl
root@nd-desktop:/build_opt_plain# taskset -c 1   ../otp_src_R13B02-1/bin/erl +K true +h 99999  +P 99999   -s ehttpd
Erlang R13B02 (erts-5.7.3) [source] [rq:1] [hipe] [kernel-poll:true]

ehttpd ready with 1 schedulers on port 8888
Eshell V5.7.3  (abort with ^G)
1>

优化版本启用hipe单个cpu:20090.83 [#/sec] (mean)

附上我们的最小的高性能的http echo 服务器:

root@nd-desktop:/build_opt_plain# cat ehttpd.erl
-module(ehttpd).
-compile(export_all).


start() ->
    start(8888).
start(Port) ->
    N = erlang:system_info(schedulers),
    listen(Port, N),
    io:format("ehttpd ready with ~b schedulers on port ~b~n", [N, Port]),

    register(?MODULE, self()),
    receive Any -> io:format("~p~n", [Any]) end.  %% to stop: ehttpd!stop.

listen(Port, N) ->
    Opts = [{active, false},
            binary,
            {backlog, 256},
            {packet, http_bin},
            {raw,6,9,<<1:32/native>>}, %defer accept
            %%{delay_send,true},
            %%{nodelay,true},
            {reuseaddr, true}],

    {ok, S} = gen_tcp:listen(Port, Opts),
    Spawn = fun(I) ->    
                    register(list_to_atom("acceptor_" ++ integer_to_list(I)),
                             spawn_opt(?MODULE, accept, [S, I], [link, {scheduler, I}]))
            end,
    lists:foreach(Spawn, lists:seq(1, N)).

accept(S, I) ->
    case gen_tcp:accept(S) of
        {ok, Socket} -> spawn_opt(?MODULE, loop, [Socket], [{scheduler, I}]);
        Error    -> erlang:error(Error)
    end,
    accept(S, I).

loop(S) ->
    case gen_tcp:recv(S, 0) of
        {ok, http_eoh} ->
            Response = <<"HTTP/1.1 200 OK\r\nContent-Length: 12\r\n\r\nhello world!">>,
            gen_tcp:send(S, Response),
            gen_tcp:close(S),
            ok;

        {ok, _Data} ->
            loop(S);

        Error ->
            Error
    end.


这个服务器是最小的,单是在多处理器和单cpu上都有非常好的性能。

root@nd-desktop:/build_opt_plain# cat /proc/cpuinfo
model name      : Pentium(R) Dual-Core  CPU      E5200  @ 2.50GHz

注:这个http服务器基本上是在c的程序跑,erlang的代码执行的很少, 所以hipe的提升效果不是很明显。对于复杂的业务,应该是有很大的帮助的。

附件里是用到的脚本和补丁。


我们可以得出结论:
hipe启用要比不启用快。
优化版本的和标准版本的 20090:11203, 性能提高了将近80% 还是非常可观的。


分享到:
评论
21 楼 mryufeng 2010-01-14  
rain2005 写道
spawn_opt(?MODULE, loop, [Socket], [{scheduler, I}]); 


原来spawn option有scheduler, I这个选项,学习了一把,这样SMP下锁的开销基本上没有了哦。同时erlang支持多个accept process

今天把老大的文章看个遍,呵呵,貌似最近不怎么写文章了哦。


这个选项是未公开的 otp team还没有最终想好这个功能如何体现 不过你可以先用着 这个cpu绑定对提高性能很有帮助, 前提是你规划好了...
20 楼 rain2005 2010-01-14  
spawn_opt(?MODULE, loop, [Socket], [{scheduler, I}]); 


原来spawn option有scheduler, I这个选项,学习了一把,这样SMP下锁的开销基本上没有了哦。同时erlang支持多个accept process

今天把老大的文章看个遍,呵呵,貌似最近不怎么写文章了哦。
19 楼 mryufeng 2009-11-22  
linkerlin 写道
老大,最近有折腾lua么?

lua有空的时候都在看呀 百看不厌呀
18 楼 linkerlin 2009-11-21  
老大,最近有折腾lua么?
17 楼 whrllm 2009-11-10  
我确认过了,我重新装过一次没有patch的时候可以正常运行,但是patch后,运行erl就一堆得错误
16 楼 mryufeng 2009-11-10  
你先确认patch前你的make过程没有问题 我在64位上没有问题的。
15 楼 whrllm 2009-11-10  
老大,写一个全的patch好么?好象在64位的机器上跑不起来呀。出了好多的错误,期待呀//
14 楼 joshzhu 2009-11-08  
mryufeng补充:以上例子要在R13版本才能跑
13 楼 mryufeng 2009-11-06  
joel的hotwheel程序是个优化的典型 可以看到很多技术点。。。
12 楼 mryufeng 2009-11-05  
设计是1方面 性能挖掘是一方面 同样的代码logic 会差很多的.
11 楼 大忙人 2009-11-05  
不错不错。
不过,我觉得这类还是通过设计来解决比较好一些。毕竟这种做法不具有扩展性。
10 楼 mryufeng 2009-11-05  
我用这个vm hotwheel比赛突破4W 奖励下我哦 $1K。。。
9 楼 mryufeng 2009-11-05  
right
8 楼 whrllm 2009-11-05  
是不是在./configure 那不带任何参数就可以了?
7 楼 whrllm 2009-11-05  
老大 把编smp的版本的脚本也发出来嘛//
6 楼 mryufeng 2009-11-05  
我编译的是 单cpu版本的 hipe是和版本相关的 你要想用smp, 得重新编译个。 smp和plain版本的完全不兼容。
5 楼 whrllm 2009-11-05  
还有个问题,就是我为什么使用erl -smp -enable无效,怎么才能在hipe的情况下 使用smp啊?谢谢
4 楼 whrllm 2009-11-05  
老大 请教个问题,我按照这些步骤编译了,而且过程没有出错,
但是我用 m(lists),并没有看到debug_info,native,"{hipe, [o3]}"] 这个显示,是不是没有成功啊?

PS:不好意思,刚不小心发错文章了
3 楼 joshzhu 2009-11-04  
这个结果相当NB,相当有说服力~~~
2 楼 whrllm 2009-11-04  
等了一个晚上,出来了,哈哈,老大太帅了////

相关推荐

Global site tag (gtag.js) - Google Analytics