Skip to content

Instantly share code, notes, and snippets.

@tatsuya6502
Created October 15, 2011 05:35
Show Gist options
  • Save tatsuya6502/1289107 to your computer and use it in GitHub Desktop.
Save tatsuya6502/1289107 to your computer and use it in GitHub Desktop.
Hibari 1 key 100 puts benchmark
#!/home/hibari/hibari/erts-5.8.5/bin/escript
%% -*- erlang -*-
%%! -name bench_q1w2e3r4t5y6@127.0.0.1
-define(RPC_TIMEOUT, 15000).
-define(FAIL_MSG(Format, Args), io:format(Format, Args), timer:sleep(1000), halt(1)).
main([]) ->
HibariHome = "/home/hibari/hibari/",
HibariNode = 'hibari@127.0.0.1',
Cookie = 'hibari',
Table = tmp,
Key = <<"k">>,
ok = add_code_paths(HibariHome),
ok = start_hibari_client(HibariNode, Cookie),
io:format("waiting for information about ~p... ", [Table]),
%% TODO: CHECKME wait_for_table doesn't seem to be working - it returns too early.
ok = wait_for_table(HibariNode, Table),
timer:sleep(1000),
io:format("done.~n"),
io:format("setting WAL's do_sync to false... "),
_ = checkpoint(HibariNode, tmp),
ok = go_async(HibariNode, tmp),
timer:sleep(500),
io:format("done.~n"),
%% Run benchmark
io:format("running put operations...~n"),
Start = now(),
try
do_puts(Table, Key)
catch
Class:Reason ->
?FAIL_MSG("Terminated by error: ~p:~p~n", [Class, Reason])
end,
ElapsedMicroSecs = timer:now_diff(now(), Start),
io:format("~p time elapsed for 1000 sets~n", [ElapsedMicroSecs / 1000000]),
io:format("~p ops/sec~n", [1000 / (ElapsedMicroSecs / 1000000)]),
ok = stop_hibari_client(HibariNode),
ok.
do_puts(Table, Key) ->
for(1, 100,
fun(_) ->
for(1, 10,
fun(_) ->
case brick_simple:set(Table, Key, <<"fuga">>) of
ok ->
ok;
{ok, _Ts} ->
ok;
Reason ->
throw(Reason)
end
end)
end).
for(C, N, _) when C > N ->
ok;
for(C, N, Fun) ->
Fun(C),
for(C + 1, N, Fun).
add_code_paths(HibariHome) ->
add_code_paths0([filename:join(HibariHome, "lib/cluster_info-0.1.1"),
filename:join(HibariHome, "lib/gmt_util-0.1.6"),
filename:join(HibariHome, "lib/gdss_brick-0.1.6"),
filename:join(HibariHome, "lib/gdss_client-0.1.6")]).
add_code_paths0([]) ->
ok;
add_code_paths0([Path | Rest]) ->
Absname = filename:absname(Path),
case filename:basename(Absname) of
"ebin" ->
true = code:add_path(Absname);
_ ->
true = code:add_path(filename:join(Absname, "ebin"))
end,
add_code_paths0(Rest).
start_hibari_client(HibariNode, Cookie) ->
ok = safe_start_application(sasl),
ok = start_net_kernel(node()),
true = erlang:set_cookie(HibariNode, Cookie),
ok = safe_start_application(gmt_util),
ok = safe_start_application(gdss_client),
%% Register client nodes to Hibari
case add_client_monitor(HibariNode, node()) of
ok ->
ok;
{ok, _Ts} ->
ok
end,
ok.
stop_hibari_client(HibariNode) ->
case delete_client_monitor(HibariNode, node()) of
ok ->
ok;
{ok, _Ts} ->
ok
end,
ok.
safe_start_application(App) ->
case application:start(App) of
ok ->
ok;
{error, {already_started, _}} ->
ok;
{error, {{already_started, _}, _}} ->
%% TODO: doesn't match documentation
ok;
{error, Reason1} ->
?FAIL_MSG("Failed to start ~p: ~p\n", [App, Reason1])
end.
start_net_kernel(Node) ->
case net_kernel:start(Node) of
{ok, _} ->
ok;
{error, {already_started, _}} ->
ok;
{error, {{already_started, _}, _}} ->
%% TODO: doesn't match documentation
ok;
{error, Reason1} ->
?FAIL_MSG("Failed to start net_kernel for ~p: ~p\n", [?MODULE, Reason1])
end.
rpc(Node, M, F, A) ->
case rpc:call(Node, M, F, A, ?RPC_TIMEOUT) of
{badrpc, Reason} ->
?FAIL_MSG("RPC(~p:~p:~p) to ~p failed: ~p\n",
[M, F, A, Node, Reason]);
Reply ->
Reply
end.
add_client_monitor(HibariNode, ClientNode) ->
rpc(HibariNode, brick_admin, add_client_monitor, [ClientNode]).
delete_client_monitor(HibariNode, ClientNode) ->
rpc(HibariNode, brick_admin, delete_client_monitor, [ClientNode]).
wait_for_table(GDSSAdmin, Table) ->
PollTable = fun({Node, not_ready, Tab} = T) ->
TabCh = gmt_util:atom_ify(gmt_util:list_ify(Tab) ++ "_ch1"),
case rpc(Node, brick_sb, get_status, [chain, TabCh]) of
{ok, healthy} ->
{false, ok};
_ ->
ok = timer:sleep(50),
{true, T}
end
end,
gmt_loop:do_while(PollTable, {GDSSAdmin, not_ready, Table}).
go_async(GDSSAdmin, Table) ->
go_sync(GDSSAdmin, Table, false).
%%go_sync(GDSSAdmin, Table) ->
%% go_sync(GDSSAdmin, Table, true).
go_sync(GDSSAdmin, Table, Bool) ->
_ = [rpc(Node, brick_server, set_do_sync, [{Brick, Node}, Bool])
|| {Brick, Node} <- running_bricks(GDSSAdmin, Table)],
SyncStatus = get_sync_properties(GDSSAdmin, Table),
Result = lists:foldl(fun(Status, Acc) ->
Status == Bool andalso Acc
end,
true,
SyncStatus),
case Result of
true ->
ok;
false ->
{error, SyncStatus}
end.
checkpoint(GDSSAdmin, Table) ->
[rpc(Node, brick_server, checkpoint, [Brick, Node])
|| {Brick, Node} <- running_bricks(GDSSAdmin, Table)].
get_sync_properties(GDSSAdmin, Table) ->
BrickStatusList = [rpc(Node, brick_server, status, [Brick, Node])
|| {Brick, Node} <- running_bricks(GDSSAdmin, Table)],
lists:map(fun({ok, BrickStatus}) ->
BrickImpl = proplists:get_value(implementation, BrickStatus, undefined),
proplists:get_value(do_sync, BrickImpl, undefined)
end,
BrickStatusList).
running_bricks(GDSSAdmin, Table) ->
{ok, Properties} = rpc(GDSSAdmin, brick_admin, get_table_info,
[{global, brick_admin}, Table]),
GHash = proplists:get_value(ghash, Properties),
Chains = lists:usort(brick_hash:all_chains(GHash, current)
++
brick_hash:all_chains(GHash, new)),
[Brick || {_Chain, Bricks} <- Chains, Brick <- Bricks].
#!/home/hibari/hibari/erts-5.8.5/bin/escript
%% -*- erlang -*-
%%! -name bench_a1b2c3d4e5f6@127.0.0.1
-include("/home/hibari/hibari/lib/ubf-1.15.6/include/ubf.hrl").
-define(RPC_TIMEOUT, 15000).
-define(FAIL_MSG(Format, Args), io:format(Format, Args), timer:sleep(1000), halt(1)).
main([]) ->
HibariHome = "/home/hibari/hibari/",
HibariNode = "localhost",
Table = tmp,
Key = <<"k">>,
ok = add_code_paths(HibariHome),
%% Start UBF connection and session
{ok, Con, _} = ubf_client:connect(HibariNode, 7581, [{proto, ubf}], ?RPC_TIMEOUT),
{reply, {ok, ok}, none} = ubf_client:rpc(Con, {startSession, {'#S', "gdss"}, []}),
%% Run benchmark
io:format("running put operations...~n"),
Start = now(),
try
do_puts(Con, Table, Key)
catch
Class:Reason ->
?FAIL_MSG("Terminated by error: ~p:~p~n", [Class, Reason])
end,
ElapsedMicroSecs = timer:now_diff(now(), Start),
io:format("~p time elapsed for 1000 sets~n", [ElapsedMicroSecs / 1000000]),
io:format("~p ops/sec~n", [1000 / (ElapsedMicroSecs / 1000000)]),
ok.
do_puts(Con, Table, Key) ->
for(1, 100,
fun(_) ->
for(1, 10,
fun(_) ->
case ubf_client:rpc(Con, {set, Table, Key, <<"fuga">>,
0, [], ?RPC_TIMEOUT}) of
{reply, ok, none} ->
ok;
{reply, {ok, _Ts}, none} ->
ok;
Reason ->
throw(Reason)
end
end)
end).
for(C, N, _) when C > N ->
ok;
for(C, N, Fun) ->
Fun(C),
for(C + 1, N, Fun).
add_code_paths(HibariHome) ->
add_code_paths0([filename:join(HibariHome, "lib/ubf-1.15.6")]).
add_code_paths0([]) ->
ok;
add_code_paths0([Path | Rest]) ->
Absname = filename:absname(Path),
case filename:basename(Absname) of
"ebin" ->
true = code:add_path(Absname);
_ ->
true = code:add_path(filename:join(Absname, "ebin"))
end,
add_code_paths0(Rest).
#!/bin/sh
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./s3/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./congestion_watcher/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./gdss_admin/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./partition_detector/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./gmt_util/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./mochiweb/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./riak_err/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./meck/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./gdss_ubf_proto/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./ubf_thrift/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./gdss_client/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./cluster_info/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./ubf/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./gdss_brick/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./ubf_jsonrpc/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./gdss_s3_proto/rebar.config
sed -i "s/\({erl_opts, .*, warnings_as_errors\$\)/\1, native/g" ./gdss_json_rpc_proto/rebar.config
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment