Erlang中本地和远程ETS表操作的性能比较
早上在路上想到一个idea,在每台游戏服务器上运行一个数据节点 + 多个游戏逻辑节点,两台服务器只需要在两个数据节点间同步数据,最小化数据同步量。到了公司快速做了一个测试,比较了一下直接ets表插入和通过rpc:call调用的ets表插入的性能,下面是测试代码。
-module(ets_test). -export([ local/0, remote/0, remote_start/0, remote_init/0, remote_call/1 ]). -define(TIMES, 100000). -define(TEST_DATA, {<<I:128>>}). -define(MASTER_NODE, 'master@192.168.1.120'). local()-> ets:new(test_table, [private, set, named_table]), statistics(wall_clock), Fun = fun(I) -> ets:insert(test_table, ?TEST_DATA) end, for(?TIMES, Fun), {_, Time} = statistics(wall_clock), io:format("Time: ~pms~n", [Time]). remote()-> net_adm:ping(?MASTER_NODE), statistics(wall_clock), Fun = fun(I)-> rpc:call(?MASTER_NODE, ?MODULE, remote_call, [?TEST_DATA]) end, for(?TIMES, Fun), {_, Time} = statistics(wall_clock), io:format("Time: ~pms~n", [Time]). remote_start()-> proc_lib:spawn(?MODULE, remote_init, []), ok. remote_init()-> register(remote_proc, self()), ets:new(test_table, [private, set, named_table]), remote_proc(). remote_proc()-> receive {insert, Pid, Data} -> ets:insert(test_table, Data), Pid ! ok, remote_proc() end. remote_call(Data)-> remote_proc ! {insert, self(), Data}, receive ok -> ok end. for(0, _)-> ok; for(N, Fun)-> Fun(N), for(N - 1, Fun).
执行本地直接插入测试的脚本:
#!/bin/sh erl -noshell -s ets_test local -s init stop
测试10w数据插入耗时140ms。
执行远程插入测试需要先启动一个master节点,再启动一个slave节点。
master节点的启动脚本:
#!/bin/sh erl -name master@192.168.1.120 -setcookie the_cookie -s ets_test remote_start
slave节点的测试脚本:
#!/bin/sh erl -noshell -name slave@192.168.1.120 -setcookie the_cookie -s ets_test remote -s init stop
测试10w数据插入耗时21s。
140ms和21s,两者性能相差巨大。