Сначала я бы попробовал изменить способ планирования заданий, чтобы инструмент, отправляющий задания, сначала проверял наличие запущенных заданий, а затем регистрировал, что он пропускает отправку из-за уже запущенного задания. Однако есть и другие варианты.
Вариант 1 - Сервер истории
Это самый простой и самый прямой вариант. Сервер истории Spark предоставляет пользовательский интерфейс, который показывает все приложения (запускаемые), когда они были запущены, а если еще не запущены, то когда они завершились или потерпели неудачу. См. Документацию Spark по Monitoring .
Там более короткое описание настройки сервера истории: https://luminousmen.com/post/spark-history-server-and-monitoring-jobs-performance
Option2 - Сервер временной шкалы запросов (YARN)
См. https://hadoop.apache.org/docs/current/hadoop-yarn/hadoop-yarn-site/TimelineServer.html
Вариант 3 - Анализ журналов
Как упомянутый в одном из комментариев, вы можете искать в своих журналах. Проще всего, если вы уже интегрировались с таким инструментом, как logsta sh.
Если такой инструмент не включен, вы можете попробовать более простой метод использования журналирования из планировщика в вашем кластере. Включите агрегирование журналов, если оно еще не включено. Как вы это делаете, зависит от того, используете ли вы YARN, Mesos или какой-либо другой вариант для запуска Spark. Например, если вы используете YARN и он настроен для агрегирования журналов, вы можете просматривать все отправленные идентификаторы приложений и их статусы, используя yarn application -list -appStates ALL
, и собирать журналы для приложения, используя yarn logs <application_id>
. Затем вы можете использовать временные метки и другую информацию в журналах (при условии, что файлы конфигурации, такие как log4j.properties, верны).
Вариант 4 - время записи, прошедшее в драйвере
Если указанное выше не является вариантом (сервер истории не настроен и у вас нет доступа, задания не выполняются в одном кластере или по какой-либо другой причине), вы можете записать val start = System.currentTimeMillis
в начало вашей программы, а затем подсчитайте прошедшие минуты в конце, используя val elapsedMin = (System.currentTimeMillis - start) / 60000
. Затем вы можете записать прошедшие минуты и / или отправить сообщение, если elapsedMin >= 15
. Вам может потребоваться учетная запись, чтобы приложение не запускалось вовремя. Однако этот метод будет менее надежным, поскольку он не учитывает отказы более длительных заданий. Я бы не стал использовать этот метод сам по себе.