目标
(1) 了解在多核cpu环境下,erlang并发进程调度对各个cpu核负载的影响;
(2) Erlang虚拟机的内存增加机理;
(3) Erlang进程的调度情况;
(4) Linux下监控cpu的使用状况
实验环境
联想小型机:操作系统:RedHat Enterprise LinuxServer release6.4(Santiago)
内核版本:Linux server1 2.6.32-358.el6.x86_64#1 SMP
CPU型号:Intel(R)Xeon(R)CPU E7-4820 @2.00Ghz;
4颗cpu,每颗cpu物理核数为8,总物理核数为32,逻辑核数为64
内存:125G
磁盘:289G
Erlang OTP:Erlang/OTP 17[erts-6.0][source][64bit][smp:64:64][async-thread:10]
测试过程
Erlang并发进程
测试代码
-module(test).
-export([start_proc/1]).
start_proc(Num) ->
case Num =:= 0 of
true -> ok;
false -> spawn(fun()-> loop() end),start_proc(Num-1)
end.
loop() -> loop().
Cpu运行状况
test:start_proc(1000000)启动1000000个进程后,执行mpstat –PAll 2 10
并发IO
测试代码
-module(testio).
-export([start_proc/1]).
name() ->
{A,B,C} =erlang:now(),
Integer_to_list(A) ++Integer_to_list(B)++Integer_to_list(C).
io() ->
{ok,Fd} = file:open(“./data/”++name(),[write,raw,binary,append]),
file:write(Fd,”Hi zcc,nice to meet you”),
file:read(Fd,23),
file:close(Fd).
start_proc(Num) ->
IO = fun()-> io() end,
case Num =:= 0of
true ->ok;
false-> spawn(IO),timer:sleep(1),start_proc(Num-1)
end.
Linux下查看内核相关信息
vmstat –n 3每隔3s刷新一次
利用sar进行cpu利用率的分析 sar –u 2 10
分析运行进程队列长度sar –q 2 10
cpu %usr %nice%sys %iowait %irq %soft %steal %guest %idle
mpstat –P 1:查看1号cpu的信息
%steal:虚拟cpu无意识等待时间百分比
%nice:cpu处在带有nice值的user模式下时间百分比
top –M 后按下F键,然后按j,回车,可看到进程在哪个核上运行
结论
(1) 在默认情况下Erlang的smp的调度进程schedualer是与cpu的核对应的,而不是与cpu的个数对应的,就如本环境下有4个cpu,32个物理核,开启超线程后为64个逻辑核,调度进程数为64;
(2) 当erlang并发多个进程后,通过cpu的负载可以看出,各个进程会均匀的分布在各个核上运行,而不会是某个核负载过大,某个核负载过小的情况发生,此件事情是有操作系统来做的,程序员无须关心;
(3) Erlang虚拟机的内存会随着进程数的增加,自动从主机内存中申请增加,这与java虚拟机不同,jvm1.6以前内存不会自动增加内存,只能手动配置增加jvm内存,从1.7以后才能够共享物理主机内存;Erlang虚拟机没有抑制内存增长机制。虚拟机不断的分配内存,迫使系统不得不使用交换区,直到虚拟机内存耗尽,变得非常迟钝。Erlang虚拟机设计的‘私有堆’和基于队列的编程模型是优点也是缺点,当在生产环境下运行erlang虚拟机时,要配备一个系统级的检测,以便在erlang内存使用量飞涨时,能够杀死进程。
(4) Erlang调度器运行于一个OS线程,由OS决定其是否执行在一个核上,一般来说,OS会保证线程在执行期间运行于一个核上;
(5) 估算一个系统的进程数上限=内存总量/erlang:process_info(self(),memory),得到erlang的wordsize=erlang:system_info(wordsize).Erlang中一个进程所占内存大概为2667字节。
(6) 测试结果
启动进程数 | 虚拟机内存 | 启动时间 |
10万 | 299M | 12.3s |
100万 | 2.7G | 6.8s |
1000万 | 27.2G | 57.6s |
55164851 | 132G | 400s |