Как предотвратить утечку памяти при тестировании с помощью HiveContext в PySpark

Я использую pyspark для некоторой обработки данных и использую HiveContext для оконной функции.

Чтобы протестировать код, я использую TestHiveContext, в основном копируя реализацию из исходного кода pyspark:

https://spark.apache.org/docs/preview/api/python/_modules/pyspark/sql/context.html

@classmethod
def _createForTesting(cls, sparkContext):
    """(Internal use only) Create a new HiveContext for testing.

    All test code that touches HiveContext *must* go through this method. Otherwise,
    you may end up launching multiple derby instances and encounter with incredibly
    confusing error messages.
    """
    jsc = sparkContext._jsc.sc()
    jtestHive = sparkContext._jvm.org.apache.spark.sql.hive.test.TestHiveContext(jsc)
    return cls(sparkContext, jtestHive)

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

Какое-то время это работало нормально. Тем не менее, я начал замечать некоторые прерывистые проблемы с нехваткой памяти, когда добавлял больше тестов. Теперь я не могу запустить набор тестов без сбоя.

"java.lang.OutOfMemoryError: Java heap space"

Я явно останавливаю искровой контекст после запуска каждого теста, но это, похоже, не убивает HiveContext. Таким образом, я считаю, что он продолжает создавать новые HiveContexts каждый раз, когда запускается новый тест, и не удаляет старый, что приводит к утечке памяти.

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


person matt hoover    schedule 18.03.2018    source источник
comment
Я столкнулся с тем же самым с моими собственными тестами на Java. Я не уверен, что у него чистое завершение работы, поэтому лучшее, что я придумал, это сделать его глобальным тестовым синглтоном.   -  person Hitobat    schedule 19.03.2018
comment
Я всегда слышу, что Singleton = плохой дизайн, но, возможно, в данном случае это лучшее решение. Он будет использоваться только в тестовом бегуне. У вас есть пример кода? приму как ответ.   -  person matt hoover    schedule 19.03.2018


Ответы (1)


Если вы готовы использовать синглтон для хранения контекста Spark/Hive во всех своих тестах, вы можете сделать что-то вроде следующего.

test_contexts.py:

_test_spark = None
_test_hive = None

def get_test_spark():
    if _test_spark is None:
        # Create spark context for tests.
        # Not really sure what's involved here for Python.
        _test_spark = ...
    return _test_spark

def get_test_hive():
    if _test_hive is None:
        sc = get_test_spark()
        jsc = test_spark._jsc.sc()
        _test_hive = sc._jvm.org.apache.spark.sql.hive.test.TestHiveContext(jsc)
    return _test_hive

А затем вы просто импортируете эти функции в свои тесты.

мой_test.py:

from test_contexts import get_test_spark, get_test_hive

def test_some_spark_thing():
    sc = get_test_spark()
    sqlContext = get_test_hive()
    # etc
person Hitobat    schedule 19.03.2018