Skip to content

Commit 9c893ec

Browse files
committed
Basic benchmark for topic routing
1 parent 34ac082 commit 9c893ec

File tree

1 file changed

+84
-1
lines changed

1 file changed

+84
-1
lines changed

deps/rabbit/test/rabbit_db_topic_exchange_SUITE.erl

Lines changed: 84 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,8 @@ all() ->
2222

2323
groups() ->
2424
[
25-
{all_tests, [], all_tests()}
25+
{all_tests, [], all_tests()},
26+
{benchmarks, [], benchmarks()}
2627
].
2728

2829
all_tests() ->
@@ -37,6 +38,11 @@ all_tests() ->
3738
build_multiple_key_from_deletion_events
3839
].
3940

41+
benchmarks() ->
42+
[
43+
match_benchmark
44+
].
45+
4046
init_per_suite(Config) ->
4147
rabbit_ct_helpers:log_environment(),
4248
rabbit_ct_helpers:run_setup_steps(Config).
@@ -271,6 +277,83 @@ build_multiple_key_from_deletion_events1(Config) ->
271277
lists:sort([RK || {_, RK} <- rabbit_db_topic_exchange:trie_records_to_key(Records)])),
272278
passed.
273279

280+
%% ---------------------------------------------------------------------------
281+
%% Benchmarks
282+
%% ---------------------------------------------------------------------------
283+
284+
match_benchmark(Config) ->
285+
%% run the benchmark with Mnesia first
286+
MnesiaResults = rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, match_benchmark1, [Config]),
287+
288+
%% migrate to Khepri
289+
Servers = rabbit_ct_broker_helpers:get_node_configs(Config, nodename),
290+
{T, ok} = timer:tc(fun() ->
291+
rabbit_ct_broker_helpers:enable_feature_flag(Config, Servers, raft_based_metadata_store_phase1)
292+
end),
293+
ct:pal("~p: time to migrate to Khepri: ~.2fs", [?FUNCTION_NAME, T/1000000]),
294+
295+
%% run the same same benchmark with Khepri enabled
296+
KhepriResults = rabbit_ct_broker_helpers:rpc(Config, 0, ?MODULE, match_benchmark1, [Config]),
297+
298+
%% print all the results first
299+
maps:foreach(fun(Test, KhepriResult) ->
300+
MnesiaResult = maps:get(Test, MnesiaResults),
301+
ct:pal("~p: Test: ~p, Mnesia: ~.2fus, Khepri: ~.2fus", [?FUNCTION_NAME, Test, MnesiaResult, KhepriResult])
302+
end, KhepriResults),
303+
304+
%% fail the test if needed
305+
maps:foreach(fun(Test, KhepriResult) ->
306+
MnesiaResult = maps:get(Test, MnesiaResults),
307+
?assert(KhepriResult < MnesiaResult * 1.5, "Khepri can't be significantly slower than Mnesia")
308+
end, KhepriResults).
309+
310+
match_benchmark1(_Config) ->
311+
Src = rabbit_misc:r(?VHOST, exchange, <<"test-exchange">>),
312+
Dst1 = rabbit_misc:r(?VHOST, queue, <<"test-queue1">>),
313+
Dst2 = rabbit_misc:r(?VHOST, queue, <<"test-queue2">>),
314+
Dst3 = rabbit_misc:r(?VHOST, queue, <<"test-queue3">>),
315+
Dst4 = rabbit_misc:r(?VHOST, queue, <<"test-queue4">>),
316+
Dst5 = rabbit_misc:r(?VHOST, queue, <<"test-queue5">>),
317+
Dst6 = rabbit_misc:r(?VHOST, queue, <<"test-queue6">>),
318+
319+
SimpleTopics = [list_to_binary("a.b." ++ integer_to_list(N)) || N <- lists:seq(1,1000)],
320+
Bindings = [#binding{source = Src, key = RoutingKey, destination = Dst1, args = #{}} || RoutingKey <- SimpleTopics],
321+
BindingRes = [rabbit_db_topic_exchange:set(Binding) || Binding <- Bindings],
322+
?assertMatch([ok], lists:uniq(BindingRes)),
323+
ok = rabbit_db_topic_exchange:set(#binding{source = Src, key = <<"a.b.*">>, destination = Dst2, args = #{}}),
324+
ok = rabbit_db_topic_exchange:set(#binding{source = Src, key = <<"a.b.*">>, destination = Dst3, args = #{}}),
325+
ok = rabbit_db_topic_exchange:set(#binding{source = Src, key = <<"a.#">>, destination = Dst4, args = #{}}),
326+
ok = rabbit_db_topic_exchange:set(#binding{source = Src, key = <<"*.b.42">>, destination = Dst5, args = #{}}),
327+
ok = rabbit_db_topic_exchange:set(#binding{source = Src, key = <<"#">>, destination = Dst6, args = #{}}),
328+
329+
{Tany, _} = timer:tc(fun() ->
330+
[rabbit_db_topic_exchange:match(Src, <<"foo">>) || _ <- lists:seq(1, 100)]
331+
end),
332+
?assertMatch([Dst6], rabbit_db_topic_exchange:match(Src, <<"foo">>)),
333+
334+
{Tbar, _} = timer:tc(fun() ->
335+
[rabbit_db_topic_exchange:match(Src, <<"a.b.bar">>) || _ <- lists:seq(1, 100)]
336+
end),
337+
?assertEqual(lists:sort([Dst2,Dst3,Dst4,Dst6]), lists:sort(rabbit_db_topic_exchange:match(Src, <<"a.b.bar">>))),
338+
339+
{Tbaz, _} = timer:tc(fun() ->
340+
[rabbit_db_topic_exchange:match(Src, <<"baz.b.42">>) || _ <- lists:seq(1, 100)]
341+
end),
342+
?assertEqual(lists:sort([Dst5,Dst6]), lists:sort(rabbit_db_topic_exchange:match(Src, <<"baz.b.42">>))),
343+
344+
{Tsimple, Rsimple} = timer:tc(fun() ->
345+
[rabbit_db_topic_exchange:match(Src, RoutingKey)
346+
|| RoutingKey <- SimpleTopics, RoutingKey =/= <<"a.b.123">>]
347+
end),
348+
?assertEqual([Dst1,Dst2,Dst3,Dst4,Dst6], lists:sort(lists:uniq(hd(Rsimple)))),
349+
350+
#{
351+
"average time to match `foo`" => Tany/100,
352+
"average time to match `a.b.bar`" => Tbar/100,
353+
"average time to match `baz.b.42`" => Tbaz/100,
354+
"average time to match a simple topic" => Tsimple/length(SimpleTopics)
355+
}.
356+
274357
subscribe_to_mnesia_changes([Table | Rest]) ->
275358
case mnesia:subscribe({table, Table, detailed}) of
276359
{ok, _} -> subscribe_to_mnesia_changes(Rest);

0 commit comments

Comments
 (0)