diff options
| author | Simon MacMullen <simon@rabbitmq.com> | 2015-01-20 14:55:12 +0000 |
|---|---|---|
| committer | Simon MacMullen <simon@rabbitmq.com> | 2015-01-20 14:55:12 +0000 |
| commit | 7d794dd70df7c0be0809d89ada7884230189968c (patch) | |
| tree | f39f6547b3c70d633b946467c15f00c053b01237 /src | |
| parent | f4381b01abe5f3e24439adcff49bbe76c7b08abd (diff) | |
| download | rabbitmq-server-git-7d794dd70df7c0be0809d89ada7884230189968c.tar.gz | |
Improve the performance of determine_persist_to/2, stop it being a hotspot.
Diffstat (limited to 'src')
| -rw-r--r-- | src/rabbit_variable_queue.erl | 28 | ||||
| -rw-r--r-- | src/truncate.erl | 2 |
2 files changed, 24 insertions, 6 deletions
diff --git a/src/rabbit_variable_queue.erl b/src/rabbit_variable_queue.erl index d772d69bcc..57fad266b4 100644 --- a/src/rabbit_variable_queue.erl +++ b/src/rabbit_variable_queue.erl @@ -320,11 +320,13 @@ %% betas, the IO_BATCH_SIZE sets the number of betas that we must be %% due to write indices for before we do any work at all. -define(IO_BATCH_SIZE, 2048). %% next power-of-2 after ?CREDIT_DISC_BOUND +-define(HEADER_GUESS_SIZE, 100). %% see determine_persist_to/2 -define(PERSISTENT_MSG_STORE, msg_store_persistent). -define(TRANSIENT_MSG_STORE, msg_store_transient). -define(QUEUE, lqueue). -include("rabbit.hrl"). +-include("rabbit_framing.hrl"). %%---------------------------------------------------------------------------- @@ -1404,17 +1406,33 @@ maybe_write_to_disk(ForceMsg, ForceIndex, MsgStatus, maybe_write_index_to_disk(ForceIndex, MsgStatus1, IndexState), {MsgStatus2, State #vqstate { index_state = IndexState1 }}. -determine_persist_to(Msg, #message_properties{size = Size}) -> +determine_persist_to(#basic_message{ + content = #content{properties = Props, + properties_bin = PropsBin}}, + #message_properties{size = BodySize}) -> {ok, IndexMaxSize} = application:get_env( rabbit, queue_index_embed_msgs_below), %% The >= is so that you can set the env to 0 and never persist %% to the index. %% - %% We avoid invoking exceeds_size/2 if the message is large - %% anyway. - case Size >= IndexMaxSize of + %% We want this to be fast, so we avoid size(term_to_binary()) + %% here, or using the term size estimation from truncate.erl, both + %% of which are too slow. So instead, if the message body size + %% goes over the limit then we avoid any other checks. + %% + %% If it doesn't we need to decide if the properties will push + %% it past the limit. If we have the encoded properties (usual + %% case) we can just check their size. If we don't (message came + %% via the direct client), we make a guess based on the number of + %% headers. + case BodySize >= IndexMaxSize of true -> msg_store; - false -> case truncate:exceeds_size(Msg, IndexMaxSize) of + false -> Est = case is_binary(PropsBin) of + true -> BodySize + size(PropsBin); + false -> #'P_basic'{headers = Hs} = Props, + length(Hs) * ?HEADER_GUESS_SIZE + BodySize + end, + case Est >= IndexMaxSize of true -> msg_store; false -> queue_index end diff --git a/src/truncate.erl b/src/truncate.erl index 952ed2443c..1b4d957d0b 100644 --- a/src/truncate.erl +++ b/src/truncate.erl @@ -20,7 +20,7 @@ -record(params, {content, struct, content_dec, struct_dec}). --export([log_event/2, term/2, exceeds_size/2]). +-export([log_event/2, term/2]). %% exported for testing -export([test/0]). |
