Работа u-sql очень медленная, когда я добавляю вызов .NET

Код работает очень быстро с 2000 маленьких файлов (~ 10-50 Кб) ~ 1 мин. Параллелизм = 5.

@arenaData =
    EXTRACT col1, col2, col3
    FROM @in
    USING Extractors.Tsv(quoting : true, skipFirstNRows : 1, nullEscape : "\\N", encoding:Encoding.UTF8);

@res =
    SELECT col1, col2, col3  
    FROM @arenaData;
    OUTPUT @res
    TO @out
    USING Outputters.Csv();

Но если я изменю код таким образом, это займет ~ 1 час.

@arenaData =
    EXTRACT col1, col2, col3
    FROM @in
    USING Extractors.Tsv(quoting : true, skipFirstNRows : 1, nullEscape : "\\N", encoding:Encoding.UTF8);

@res =
    SELECT
         col1.ToUniversalTime().ToString("yyyy-MM-dd HH:mm:ss", CultureInfo.InvariantCulture) AS col1_converted,
, col2, col3

    FROM @arenaData;
    OUTPUT @res
    TO @out
    USING Outputters.Csv();

Почему вызов .NET такой медленный? Мне нужно преобразовать формат даты в исходных файлах CSV в «гггг-ММ-дд ЧЧ: мм: сс»? Как я могу сделать это эффективно?


person churupaha    schedule 21.02.2017    source источник
comment
Это звучит неправильно. Существуют дополнительные накладные расходы, связанные с загрузкой среды CLR и вызовом из машинного кода в выполнение C #, но это не должно быть в 60 раз хуже. Не могли бы вы прислать мне ссылки на вакансии (usql в Microsoft dot com), чтобы я мог попросить нашу группу инженеров разобраться?   -  person Michael Rys    schedule 21.02.2017
comment
Я отправил запрос в службу поддержки ADLA до того, как опубликовал вопрос в stackoverflow. Я провел эти тесты для службы поддержки (URL-адреса JOB ниже): без CLR ~ 2 мин (MAXDOP = 5): arkadium.azuredatalakeanalytics.net/jobs/ то же самое с одним вызовом CLR ~ 38 мин (MAXDOP = 5): arkadium.azuredatalakeanalytics.net / jobs / тайминги изменены, потому что параметры были изменены, но проблема все еще существует. ооочень большая разница   -  person churupaha    schedule 22.02.2017
comment
еще несколько тестов: та же работа с параллелизмом CLR + увеличилась с 5 до 20. Затраченное время ~ 10 мин arkadium.azuredatalakeanalytics.net/jobs/ то же задание с параллелизмом CLR + увеличено с 5 до 3. затраченное время ~ 59 мин. + отменено мной arkadium.azuredatalakeanalytics.net/jobs/   -  person churupaha    schedule 22.02.2017
comment
Я узнал первопричины от команды инженеров. В настоящее время я путешествую, но отвечу позже сегодня / завтра.   -  person Michael Rys    schedule 22.02.2017
comment
Спасибо, буду ждать вашего комментария.   -  person churupaha    schedule 22.02.2017
comment
@MichaelRys Похоже, я понимаю, что происходит. У нас есть 2880 небольших файлов. На все они у нас по 1 вершине. Всего у нас 2880 вершин. Я немного прочитал о модели выполнения ADLA. И похоже, что когда Analytics Unit (AU) мигрирует из одной вершины в другую, он повторно инициализирует COM-сервер CLR. Таким образом, в нашем случае CLR повторяется 2880 раз. И решение для нас объединить файлы перед началом обработки. Я прав? Я проверил эти предположения и, похоже, они верны ... Хочу услышать ваше объяснение.   -  person churupaha    schedule 22.02.2017
comment
@MichaelRys после исправления выполняется два задания. без CLR 55 секунд: arkadium.azuredatalakeanalytics.net/jobs/ с вызовом CLR ~ 65 секунд: arkadium.azuredatalakeanalytics.net/jobs/ Мне это нравится!   -  person churupaha    schedule 22.02.2017
comment
Смотрите мои ответы, но вы в основном правы.   -  person Michael Rys    schedule 24.02.2017


Ответы (1)


Приятно слышать, что теперь у вас лучшая производительность!

Ваше задание выполняется для более чем 2800 очень маленьких файлов с использованием выражения, которое выполняется в управляемом коде и не транслируется на C ++, как некоторые из наиболее распространенных выражений C # в U-SQL.

Это приводит к следующей проблеме:

  1. Вы начинаете свою работу с определенным количеством AU. Затем каждый AU запускает контейнер YARN для выполнения части вашей работы. Это означает, что контейнер должен быть инициализирован чисто, что занимает некоторое время (вы можете увидеть это в представлении выполнения вершин как время создания). Теперь это займет немного времени, это не так уж много накладных расходов, если ваша вершина выполняет большой объем обработки. К сожалению, в вашем случае обработка небольшого файла выполняется очень быстро, поэтому возникают большие накладные расходы.

  2. Если вершина выполняет только сгенерированный системой код, который мы кодируем в код C ++, то мы можем повторно использовать контейнеры без повторной инициализации. К сожалению, мы не можем повторно использовать общий пользовательский код, который выполняется с управляемой средой выполнения, из-за того, что потенциальные артефакты остаются позади. Поэтому в этом случае нам нужно повторно инициализировать контейнеры, что потребует времени (более 2800 раз).

Теперь, основываясь на ваших отзывах, мы улучшаем нашу логику повторной инициализации (мы все еще можем выполнить повторную инициализацию, если вы не сделаете ничего особенного со встроенными выражениями C #). Кроме того, это станет лучше, когда мы сможем обрабатывать несколько небольших файлов внутри одной вершины вместо одного файла на вершину.

Обходной путь для вас - увеличить размеры ваших файлов и, возможно, избежать того, чтобы пользовательский код (не всегда возможно, конечно) находился в слишком большом количестве вершин.

person Michael Rys    schedule 24.02.2017
comment
Большое спасибо за подробное объяснение. Также я пока знаю, что под капотом контейнера AU ~ Apache YARN. - person churupaha; 24.02.2017
comment
Всегда приятно видеть, как команда реагирует на потребности клиентов и отзывы! - person Pittsburgh DBA; 18.03.2018