В кластере mnesia, какой узел опрашивается?
предположим, у вас есть таблица mnesia, реплицированная на узлах A и B. Если на узле C, который не содержит копии таблицы, я делаю mnesia:change_config(extra_db_nodes, [NodeA, NodeB])
, а затем на узле C я делаю mnesia:dirty_read(user, bob)
как узел C выбирает копию таблицы узла для выполнения запроса?
2 ответов
согласно моему собственному исследованию ответ на вопрос - он выберет самый последний подключенный узел. Я буду благодарен за указание на ошибки, если они найдены-mnesia-действительно сложная система!
As Дэн Гудмундссон указал в списке рассылки алгоритм выбора удаленного узла для запроса определяется в mnesia_lib:set_remote_where_to_read/2
. Это следующее
set_remote_where_to_read(Tab, Ignore) ->
Active = val({Tab, active_replicas}),
Valid =
case mnesia_recover:get_master_nodes(Tab) of
[] -> Active;
Masters -> mnesia_lib:intersect(Masters, Active)
end,
Available = mnesia_lib:intersect(val({current, db_nodes}), Valid -- Ignore),
DiscOnlyC = val({Tab, disc_only_copies}),
Prefered = Available -- DiscOnlyC,
if
Prefered /= [] ->
set({Tab, where_to_read}, hd(Prefered));
Available /= [] ->
set({Tab, where_to_read}, hd(Available));
true ->
set({Tab, where_to_read}, nowhere)
end.
таким образом, он получает список active_replicas (т. е. список кандидатов), при необходимости сжимает список до основных узлов таблицы, удаляет таблицы, которые будут игнорироваться (по любой причине), сжимает список до текущих подключенных узлов, а затем выбирает в следующем порядке:
- первая-
disc_only_copies
- любой доступный узел
самая важная часть заключается в том списке!--4-->, поскольку он определяет порядок узлов в списке кандидатов.
список active_replicas
формируется удаленными вызовами mnesia_controller:add_active_replica/*
от вновь подключенных узлов к старым узлам (т. е. тем, которые были в кластере раньше), что сводится к функции add/1
, которая добавляет элемент в начало списка.
отсюда ответ на вопрос - это выбрать самый последний подключенный узел.
заметки: Чтобы проверить список активных реплик на данном узле, вы можете использовать этот (грязный хак) код:
[ {T,X} || {{T,active_replicas}, X} <- ets:tab2list(mnesia_gvar) ].
ну, узлу C нужно будет связаться с узлом A или узлом B для выполнения запроса. Таким образом, узел C должен будет сам решить, какую копию таблицы выполнить запрос.
Если вам нужно что-то большее, чем это, вам нужно будет иметь какой-то алгоритм, который решит, какой узел запрашивать, или даже реплицировать таблицу на узле C (это обычно зависит от того, какие характеристики вы хотите / нужны).
Если узел A и узел B образуют или являются частью a кластер баз данных, хорошее начало, вероятно, является циклическим алгоритмом (или случайным, как вы предлагаете).