From e02704e05af277000d50f1ff6d4244d1d80d9c93 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 7b924b4e3..e0cba4a9e 100644 --- a/priv/emqx.schema +++ b/priv/emqx.schema @@ -2031,9 +2031,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 f3f878794..15fa32d8e 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()}).