很容易忽略的ETS表个数限制问题

最近经常碰到ets表使用的数目超过系统的限制导致Erlang应用异常的案例。 比如说神锋同学报告说在ssh模块里面,最多只能打开500个左右链接,系统空闲的很,但是无法继续加大链接。 浩庭同学报告说mnesia的事务只能开1千多,多了就上不去了。这些问题看起来没有关联。但是其实和ets都有很大的关系,而且会报**_limit错误。

Erlang系统的限制见这里: **://**.erlang.org/doc/efficiency_guide/advanced.html#id215064
其中和ets相关的:

Ets table 内存消耗
Initially 768 words + the size of each element (6 words + size of Erlang data). The table will grow when necessary.

Ets-tables
The default is 1400, can be changed with the environment variable ERL_MAX_ETS_TABLES.

这个值非常的偏保守,我们通常的服务器都有几十G的内存,因为ETS基本是消耗内存的,所以我们不介意都开大点。

回到前面的问题,ssh出问题的原因是它每个链接需要3个ets, 而mnesia一个事务也要消耗1个ets表。

知道了问题的本质就很容易解决问题:
erl -env ERL_MAX_ETS_TABLES NNNNN就好了。

再来顺手**ejabberd的配置文件的说明:

# ERL_MAX_ETS_TABLES: Maximum number of ETS and Mnesia tables
#
# The number of concurrent ETS and Mnesia tables is limited. When the limit is
# reached, errors will appear in the logs:
# ** Too many db tables **
# You can safely increase this limit when starting ejabberd. It impacts memory
# consumption but the difference will be quite small.
#
# Default: 1400
#
#ERL_MAX_ETS_TABLES=1400

但是如何知道N设成多**较合适呢?

erl shell下按下CTRL+C 再按下i就告诉你现在这些核心资源包括ets的使用情况,具体见以下代码。 你一看用的差不多了,就搞大点。

void info(int to, void *to_arg)
02
{
03
erts_memory(&to, to_arg, NULL, THE_NON_VALUE);
04
atom_info(to, to_arg);
05
module_info(to, to_arg);
06
export_info(to, to_arg);
07
register_info(to, to_arg);
08
erts_fun_info(to, to_arg);
09
erts_node_table_info(to, to_arg);
10
erts_dist_table_info(to, to_arg);
11
erts_allocated_areas(&to, to_arg, NULL);
12
erts_allocator_info(to, to_arg);
13
}
其实还有一个更简单的方法用crashdump viewer**实际系统中有多少进程,每个进程消耗多少port和ets表。
我来说下大概的步骤:
1. 产生crashdump: 在实际运行的系统中按下CTRL+C再按大写的A,看到系统退出,生成我们系统运行期的快照。
2. 运行webtool: webtool:start() 他会告诉我们web地址,打开浏览器,打开该地址。
3. 在webtool中打开crashdump viewer模块,加载我们的crashdump文件进行分析,得到系统运行期的友好的解释。
4. 在进程这一栏里面可以看到每个进程的状态和使用的资源。

根据这些信息稍微估算下系统需要开多少process和port,提前规划好。

祝玩的开心!

已邀请:

要回复问题请先登录注册