Nano Hash - криптовалюты, майнинг, программирование

Координация выполнения одной периодической задачи между серверами в кластере

(Я постараюсь сделать этот вопрос как можно короче, четко описав ситуацию. Пожалуйста, прокомментируйте, если что-то упущено.)

Ситуация

  • Я запускаю кластер с тремя серверами в одном центре обработки данных.
  • Для упрощения развертывания на каждом сервере выполняется один и тот же код приложения.

Цель

  • Запускать одну задачу (назовем ее Task X) каждую минуту на одном сервере.

В этих условиях

  • Кластер остается распределенным и высокодоступным
  • Каждый сервер продолжает выполнять один и тот же код приложения. Другими словами, не существует такого понятия, как «развернуть код A на главном сервере и развернуть код B на всех дополнительных серверах».

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

Почему это так сложно? Если бы я добавил код, который будет выполнять эту задачу каждые 5 минут, то каждый сервер выполнял бы ее, потому что на каждом сервере выполняется один и тот же код приложения. Таким образом, они должны иметь возможность координировать, какой сервер будет работать одинаково во время каждого тика.

Я могу использовать распределенные механизмы обмена сообщениями, такие как Apache Kafka или Redis. Если использовать такой механизм для координации такой задачи, как будет работать такой «алгоритм»?

Я задал этот вопрос кому-то другому, его ответ заключался в том, чтобы использовать очередь задач. Однако это не решает проблему, потому что остается вопрос: какой сервер будет добавлять задачу в очередь задач? Если все серверы добавят задачу в очередь, это приведет к дублированию записей. Более того, какой сервер будет выполнять следующую задачу в очереди? Все это нужно решать через координацию внутри кластера, без разграничения между разными типами серверов.


  • @ Чарльз, как это не о координации? 31.10.2012
  • Координация в целом очень и очень расплывчата, и это было бы плохой меткой. Существующие теги довольно хорошо классифицируют ваш вопрос. 31.10.2012
  • Спасибо за добавление, это прекрасно описывает проблему, которую я собирался написать :) 20.02.2013
  • @Стивен, это здорово. На каком языке вы работаете? 20.02.2013
  • @Tom, среда Python/Django, но почти та же проблема. У меня есть несколько машин, я хочу, чтобы одна из них выполняла задачу x, но не все из них, но мне не нужна главная машина. Я хочу, чтобы одна машина могла исчезнуть без каких-либо вредных последствий (сохранить нагрузку/избыточность и т. д.). 20.02.2013
  • @Стивен, хорошо, это именно то, что мне нужно. У меня сработала распределенная блокировка (см. ответ с MongoDB вместо Redis). Самое главное, что нужно сделать, это убедиться, что база данных может разблокировать задачу, если сервер, выполняющий задачу, отключится, установив тайм-аут (или TTL). 21.02.2013
  • Замечательно, спасибо за комментарии. 21.02.2013

Ответы:


1

Похоже, вы ищете распределенную блокировку. Redis прекрасно справляется с этим с помощью setnx. Если вы объедините его с expire, вы можете создавать глобальные блокировки, которые снимаются каждые N секунд.

setnx запишет значение и вернет true только в том случае, если ключ еще не существует. Операции Redis являются атомарными, поэтому только первый сервер, который вызовет setnx после истечения срока действия ключа, получит разрешение на выполнение задачи.

Вот пример на рубине:

# Attempt to get the lock for 'Task X' by setting the current server's hostname
if redis.setnx("lock:task:x", `hostname`.chomp)
  # Got the lock, now I set it to expire after 5 minutes
  redis.expire("lock:task:x", 60 * 5)
  # This server has the go ahead to execute the task
  execute_task_x
else
  # Failed to get the lock. Another server is doing the work this time around
end

При этом вы по-прежнему зависите от вызова одного сервера Redis Master, если только вы не воспользуетесь преимуществом redis-sentinel. Просмотрите документацию redis-sentinel, чтобы узнать, как настроить автоматическое отключение.

31.10.2012
  • Интересно, я не думал, что база данных может помочь мне здесь. Я упомянул Redis, но больше из-за его pubsub. Вы знаете, возможно ли то же самое с MongoDB? С точки зрения БД я предпочитаю его Redis. 02.11.2012
  • Я верю, что вы можете, хотя я не пробовал это лично. Вам нужно будет установить уникальный индекс для ключа и срок действия до истечения срока действия. db.jobs.ensureIndex( { "job_x": 1 }, { expireAfterSeconds: 300 } ) 02.11.2012
  • Я забыл добавить «уникальный: правда». Вызов mongo ensure index должен выглядеть примерно так: db.jobs.ensureIndex( { "job_x": 1 }, { unique: true, expireAfterSeconds: 300 } ). Имейте в виду, что Redis использует только 1 МБ памяти, когда он пуст, и имеет множество других применений, кроме приведенного выше. 02.11.2012
  • Спасибо, я попробую и отчитаюсь. Обратите внимание, что для этого требуется MongoDB 2.2+ (docs.mongodb.org/manual/tutorial/expire -данные). 03.11.2012
  • +50 Это работает, но значение должно быть типа Date. Поэтому требуется другой индекс с уникальным полем, потому что дата никогда не бывает уникальной. 05.11.2012

  • 2

    Для этого также можно использовать JGroups. Пример реализации можно найти здесь

    16.10.2014
    Новые материалы

    Кластеризация: более глубокий взгляд
    Кластеризация — это метод обучения без учителя, в котором мы пытаемся найти группы в наборе данных на основе некоторых известных или неизвестных свойств, которые могут существовать. Независимо от..

    Как написать эффективное резюме
    Предложения по дизайну и макету, чтобы представить себя профессионально Вам не позвонили на собеседование после того, как вы несколько раз подали заявку на работу своей мечты? У вас может..

    Частный метод Python: улучшение инкапсуляции и безопасности
    Введение Python — универсальный и мощный язык программирования, известный своей простотой и удобством использования. Одной из ключевых особенностей, отличающих Python от других языков, является..

    Как я автоматизирую тестирование с помощью Jest
    Шутка для победы, когда дело касается автоматизации тестирования Одной очень важной частью разработки программного обеспечения является автоматизация тестирования, поскольку она создает..

    Работа с векторными символическими архитектурами, часть 4 (искусственный интеллект)
    Hyperseed: неконтролируемое обучение с векторными символическими архитектурами (arXiv) Автор: Евгений Осипов , Сачин Кахавала , Диланта Хапутантри , Тимал Кемпития , Дасвин Де Сильва ,..

    Понимание расстояния Вассерштейна: мощная метрика в машинном обучении
    В обширной области машинного обучения часто возникает необходимость сравнивать и измерять различия между распределениями вероятностей. Традиционные метрики расстояния, такие как евклидово..

    Обеспечение масштабируемости LLM: облачный анализ с помощью AWS Fargate и Copilot
    В динамичной области искусственного интеллекта все большее распространение получают модели больших языков (LLM). Они жизненно важны для различных приложений, таких как интеллектуальные..