From a4d8ef4f938bd75266cf2d75bfa72dc87fc6b6c7 Mon Sep 17 00:00:00 2001 From: William Yang Date: Tue, 27 Apr 2021 13:55:33 +0200 Subject: [PATCH] perf(broker): Optimization for handling bursty traffic intro. new lock type: 'spawn' of broker.perf.route_lock_type mnesia get lock calls are not optimized for selective receive. hence taking locks would be very expensive while there are tones of messages in the brokers message queue. This optimization run the transaction in a separate process to utilize the selective receive optimization of the compiler. --- priv/emqx.schema | 4 +++- src/emqx_router.erl | 20 +++++++++++++++++++- 2 files changed, 22 insertions(+), 2 deletions(-) diff --git a/priv/emqx.schema b/priv/emqx.schema index 8f662aa10..623788069 100644 --- a/priv/emqx.schema +++ b/priv/emqx.schema @@ -2110,9 +2110,11 @@ end}. %% key: mnesia translational updates with per-key locks. recommended for single node setup. %% tab: mnesia translational updates with table lock. recommended for multi-nodes setup. %% global: global lock protected updates. recommended for larger cluster. +%% spawn: same as `key', but transaction is done in another proc, ideal for handling bursty traffic. +%% {mapping, "broker.perf.route_lock_type", "emqx.route_lock_type", [ {default, key}, - {datatype, {enum, [key, tab, global]}} + {datatype, {enum, [key, tab, global, spawn]}} ]}. %%-------------------------------------------------------------------- diff --git a/src/emqx_router.erl b/src/emqx_router.erl index b77311e62..abbc7d785 100644 --- a/src/emqx_router.erl +++ b/src/emqx_router.erl @@ -264,7 +264,25 @@ maybe_trans(Fun, Args) -> trans(fun() -> emqx_trie:lock_tables(), apply(Fun, Args) - end, []) + end, []); + spawn -> + %% trigger selective receive optimization of compiler, + %% ideal for handling busty traffic. + Ref = erlang:make_ref(), + Owner = self(), + {WPid, RefMon} = spawn_monitor(fun() -> + Res = trans(Fun, Args), + Owner ! {Ref, Res} + end), + receive + {Ref, TransRes} -> + receive + {'DOWN', RefMon, process, WPid, normal} -> ok + end, + TransRes; + {'DOWN', RefMon, process, WPid, _Info} -> + {error, trans_crash} + end end. -spec(trans(function(), list(any())) -> ok | {error, term()}).