summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/rabbitmq.config.example18
-rw-r--r--docs/rabbitmqctl.1.xml13
-rw-r--r--src/rabbit_alarm.erl3
-rw-r--r--src/rabbit_control_main.erl12
-rw-r--r--src/rabbit_disk_monitor.erl18
-rw-r--r--src/rabbit_resource_monitor_misc.erl49
-rw-r--r--src/vm_memory_monitor.erl19
7 files changed, 118 insertions, 14 deletions
diff --git a/docs/rabbitmq.config.example b/docs/rabbitmq.config.example
index 13cac251e6..55c5736994 100644
--- a/docs/rabbitmq.config.example
+++ b/docs/rabbitmq.config.example
@@ -193,6 +193,19 @@
%% Alternatively, we can set a limit (in bytes) of RAM used by the node.
%%
%% {vm_memory_high_watermark, {absolute, 1073741824}},
+ %%
+ %% Or you can set absolute value using memory units.
+ %%
+ %% {vm_memory_high_watermark, {absolute, "1024M"}},
+ %%
+ %% Supported units suffixes:
+ %%
+ %% k, kiB: kibibytes (2^10 bytes)
+ %% M, MiB: mebibytes (2^20)
+ %% G, GiB: gibibytes (2^30)
+ %% kB: kilobytes (10^3)
+ %% MB: megabytes (10^6)
+ %% GB: gigabytes (10^9)
%% Fraction of the high watermark limit at which queues start to
%% page message out to disc in order to free up memory.
@@ -211,6 +224,11 @@
%% listed above for more details.
%%
%% {disk_free_limit, 50000000},
+ %%
+ %% Or you can set it using memory units (same as in vm_memory_high_watermark)
+ %% {disk_free_limit, "50MB"},
+ %% {disk_free_limit, "50000kB"},
+ %% {disk_free_limit, "2GB"},
%% Alternatively, we can set a limit relative to total available RAM.
%%
diff --git a/docs/rabbitmqctl.1.xml b/docs/rabbitmqctl.1.xml
index 885e3c4dd2..b9e478cb53 100644
--- a/docs/rabbitmqctl.1.xml
+++ b/docs/rabbitmqctl.1.xml
@@ -1958,15 +1958,22 @@
</listitem>
</varlistentry>
<varlistentry>
- <term><cmdsynopsis><command>set_vm_memory_high_watermark absolute</command> <arg choice="req"><replaceable>memory_limit_in_bytes</replaceable></arg></cmdsynopsis></term>
+ <term><cmdsynopsis><command>set_vm_memory_high_watermark absolute</command> <arg choice="req"><replaceable>memory_limit</replaceable></arg></cmdsynopsis></term>
<listitem>
<variablelist>
<varlistentry>
- <term>memory_limit_in_bytes</term>
+ <term>memory_limit</term>
<listitem><para>
The new memory limit at which flow control is
triggered, expressed in bytes as an integer number
- greater than or equal to 0.
+ greater than or equal to 0 or as string with memory unit
+ (e.g. 1024MB). Available units are:
+ k, kiB: kibibytes (2^10 bytes)
+ M, MiB: mebibytes (2^20)
+ G, GiB: gibibytes (2^30)
+ kB: kilobytes (10^3)
+ MB: megabytes (10^6)
+ GB: gigabytes (10^9)
</para></listitem>
</varlistentry>
</variablelist>
diff --git a/src/rabbit_alarm.erl b/src/rabbit_alarm.erl
index 111f780076..fdb673a61b 100644
--- a/src/rabbit_alarm.erl
+++ b/src/rabbit_alarm.erl
@@ -39,6 +39,8 @@
-define(SERVER, ?MODULE).
+
+
%%----------------------------------------------------------------------------
-ifdef(use_specs).
@@ -77,6 +79,7 @@ start() ->
ok = rabbit_sup:start_restartable_child(?MODULE),
ok = gen_event:add_handler(?SERVER, ?MODULE, []),
{ok, MemoryWatermark} = application:get_env(vm_memory_high_watermark),
+
rabbit_sup:start_restartable_child(
vm_memory_monitor, [MemoryWatermark,
fun (Alarm) ->
diff --git a/src/rabbit_control_main.erl b/src/rabbit_control_main.erl
index d21f60a440..91a079da93 100644
--- a/src/rabbit_control_main.erl
+++ b/src/rabbit_control_main.erl
@@ -417,10 +417,14 @@ action(set_vm_memory_high_watermark, Node, [Arg], _Opts, Inform) ->
rpc_call(Node, vm_memory_monitor, set_vm_memory_high_watermark, [Frac]);
action(set_vm_memory_high_watermark, Node, ["absolute", Arg], _Opts, Inform) ->
- Limit = list_to_integer(Arg),
- Inform("Setting memory threshold on ~p to ~p bytes", [Node, Limit]),
- rpc_call(Node, vm_memory_monitor, set_vm_memory_high_watermark,
- [{absolute, Limit}]);
+ case rabbit_resource_monitor_misc:parse_information_unit(Arg) of
+ {ok, Limit} ->
+ Inform("Setting memory threshold on ~p to ~p bytes", [Node, Limit]),
+ rpc_call(Node, vm_memory_monitor, set_vm_memory_high_watermark,
+ [{absolute, Limit}]);
+ {error, parse_error} ->
+ {error_string, "Unable to parse absolute memory limit value ~p", [Arg]}
+ end;
action(set_permissions, Node, [Username, CPerm, WPerm, RPerm], Opts, Inform) ->
VHost = proplists:get_value(?VHOST_OPT, Opts),
diff --git a/src/rabbit_disk_monitor.erl b/src/rabbit_disk_monitor.erl
index 3e9171b79a..30b11c0c11 100644
--- a/src/rabbit_disk_monitor.erl
+++ b/src/rabbit_disk_monitor.erl
@@ -44,6 +44,7 @@
-define(SERVER, ?MODULE).
-define(DEFAULT_MIN_DISK_CHECK_INTERVAL, 100).
-define(DEFAULT_MAX_DISK_CHECK_INTERVAL, 10000).
+-define(DEFAULT_DISK_FREE_LIMIT, 50000000).
%% 250MB/s i.e. 250kB/ms
-define(FAST_RATE, (250 * 1000)).
@@ -71,7 +72,7 @@
-ifdef(use_specs).
--type(disk_free_limit() :: (integer() | {'mem_relative', float()})).
+-type(disk_free_limit() :: (integer() | string() | {'mem_relative', float()})).
-spec(start_link/1 :: (disk_free_limit()) -> rabbit_types:ok_pid_or_error()).
-spec(get_disk_free_limit/0 :: () -> integer()).
-spec(set_disk_free_limit/1 :: (disk_free_limit()) -> 'ok').
@@ -233,10 +234,17 @@ parse_free_win32(CommandResult) ->
[{capture, all_but_first, list}]),
list_to_integer(lists:reverse(Free)).
-interpret_limit({mem_relative, R}) ->
- round(R * vm_memory_monitor:get_total_memory());
-interpret_limit(L) ->
- L.
+interpret_limit({mem_relative, Relative})
+ when is_float(Relative), Relative < 1 ->
+ round(Relative * vm_memory_monitor:get_total_memory());
+interpret_limit(Absolute) ->
+ case rabbit_resource_monitor_misc:parse_information_unit(Absolute) of
+ {ok, ParsedAbsolute} -> ParsedAbsolute;
+ {error, parse_error} ->
+ rabbit_log:error("Unable to parse disk_free_limit value ~p",
+ [Absolute]),
+ ?DEFAULT_DISK_FREE_LIMIT
+ end.
emit_update_info(StateStr, CurrentFree, Limit) ->
rabbit_log:info(
diff --git a/src/rabbit_resource_monitor_misc.erl b/src/rabbit_resource_monitor_misc.erl
new file mode 100644
index 0000000000..88f3bd1121
--- /dev/null
+++ b/src/rabbit_resource_monitor_misc.erl
@@ -0,0 +1,49 @@
+%% The contents of this file are subject to the Mozilla Public License
+%% Version 1.1 (the "License"); you may not use this file except in
+%% compliance with the License. You may obtain a copy of the License
+%% at http://www.mozilla.org/MPL/
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and
+%% limitations under the License.
+%%
+%% The Original Code is RabbitMQ.
+%%
+%% The Initial Developer of the Original Code is GoPivotal, Inc.
+%% Copyright (c) 2007-2015 Pivotal Software, Inc. All rights reserved.
+%%
+
+
+-module(rabbit_resource_monitor_misc).
+
+-export([parse_information_unit/1]).
+
+-ifdef(use_spec).
+
+-spec(parse_information_unit/1 :: (integer() | string()) ->
+ {ok, integer()} | {error, parse_error}).
+
+-endif.
+
+parse_information_unit(Value) when is_integer(Value) -> {ok, Value};
+parse_information_unit(Value) when is_list(Value) ->
+ case re:run(Value,
+ "^(?<VAL>[0-9]+)(?<UNIT>kB|KB|MB|GB|kb|mb|gb|Kb|Mb|Gb|kiB|KiB|MiB|GiB|kib|mib|gib|KIB|MIB|GIB|k|K|m|M|g|G)?$",
+ [{capture, all_names, list}]) of
+ {match, [[], _]} ->
+ {ok, list_to_integer(Value)};
+ {match, [Unit, Num]} ->
+ Multiplier = case Unit of
+ KiB when KiB =:= "k"; KiB =:= "kiB"; KiB =:= "K"; KiB =:= "KIB"; KiB =:= "kib" -> 1024;
+ MiB when MiB =:= "m"; MiB =:= "MiB"; MiB =:= "M"; MiB =:= "MIB"; MiB =:= "mib" -> 1024*1024;
+ GiB when GiB =:= "g"; GiB =:= "GiB"; GiB =:= "G"; GiB =:= "GIB"; GiB =:= "gib" -> 1024*1024*1024;
+ KB when KB =:= "KB"; KB =:= "kB"; KB =:= "kb"; KB =:= "Kb" -> 1000;
+ MB when MB =:= "MB"; MB =:= "mB"; MB =:= "mb"; MB =:= "Mb" -> 1000000;
+ GB when GB =:= "GB"; GB =:= "gB"; GB =:= "gb"; GB =:= "Gb" -> 1000000000
+ end,
+ {ok, list_to_integer(Num) * Multiplier};
+ nomatch ->
+ % log error
+ {error, parse_error}
+ end.
diff --git a/src/vm_memory_monitor.erl b/src/vm_memory_monitor.erl
index 1d98843365..e599f50103 100644
--- a/src/vm_memory_monitor.erl
+++ b/src/vm_memory_monitor.erl
@@ -49,6 +49,7 @@
%% wrong. Scale by vm_memory_high_watermark in configuration to get a
%% sensible value.
-define(MEMORY_SIZE_FOR_UNKNOWN_OS, 1073741824).
+-define(DEFAULT_VM_MEMORY_HIGH_WATERMARK, 0.4).
-record(state, {total_memory,
memory_limit,
@@ -63,7 +64,7 @@
-ifdef(use_specs).
--type(vm_memory_high_watermark() :: (float() | {'absolute', integer()})).
+-type(vm_memory_high_watermark() :: (float() | {'absolute', integer() | string()})).
-spec(start_link/1 :: (float()) -> rabbit_types:ok_pid_or_error()).
-spec(start_link/3 :: (float(), fun ((any()) -> 'ok'),
fun ((any()) -> 'ok')) -> rabbit_types:ok_pid_or_error()).
@@ -208,7 +209,7 @@ set_mem_limits(State, MemLimit) ->
_ ->
TotalMemory
end,
- MemLim = interpret_limit(MemLimit, UsableMemory),
+ MemLim = interpret_limit(parse_mem_limit(MemLimit), UsableMemory),
error_logger:info_msg("Memory limit set to ~pMB of ~pMB total.~n",
[trunc(MemLim/?ONE_MB), trunc(TotalMemory/?ONE_MB)]),
internal_update(State #state { total_memory = TotalMemory,
@@ -220,6 +221,20 @@ interpret_limit({'absolute', MemLim}, UsableMemory) ->
interpret_limit(MemFraction, UsableMemory) ->
trunc(MemFraction * UsableMemory).
+
+parse_mem_limit({absolute, Limit}) ->
+ case rabbit_resource_monitor_misc:parse_information_unit(Limit) of
+ {ok, ParsedLimit} -> {absolute, ParsedLimit};
+ {error, parse_error} ->
+ rabbit_log:error("Unable to parse vm_memory_high_watermark value ~p", [Limit]),
+ ?DEFAULT_VM_MEMORY_HIGH_WATERMARK
+ end;
+parse_mem_limit(Relative) when is_float(Relative), Relative < 1 ->
+ Relative;
+parse_mem_limit(_) ->
+ ?DEFAULT_VM_MEMORY_HIGH_WATERMARK.
+
+
internal_update(State = #state { memory_limit = MemLimit,
alarmed = Alarmed,
alarm_funs = {AlarmSet, AlarmClear} }) ->