Memory Erlang更改VM进程初始大小。调优Erlang虚拟机

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

首先,我必须提到,我运行的CentOS 7经过调整,可支持100万个连接。我用一个简单的C服务器和客户端进行了测试,连接了512000个客户端。我可以连接更多,但我没有足够的内存来生成更多的linux客户端机器,因为从一台机器上我可以打开65536个连接;8台机器*64000个连接每个=512000

我制作了一个简单的Erlang服务器,我想使用同一个C客户机连接100万或50万个客户机。我现在遇到的问题与记忆有关。对于每个成功的
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