Skip to content

Instantly share code, notes, and snippets.

View jadeallenx's full-sized avatar

Jade Allen jadeallenx

View GitHub Profile
@jadeallenx
jadeallenx / bench.md
Last active August 29, 2015 14:22
Lager 3.0 benchmarking

Intro

Last Friday (May 29, 2015) I published a tweet teaser about @macintux and my work on Lager 3.x. We have been benchmarking the "final" product including all of the community PRs we have decided to merge for 3.0 and we achieved some really great results over the 2.x branch. Those graphs look like this:

https://www.dropbox.com/s/417ysstatybvtkd/log_1000.png https://www.dropbox.com/s/iwoz7r2s690itdr/tput_1000.png

Many had questions about how we achieved such a big improvement in throughput and latency. The secret is very simple.

  1. We tried to move some decisions about whether to do work earlier into the process.
  2. We moved a couple pieces of global state into ets.
handoff_starting(_TargetNode, State) ->
{true, State}.
handoff_cancelled(State) ->
{ok, State}.
handoff_finished(_TargetNode, State) ->
{ok, State}.
is_empty(State) ->
Result = case list_dir(State) of
[] -> true;
{error, _Reason} -> true;
_ -> false
end,
{Result, State}.
handle_handoff_data(Data, State) ->
{Meta, Blob} = binary_to_term(Data),
R = case Meta#file.csum =:= erlang:adler32(Blob) of
true ->
Result = store(State, Meta, Blob),
?PRINT(Result),
ok;
false ->
{error, file_checksum_differs}
end,
encode_handoff_item(_Key, Data = {_Meta, _File}) ->
term_to_binary(Data).
handle_handoff_command(?FOLD_REQ{foldfun=VisitFun, acc0=Acc0}, _Sender, State) ->
AllObjects = get_all_objects(State),
Base = make_base_path(State),
Do = fun(Object, AccIn) ->
MPath = path_from_object(Base, Object, ".meta"),
?PRINT(MPath),
Meta = get_metadata(MPath),
?PRINT(Meta),
%% TODO: Get all file versions
-record(riak_core_fold_req_v2, {
foldfun :: fun(),
acc0 :: term(),
forwardable :: boolean(),
opts = [] :: list()}).
-define(FOLD_REQ, #riak_core_fold_req_v2).
handle_handoff_command(?FOLD_REQ{foldfun=VisitFun, acc0=Acc0}, _Sender, State) ->
%% eliding details for now. Don't worry, we'll get to them shortly.
Final = lists:foldl(fun magic/2, Acc0, object_list()),
{reply, Final, State}.
handle_handoff_command(_Message, _Sender, State) ->
{noreply, State}.
handoff_starting(_TargetNode, State) ->
{true, State}.
handoff_cancelled(State) ->
{ok, State}.
handoff_finished(_TargetNode, State) ->
ping() ->
DocIdx = riak_core_util:chash_key({<<"ping">>, term_to_binary(now())}),
PrefList = riak_core_apl:get_primary_apl(DocIdx, 1, demoapp),
[{IndexNode, _Type}] = PrefList,
riak_core_vnode_master:sync_spawn_command(IndexNode, ping, demoapp_vnode_master).