Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Per vhost message store #766

Merged
merged 55 commits into from
Dec 24, 2016
Merged

Per vhost message store #766

merged 55 commits into from
Dec 24, 2016

Conversation

hairyhum
Copy link
Contributor

@hairyhum hairyhum commented Apr 21, 2016

Closes #567.

rabbit_msg_store is a gen_server having directory in it's working state and storing data in Dir/server_name.
To be able to have multiple message stores where should be multiple rabbit_msg_store servers with different names and different directories (or just different names).
rabbit_msg_store_vhost_sup is a supervisor, that can create a message store for specified VHost. This supervisor is started instead of rabbit_msg_store during boot process.
rabbit_variable_queue access message store using message store clients and can request this client from supervisor (supplying VHost) the same way as it does from message store directly.

To move messages from old message store format to the VHost based format there are special boot step.
This boot step is running before queue recovery step so queue index and message store is not yet started. This boot step are performing new scope of upgrades: queues.
move_messages_to_vhost_store is upgrade performing message migration. It starts queue indexes for durable queues, recovers old format message store, reads all messages from index that is stored in message store and writes them to the new store. After migrating all durable queues old message store is being deleted.

Message stores are placed in rabbit_mnesia:dir()/VHOST/msg_store_typeVHOST. VHOST is VHost name encoded with base64.
Separate VHOST directories are used to make it easier to operator to control multitenancy. Queue indexes may be moved to VHOST directories as well.

Tested manually so far.

@hairyhum hairyhum force-pushed the rabbitmq-server-567 branch from 31a922b to 99ee963 Compare June 2, 2016 12:40
@hairyhum hairyhum force-pushed the rabbitmq-server-567 branch from 43a239d to 38b51ac Compare October 18, 2016 15:37
@hairyhum hairyhum force-pushed the rabbitmq-server-567 branch from 9a94225 to 36f3e67 Compare October 20, 2016 13:50
@hairyhum
Copy link
Contributor Author

Queue indexes was also moved to vhost storage directory, so it's easier to distinguish queues from different vhosts.
New queue index location: mnesia_dir/queues/:queue_id -> mnesia_dir/:vhost/queues/:queue_id
So directory mnesia_dir/:vhost effectively contains all messages data.
If vhost is deleted - all it's messages data is deleted, including directory.
It's possible to delete all vhost data by running rabbit_vhost:purge_messages/1, that will delete vhost message store and all it's queues indexes. It's not safe operation.

Testing

Migration to per-vhost message store mechanism can be tested using make in https://github.com/rabbitmq/rabbitmq-server-release/tree/stable/upgrade.

@hairyhum hairyhum changed the title DO NOT MERGE Per vhost message store Per vhost message store Oct 20, 2016
@michaelklishin michaelklishin self-assigned this Nov 9, 2016
Copy link
Member

@michaelklishin michaelklishin left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks promising but vhost-to-dir naming function is not safe.


blank_state_dir(Dir) ->
blank_state_dir_funs(Dir,
fun (_) -> ok end,
fun (_) -> ok end).

queue_dir(#resource{ virtual_host = VHost } = QueueName) ->
%% Queue directory is rabbit_mnesia_dir/:vhost/queues/:queue_id
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It would be a bit clearer if we used {node_database_dir}/vhosts/{vhost}/queues/{queue}.

end.
all_queue_directory_names() ->
QueuesBaseDir = queues_base_dir(),
filelib:wildcard(filename:join([QueuesBaseDir, "*", "queues", "*"])).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See below. It would be less risky if we used {node_database_dir}/vhosts/{vhost}/queues/{queue} for path naming.

@@ -185,3 +197,6 @@ info_all(Ref, AggregatorPid) -> info_all(?INFO_KEYS, Ref, AggregatorPid).
info_all(Items, Ref, AggregatorPid) ->
rabbit_control_misc:emitting_map(
AggregatorPid, Ref, fun(VHost) -> info(VHost, Items) end, list()).

dir(Vhost) ->
base64:encode(Vhost).
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

After a brief internal discussion we decided it's not safe to use Base64 or Base32 for our needs because they both use lower and upper case characters. Queue directory naming uses MD5 hashing, which is safe but annoying for operators as it's not easy to infer what directory corresponds to what queue.

I suspect we can create a text file in each vhost (and possibly queue) directory that contains its actual name.

@michaelklishin
Copy link
Member

Another change worth considering is keeping track of vhost message store processes in an ETS table as opposed to using registered processes: with very high vhost churn we run the risk of exhausting the atom table.

@hairyhum hairyhum changed the title DO NOT MERGE Per vhost message store Per vhost message store Nov 30, 2016
@hairyhum hairyhum force-pushed the rabbitmq-server-567 branch from b57483d to f43990d Compare November 30, 2016 12:23
@hairyhum
Copy link
Contributor Author

Queues are migrated in batches of 100 in parallel by default. The batch size can be configured with queue_migration_batch_size environment variable.

@hairyhum
Copy link
Contributor Author

Per queue migration messages are logged to rabbit_upgrade.log file.

ok = rabbit_file:ensure_dir(NewQueueDir),
ok = rabbit_file:rename(OldQueueDir, NewQueueDir);
false ->
rabbit_log:info("Queue index directoy not found for queue ~p~n",
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

directoy should be directory

@michaelklishin michaelklishin merged commit fdf783f into master Dec 24, 2016
michaelklishin added a commit that referenced this pull request Jun 23, 2017
It emits a warning and breaks compilation on OTP 20.
Originally introduced in 492e23b,
likely unintentionally.

Fixes #1272, references #567, #766.
@dumbbell dumbbell deleted the rabbitmq-server-567 branch January 2, 2018 15:27
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants