В кластере 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 (т. е. список кандидатов), при необходимости сжимает список до основных узлов таблицы, удаляет таблицы, которые будут игнорироваться (по любой причине), сжимает список до текущих подключенных узлов, а затем выбирает в следующем порядке:

  1. первая-disc_only_copies
  2. любой доступный узел

самая важная часть заключается в том списке!--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 кластер баз данных, хорошее начало, вероятно, является циклическим алгоритмом (или случайным, как вы предлагаете).