, потому что реализация интерфейса делает конструктором тип интерфейса. Это означает, что экземпляры должны иметь методы, определенные типом, а не классом экземпляров.
Другими словами,
public void mymethod
и
public static void mymethod
НЕ являются тем же самым объявлением метода. Они совершенно разные. Если mymethod
определен на интерфейсе, то второе определение просто не удовлетворяет реализации интерфейса.
Связь с использованием шлюза Py4J по умолчанию просто невозможна. Чтобы понять, почему мы должны взглянуть на следующую диаграмму из документа PySpark Internals [1]:
Поскольку шлюз Py4J работает на драйвере он не доступен интерпретаторам Python, которые взаимодействуют с рабочими JVM через сокеты (см., например, PythonRDD
/ rdd.py
).
Теоретически было бы возможно создать отдельный Py4J-шлюз для каждого рабочего, но на практике это вряд ли будет полезно. Игнорирование таких проблем, как надежность Py4J, просто не предназначено для выполнения задач, требующих большой объем данных.
Есть ли какие-либо обходные пути?
DataFrames
(см. Как использовать класс Scala внутри Pyspark ). Последнее решение выглядит гораздо более дружелюбным, поскольку все данные уже обрабатываются существующим API. Минусы: Низкий уровень, требуемое преобразование данных, то же, что и UDF, требует доступа к Py4J и внутреннему API, не поддерживается Некоторые основные примеры можно найти в Преобразование PySpark RDD с помощью Scala SQLContext
(см., Например, Apache Zeppelin или Livy ) для передачи данных между гостевыми языками с использованием зарегистрированных временных таблиц. Плюсы: хорошо подходит для интерактивного анализа Минусы: не столько для пакетных заданий (Цеппелин), либо может потребоваться дополнительная оркестровка (Livy)