2016-12-04 3 views
0

У меня есть программа Python, которую я запускаю как работу в кластере Kubernetes каждые 2 часа. У меня также есть веб-сервер, который запускает работу всякий раз, когда пользователь нажимает кнопку на странице.Обеспечение не более одного экземпляра выполнения задания на Kubernetes и запись в Postgresql

Мне нужно убедиться, что в кластере в любой момент времени выполняется только один экземпляр задания.

Учитывая, что я использую Kubernetes для запуска задания и подключения к Postgresql изнутри задания, решение должно каким-то образом использовать эти два. Я немного об этом подумал и пришел к следующему:

  1. Найти параметр в Кубернете, который установил бы этот предел, попытки запустить второй экземпляр затем потерпят неудачу. Я не смог найти эту настройку.
  2. Создайте общую блокировку или мьютексы. Недостатком является то, что если сбой работы, я не могу разблокироваться, прежде чем уйти.
    1. Kubernetes работает etcd, может быть, я могу использовать это
    2. Создать таблицу «замок» в Postgresql, когда новый экземпляр соединяется, он проверяет, является ли это только один работает. Используйте транзакции так или иначе, чтобы один выигрывал и продолжал, а другие уходили. Я еще не думал об этом, но должен работать.
  3. Query kubernetes API для ярлыка, который я использую для работы, см., Есть ли какие-то экземпляры. Это может быть не атомарным, поэтому более одного экземпляра может проскользнуть.

Каковы обычные решения этой проблемы с учетом выбора платформы, которую я сделал? Что мне делать, чтобы не изобретать колесо и не иметь что-то надежное?

ответ

1

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

Там может быть 2 подхода к реализации этого:

  1. Вы можете поставить механизм проверки внутри кода jobserver, чтобы гарантировать, что даже если 2 API вызовы происходят одновременно на сервере заданий, только один выполняется, в то время как другие ждут. Вы можете использовать функции блокировки языковой платформы для достижения этой цели или использовать очередь сообщений.
  2. Вы можете поместить механизм проверки вне кода сервера работ (в базе данных), чтобы гарантировать выполнение только одного вызова API. Похоже на то, что вы предложили. Если вы используете транзакцию postgres, вам не нужно беспокоиться о сбое вашей работы и о том, что значение оставшегося останова установлено.

Достоинства/недостатки обоих подходов просты. Основное различие в моем разуме между 1 & 2 заключается в том, что если вы обновите код сервера задания, то может возникнуть ситуация, когда одновременно могут работать 2 сервера заданий. Это разрушит свойство изоляции, которое вы хотите. Следовательно, база данных может работать лучше или быть более идиоматичной в смысле k8s (все серверы являются апатридами, поэтому все полезные свойства k8s работают, помещают любое общее состояние в базу данных, которая может обрабатывать параллелизм).

Обращаясь свои идеи, вот мои мысли:

  1. Найти установку в K8S, который будет ограничивать это: K8S не заводится вещи с таким же именем (в метаданных спецификации). Но все остальное идет на работу, и k8s начнет другую работу.

  2. a) etcd3 поддерживает распределенные блокирующие примитивы. Тем не менее, я никогда не использовал это, и я действительно не знаю, на что нужно следить.

  3. b) значение блокировки postgres должно работать. Даже в случае сбоя работы вам не нужно беспокоиться о стоимости оставшегося набора блокировок.

  4. Запрос сервера API k8s для вещей, которые должны быть атомарными, - это не очень хорошая идея, как вы сказали. Я использовал систему, которая реагирует на события k8s (например, изменение аннотации на спецификации объекта), но у меня были ошибки, когда мой «оператор» внезапно прекратил получать события k8s и должен быть перезапущен или снова, если захочу чтобы направить обновление на сервер обработчика событий, тогда могут быть два обработчика событий, которые существуют одновременно.

Я бы порекомендовал вам придерживаться того, с которым вы лучше всего знакомы. В моем случае это будет реализация сервера заданий типа k8s, который работает как сервер и прослушивает вызовы событий/API.

+0

Спасибо, я попытаюсь сначала использовать подход «k8s не запускается с тем же именем» или, возможно, «postgres lock». – user7610

Смежные вопросы