Как стать автором
Обновить

Комментарии 16

Отличная стать, хорошо что еще есть отличные авторские работы по отличным языкам!
На мой взгляд работа станет неплохой если результат хотя бы минимально сравнят с альтернативными решениями. А то получился сферический эрланг в вакууме. У меня например есть опасение, что кластер на эрланге будет работать медленнее, чем однопоточный вариант на си.
А программа-минимум, бенчмарки относительно самого себя. Сейчас доступно море технологий дающих линейное масштабирование, является ли эрланг одной из них? С 1000 воркеров скорость в 1000 раз больше? Если поставить 50 нод, вырастет ли в 50 раз производительность?
в статье предполагается, что читатель в курсе, что такое кластер, распределенное вычисление, и зачем они нужны. если у вас есть задача, которая быстрее решается в один поток на си — делайте в один поток на си.
Понимаю поинт, однако:
1) Если в Erlang не делать вычислений, о которых известно, что они работают в Erlang медленно, то скорость работы Erlang приложения будет не хуже, чем аналогичного приложения на Java.
2) В Erlang есть проработанный механизм, как подключать код на C. :)
3) Мы не бьемся за проценты от скорости работы приложения. Для нас важнее скорость разработки, простота поддержки и мультиплатформенность.
Судя по всему поинт таки не поняли. Например в java есть stream api, там есть примерно тот же самый map и очень похожий parallel (который сам делает всё волшебство). Загвоздка в том, что на многих задачах это приводит к тормозам, даже когда в теории вроде как должно параллелиться. Так и тут — без бенчмарков неубедительно.
Например в java есть stream api


А это… когда оно там появилось, сколько лет назад?
Я отвечал на вопрос: Erlang cluster VS однопоточный вариант на С :).
Что касается тестирования Erlang кластера как кластера, то, да, тестирование тут очень важно. Мы тут не привнесли ничего нового: кластер, который мы поднимаем — стандартный Erlang кластер, для которого бенчмарки, по идее, уже должны быть сделаны другими исследователями до нас :). Вопрос действительно важный, я скину ссылки на эти исследования, если найду.
Спасибо за предложение сравнить Erlang кластер с другими решениями, возможно в будущем мы сделаем такие бенчмарки и опубликуем их (это не тривиальная задача).
Спасибо.
Erlang — язык со своими плюсами и минусами.
Некоторые задачи решаются в Erlang очень красиво, а следовательно — быстро и надежно.
Было бы полезно, если бы кто-нибудь написал похожую статью, но используя Elixir.
Там все значительно проще. Мне кажется, даже статья не понадобится. Смотрите.

Это parallel map на локальной ноде
defmodule Parallel do
  def pmap(collection, func) do
    collection
    |> Enum.map(&(Task.async(fn -> func.(&1) end)))
    |> Enum.map(&Task.await/1)
  end
end


Чтобы пускать таски на удаленных нодах, нам нужен TaskSupervisor вместо обычного Task
# On the remote node
Task.Supervisor.start_link(name: MyApp.DistSupervisor)

# On the client
Task.Supervisor.async({MyApp.DistSupervisor, :remote@local},
                      MyMod, :my_fun, [arg1, arg2, arg3])


Естественно, супервизор надо будет в supervision tree добавить или пускать через start_link, и модуль на нодах написать, который будет дергаться через TaskSupervisor. Остальное сделает эликсир сам.

Ссылки, куда посмотреть можно:
hexdocs.pm/elixir/Task.Supervisor.html
elixir-recipes.github.io/concurrency/parallel-map
elixir-lang.org/getting-started/mix-otp/distributed-tasks-and-configuration.html
Спасибо за подробный ответ.
Ничего не имею против вашего решения, но действительно ли это решение эквивалентно
нашему?
1) Есть ли ограничение по количеству одновременно запущенных процессов-воркеров?
2) Есть ли остановка в случае креша в любом из воркеров?
3) Есть ли остановка в случае таймаута при ожидании ответа от воркера?
4) Можете привести примеры тестов, которые у нас приведены для `dmap_pmap:map`?

Elixir компилирует в Erlang VM, поэтому на вскидку не совсем понятно, зачем писать отдельное решение для dmap на Elixir, если можно просто использовать готовое решение на Erlang, которое просто синтегрировать со своим Elixir кодом :).
Это не эквивалентное решение. Это решение тех же задач. Да и вообще, я не собираюсь меряться кодом. Человек спросил, как на Elixir сделать аналогичную штуку, я ответил. В общих чертах, но по документации легко будет разобраться в тонкостях.

1. Сколько запустите, столько и будет. Ноды назначаются явно. Разумеется, в случае реального боевого проекта это можно легко автоматизировать.
Однако если я захочу ограничить количество параллельных процессов, я не буду писать велосипед, а использую poolboy.

Да и вообще, poolboy прекрасно решает большинство проблем по распределению задач между процессами.

2. Креш Task уронит вызывающую функцию. Строго говоря, несмотря на парадигму let it crash, я не считаю это хорошей идеей. Но механизм есть.

3. await(task, timeout \\ 5000)
Но опять же, я не считаю остановку в случае вылета по таймауту хорошей идеей. У меня на проекте есть такой вариант:
ret = case Task.yield(task, 60000) do
      {:ok, result} ->
        result
      nil ->
        Task.shutdown(task)
        :timeout
    end

По крайней мере я хочу получить результаты, которые есть. С проблемами разберемся позже. Но у меня такой род приложений, что частичная потеря данных простительна, а вот лишние задержки — не очень хорошо.

4. Нет, тестов нет. При случае сделаю, пока задачи запускать таски на удаленных нодах не было. pmap используем, но на локальных нодах.

У нас проекты на Elixir, и я не вижу смысла писать на Erlang и потом интегрировать код с Elixir, если могу сразу все сделать на Elixir. Даже учитывая то, что мне все равно часто приходится возиться с кодом на Erlang.

В эликсире будет использоваться тот же модуль rpc и функция call, ничего полезного в общем

Поскольку оба языка Erlang и Elixir компилируют в код Erlang VM, то функции из Erlang либы доступны в Elixir приложении и обратно (насколько я понимаю). Другими словами функцию `dmap_dmap:map` можно вызвать из приложения на Elixir и на Elixir же написать код для воркера :).
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории