(Я постараюсь сделать этот вопрос как можно короче, четко описав ситуацию. Пожалуйста, прокомментируйте, если что-то упущено.)
Ситуация
- Я запускаю кластер с тремя серверами в одном центре обработки данных.
- Для упрощения развертывания на каждом сервере выполняется один и тот же код приложения.
Цель
- Запускать одну задачу (назовем ее Task X) каждую минуту на одном сервере.
В этих условиях
- Кластер остается распределенным и высокодоступным
- Каждый сервер продолжает выполнять один и тот же код приложения. Другими словами, не существует такого понятия, как «развернуть код A на главном сервере и развернуть код B на всех дополнительных серверах».
Причина, по которой я не хочу различать типы серверов, заключается в том, чтобы поддерживать высокую доступность (избежание проблем, когда так называемый главный сервер выходит из строя), избыточность (распределение нагрузки) и избегать создания сложной процедуры развертывания, когда мне нужно развертывать разные серверы. приложений к разным типам серверов.
Почему это так сложно? Если бы я добавил код, который будет выполнять эту задачу каждые 5 минут, то каждый сервер выполнял бы ее, потому что на каждом сервере выполняется один и тот же код приложения. Таким образом, они должны иметь возможность координировать, какой сервер будет работать одинаково во время каждого тика.
Я могу использовать распределенные механизмы обмена сообщениями, такие как Apache Kafka
или Redis
. Если использовать такой механизм для координации такой задачи, как будет работать такой «алгоритм»?
Я задал этот вопрос кому-то другому, его ответ заключался в том, чтобы использовать очередь задач. Однако это не решает проблему, потому что остается вопрос: какой сервер будет добавлять задачу в очередь задач? Если все серверы добавят задачу в очередь, это приведет к дублированию записей. Более того, какой сервер будет выполнять следующую задачу в очереди? Все это нужно решать через координацию внутри кластера, без разграничения между разными типами серверов.
db.jobs.ensureIndex( { "job_x": 1 }, { expireAfterSeconds: 300 } )
02.11.2012ensure index
должен выглядеть примерно так:db.jobs.ensureIndex( { "job_x": 1 }, { unique: true, expireAfterSeconds: 300 } )
. Имейте в виду, что Redis использует только 1 МБ памяти, когда он пуст, и имеет множество других применений, кроме приведенного выше. 02.11.2012Date
. Поэтому требуется другой индекс с уникальным полем, потому что дата никогда не бывает уникальной. 05.11.2012