Memory Erlang更改VM进程初始大小。调优Erlang虚拟机
首先,我必须提到,我运行的CentOS 7经过调整,可支持100万个连接。我用一个简单的C服务器和客户端进行了测试,连接了512000个客户端。我可以连接更多,但我没有足够的内存来生成更多的linux客户端机器,因为从一台机器上我可以打开65536个连接;8台机器*64000个连接每个=512000 我制作了一个简单的Erlang服务器,我想使用同一个C客户机连接100万或50万个客户机。我现在遇到的问题与记忆有关。对于每个成功的Memory Erlang更改VM进程初始大小。调优Erlang虚拟机,memory,process,erlang,server,Memory,Process,Erlang,Server,首先,我必须提到,我运行的CentOS 7经过调整,可支持100万个连接。我用一个简单的C服务器和客户端进行了测试,连接了512000个客户端。我可以连接更多,但我没有足够的内存来生成更多的linux客户端机器,因为从一台机器上我可以打开65536个连接;8台机器*64000个连接每个=512000 我制作了一个简单的Erlang服务器,我想使用同一个C客户机连接100万或50万个客户机。我现在遇到的问题与记忆有关。对于每个成功的gen\u tcp:accept调用,我生成一个进程。大约5000
gen\u tcp:accept
调用,我生成一个进程。大约50000个开放连接在服务器上花费了我3.7GB的RAM,同时使用C服务器,我可以使用1.9GB的RAM打开512000个连接。的确,在C服务器上,我没有在accept之后创建一个进程来处理东西,我只是在while循环中再次调用accept,但即使如此。。。网络上的家伙用更少的内存做了这个erlang(ejabberd riak)
我认为传递给erlang VM的标志应该起作用。从我在文档和网络上阅读的内容来看,我得到的是:erl+K true+Q 64200+P 134217727-env erl_MAX_端口40960000-env ERTS_MAX_端口40960000+a 16+hms 1024+hmbs 1024
这是服务器代码,我通过调用start(15001)
打开一个监听端口5001的侦听器
考虑到这种配置,您的my beam在启动时消耗了大约
2.5 GB
的内存,甚至没有加载模块
但是,如果您将最大进程数减少到合理的值,如50000个连接测试的+p60000
,内存消耗会迅速下降
由于有60000个进程,启动时仅使用虚拟内存的527MB
我试图重现您的测试,但不幸的是,在内存不足之前(由于客户端作业),我只能在系统上启动30000个netcat。然而,我只观察到虚拟机内存消耗的增加高达570MB
因此,我的建议是,您的数字来自高启动内存消耗,而不是大量打开的连接。即使这样,您实际上也应该注意统计信息随着打开的连接数的增加而变化,而不是绝对值
最后,我对我的基准测试使用了以下配置:
erl+K true+Q 64200+p 60000-环境erl\U最大端口40960000-环境ERT\U最大端口40960000+a 16+hms 1024+hmbs 1024
所以我用命令启动了客户端
除了你已经做的曲调,你还可以调整tcp缓冲区。默认情况下,它们采用操作系统默认值,但您可以将
{recbuf,Size}
和{sndbuf,Size}
传递给gen\u tcp:listen
。它可能会显著减少内存占用。您能将启动您使用的erlang的命令粘贴给我吗?erl和args的确切含义;还有你是如何建立这些联系的?从erlang内部,C客户端?我制作了一个C客户端,但忘了提及,这些选项记录在inet
模块中。
start(Num,LPort) ->
case gen_tcp:listen(LPort,[{reuseaddr, true},{backlog,9000000000}]) of
{ok, ListenSock} ->
start_servers(Num,ListenSock),
{ok, Port} = inet:port(ListenSock),
Port;
{error,Reason} ->
{error,Reason}
end.
start_servers(0,_) ->
ok;
start_servers(Num,LS) ->
spawn(?MODULE,server,[LS,0]),
start_servers(Num-1,LS).
server(LS, Nr) ->
io:format("before accept ~w~n",[Nr]),
case gen_tcp:accept(LS) of
{ok,S} ->
io:format("after accept ~w~n",[Nr]),
spawn(ex,server,[LS,Nr+1]),
proc_lib:hibernate(?MODULE, loop, [S]);
Other ->
io:format("accept returned ~w - goodbye!~n",[Other]),
ok
end.
loop(S) ->
ok = inet:setopts(S,[{active,once}]),
receive
{tcp,S, _Data} ->
Answer = 1, % Not implemented in this example
gen_tcp:send(S,Answer),
proc_lib:hibernate(?MODULE, loop, [S]);
{tcp_closed,S} ->
io:format("Socket ~w closed [~w]~n",[S,self()]),
ok
end.
for i in `seq 1 50000`; do nc 127.0.0.1 5001 & done