Erlang: распределенная работа над массивом - PullRequest
4 голосов
/ 02 февраля 2012

Я работаю над проектом, в котором у нас есть массив атомов, который действует как хэш.Всякий раз, когда пользователь подключается к серверу, определенное значение хэшируется, и этот хэш используется в качестве индекса для поиска элемента в массиве и возврата этого элемента.«Внешние силы» (которые обрабатываются продолжительным gen_server) могут изменить этот массив, поэтому я не могу просто жестко его кодировать.Моя проблема заключается в том, как «разместить» этот массив.

Моей первой реализацией был простой gen_server, который хранил копию массива и отправлял ее тому, кто ее запрашивал.Процесс, запрашивающий его, может затем пройти его и получить нужный индекс.Эта реализация имела чрезмерное количество используемой памяти, что я приписал тому, что вокруг него столько копий этого массива.

В моей текущей реализации есть центральный сервер gen_server, который обрабатывает состояние этого массива, и дочерние элементыкоторые обрабатывают фактические запросы.Когда состояние изменяется, центральный gen_server обновляет дочерние элементы.Когда процесс хочет найти свой результат хеширования, он отправляет свой индексный номер в центральный сервер gen_server, который направляет запрос одному из дочерних элементов.Дочерний объект перебирает свой «локальный» список и отправляет полученный атом обратно в исходный процесс.

Проблема с текущей реализацией заключается в том, что он перегружен при большом трафике.Я пробовал использовать все больше и больше детей, но я почти уверен, что центральным gen_server является узкое место.

У кого-нибудь есть идеи по поводу лучшего решения моей проблемы?

РЕДАКТИРОВАТЬ:% s / массив / список / г

Ответы [ 2 ]

6 голосов
/ 02 февраля 2012

Я предлагаю вам использовать ETS Tables. Я думаю, что метод Array недостаточно эффективен. С ETS Table, созданным как общедоступный в бэкенде приложения, любой процесс может искать элемент, как только он ему нужен. ETS Tables в текущих новых версиях erlang имеют возможность одновременного доступа.

%% Lets create a record structure 
%% where by the key will be a value
%% in the array.
%% For now, i do not know what to 
%% put in the field: 'other'<br>
-record(element,{key,other}).<br>
create_table(TableName)->
    Options = [
                named_table,set,
                public,
                {keypos,2}, %% coz we are using record NOT tuple
                {write_concurrency,true}
            ],
    case ets:new(TableName,Options) of
        TableName -> {success,true};
        Error -> {error,Error}
    end.<br>
lookup_by_hash(TableName,HashValue)->
    try ets:lookup(TableName,HashValue) of
        Value -> {value,Value};
    catch
        X:Y -> {error,{X,Y}}
    end.
При таком типе организации вы избежите A Single Point of Failure, возникающих из-за одного gen_server, содержащего данные. Эти данные нужны многим процессам и, следовательно, не должны храниться в одном процессе. Вот где таблица доступна для любого процесса в любое время, как только ему нужно выполнить поиск.

Значения в массиве должны быть преобразованы в записи вида как element, а затем вставлены в ETS Tables.

Преимущества такого подхода

1. Мы можем создать как можно больше ETS Tables
2. Таблица ETS может обрабатывать гораздо больше элементов, чем структура данных, такая как список или массив, с гораздо более низким сопоставимым потреблением памяти.
3. ETS Tables может быть одновременно доступен любому доступному процессу, и, следовательно, вам не понадобится центральный процесс или сервер для обработки данных
4. Один процесс или gen_server, содержащий эти данные, означает, что если они скомпрометированы (выйдут из строя из-за полного почтового ящика), они будут недоступны, следовательно, процессам, которым нужен массив, придется ждать, пока этот сервер перезапустится, или я не знаю ....
5. Доступ к данным массива путем отправки сообщений с запросами и создания копий одного и того же массива для каждого процесса, который нуждается в этом, не является "Erlangic".
6. Наконец, ETS Tables право собственности может быть передано от процесса к процессу. Когда происходит сбой процесса владения (только gen_servers может обнаружить, что они умирают [обратите внимание на это]), он может передать ETS Table другому процессу, чтобы вступить во владение. Проверьте здесь: ETS Give Away

Это мое мышление.
1 голос
/ 02 февраля 2012

Не уверен, поможет ли это, но вы могли бы управлять центральным хеш-значением в распределенной хеш-таблице (независимо от вашего хеш-бизнеса) так же, как любое другое значение? Таким образом, несколько процессов могут взять на себя нагрузку вместо одного центрального процесса.

Из того, что я прочитал, массив, похоже, не обязательно должен быть массивом.

...