Тестирование и диагностика
Операторы диагностики
DESCRIBE
Возвращает схему отношения.
Синтаксис
| DESCRIBE alias; |
Термины
| alias | Имя отношения. |
Использование
Используйте оператор DESCRIBE для просмотра схемы отношения. Вы можете просматривать внешние отношения, а также отношения, определённые вложенном операторе FOREACH.
Пример
В этом примере схема задаётся с помощью оператора AS. Если все данные соответствуют схеме, Pig будет использовать заданные типы.
A = LOAD 'student' AS (name:chararray, age:int, gpa:float);
B = FILTER A BY name matches 'J.+';
C = GROUP B BY name;
D = FOREACH C GENERATE COUNT(B.age);
DESCRIBE A;
A: {name: chararray,age: int,gpa: float}
DESCRIBE B;
B: {name: chararray,age: int,gpa: float}
DESCRIBE C;
C: {group: chararray,B: {(name: chararray,age: int,gpa: float)}}
DESCRIBE D;
D: {long}
В этом примере схема не задаётся. Все поля по умолчанию имеют тип bytearray или long (см. Типы данных).
a = LOAD 'student';
b = FILTER a BY $0 matches 'J.+';
c = GROUP b BY $0;
d = FOREACH c GENERATE COUNT(b.$1);
DESCRIBE a;
Schema for a unknown.
DESCRIBE b;
2008-12-05 01:17:15,316 [main] WARN org.apache.pig.PigServer - bytearray is implicitly cast to chararray under LORegexp Operator
Schema for b unknown.
DESCRIBE c;
2008-12-05 01:17:23,343 [main] WARN org.apache.pig.PigServer - bytearray is implicitly caste to chararray under LORegexp Operator
c: {group: bytearray,b: {null}}
DESCRIBE d;
2008-12-05 03:04:30,076 [main] WARN org.apache.pig.PigServer - bytearray is implicitly caste to chararray under LORegexp Operator
d: {long}
Этот пример показывает, как просмотреть схему вложенного отношения, используя оператор ::.
A = LOAD 'studentab10k' AS (name, age, gpa);
B = GROUP A BY name;
C = FOREACH B {
D = DISTINCT A.age;
GENERATE COUNT(D), group;}
DESCRIBE C::D;
D: {age: bytearray}
DUMP
Выводит результаты на экран.
Синтаксис
| DUMP alias; |
Термины
| alias | Имя отношения. |
Использование
Используйте оператор DUMP для выполнения (выполнения) предложений Pig Latin и отображения результатов на экране. DUMP предназначен для интерактивного режима; предложения выполняются немедленно, и результаты не сохраняются. Вы можете использовать DUMP в качестве средства отладки, чтобы убедиться, что получаемые результаты соответствуют ожиданиям.
Обратите внимание, что скрипты в режиме производства НЕ должны использовать DUMP, так как это отключит многозадачные оптимизации и, вероятно, замедлит выполнение (см. Хранение против Вывода).
Пример
В этом примере вывод выполняется после каждого оператора.
A = LOAD 'student' AS (name:chararray, age:int, gpa:float); DUMP A; (John,18,4.0F) (Mary,19,3.7F) (Bill,20,3.9F) (Joe,22,3.8F) (Jill,20,4.0F) B = FILTER A BY name matches 'J.+'; DUMP B; (John,18,4.0F) (Joe,22,3.8F) (Jill,20,4.0F)
EXPLAIN
Отображает планы выполнения.
Синтаксис
| EXPLAIN [–script pigscript] [–out path] [–brief] [–dot] [-xml] [–param param_name = param_value] [–param_file file_name] alias; |
Термины
| –script | Используется для указания скрипта Pig. |
| –out | Используется для указания пути к выходу (каталога). Сгенерирует файлы logical_plan[.txt|.dot], physical_plan[.text|.dot], exec_plan[.text|.dot] в указанном пути. По умолчанию (без указанного пути): стандартный вывод |
| –brief | Не раскрывает вложенные планы (предлагая меньшую диаграмму для общего обзора). |
| –dot, -xml | Режим текста (по умолчанию): несколько выводов (разделенные) будут разделены на секции. Режим DOT: выводит формат, который может быть передан в утилиту dot для графического отображения — сгенерирует ориентированный ациклический граф (DAG) планов в любом поддерживаемом формате (.gif, .jpg...). Режим XML: выводит XML, который представляет план (в настоящее время отображается только логический план). |
| –param param_name = param_value | См. Замена параметров. |
| –param_file file_name | См. Замена параметров. |
| alias | Имя отношения. |
Использование
Используйте оператор EXPLAIN для проверки логических, физических и планов выполнения MapReduce, которые используются для вычисления указанного отношения.
Если скрипт не задан:
-
Логический план отображает поток операторов, которые должны быть выполнены для построения отношения. Также применяются проверка типов и оптимизации, не зависящие от бэкенда (например, применение фильтров на ранней стадии).
-
Физический план отображает, как логические операторы переводятся в физические операторы, специфичные для бэкенда. Также применяются некоторые оптимизации бэкенда.
-
План MapReduce отображает, как физические операторы группируются в задачи MapReduce.
Если задан скрипт без имени отношения, он выведет весь граф выполнения (логический, физический или MapReduce).
Если задан скрипт с именем отношения, он выведет план для данного имени отношения.
Пример
В этом примере оператор EXPLAIN генерирует все три плана. (Обратите внимание, что в этом примере показана только часть вывода.)
A = LOAD 'student' AS (name:chararray, age:int, gpa:float);
B = GROUP A BY name;
C = FOREACH B GENERATE COUNT(A.age);
EXPLAIN C;
-----------------------------------------------
Logical Plan:
-----------------------------------------------
Store xxx-Fri Dec 05 19:42:29 UTC 2008-23 Schema: {long} Type: Unknown
|
|---ForEach xxx-Fri Dec 05 19:42:29 UTC 2008-15 Schema: {long} Type: bag
etc ...
-----------------------------------------------
Physical Plan:
-----------------------------------------------
Store(fakefile:org.apache.pig.builtin.PigStorage) - xxx-Fri Dec 05 19:42:29 UTC 2008-40
|
|---New For Each(false)[bag] - xxx-Fri Dec 05 19:42:29 UTC 2008-39
| |
| POUserFunc(org.apache.pig.builtin.COUNT)[long] - xxx-Fri Dec 05
etc ...
--------------------------------------------------
| Map Reduce Plan
-------------------------------------------------
MapReduce node xxx-Fri Dec 05 19:42:29 UTC 2008-41
Map Plan
Local Rearrange[tuple]{chararray}(false) - xxx-Fri Dec 05 19:42:29 UTC 2008-34
| |
| Project[chararray][0] - xxx-Fri Dec 05 19:42:29 UTC 2008-35
etc ...
If you are running in Tez mode, Map Reduce Plan will be replaced with Tez Plan:
#--------------------------------------------------
# There are 1 DAGs in the session
#--------------------------------------------------
#--------------------------------------------------
# TEZ DAG plan: PigLatin:185.pig-0_scope-0
#--------------------------------------------------
Tez vertex scope-21 -> Tez vertex scope-22,
Tez vertex scope-22
Tez vertex scope-21
# Plan on vertex
B: Local Rearrange[tuple]{chararray}(false) - scope-35 -> scope-22
etc ...
ILLUSTRATE
Отображает пошаговое выполнение последовательности операторов.
Синтаксис
| ILLUSTRATE {alias | -script scriptfile}; |
Термины
| alias | Имя отношения. |
| -script scriptfile | Ключевое слово script, за которым следует имя скрипта Pig (например, myscript.pig). Файл скрипта не должен содержать оператор ILLUSTRATE. |
Использование
Используйте оператор ILLUSTRATE для проверки того, как данные преобразуются с помощью последовательности операторов Pig Latin. ILLUSTRATE позволяет тестировать программы на небольших наборах данных и ускорить время обработки.
ILLUSTRATE основан на генераторе примеров (см. Generating Example Data for Dataflow Programs). Алгоритм работает путём извлечения небольшой выборки входных данных и последующим распространением этих данных по конвейеру. Однако некоторые операторы, такие как JOIN и FILTER, могут исключать кортежи из данных, что может привести к отсутствию данных в конвейере. Чтобы решить эту проблему, алгоритм автоматически генерирует примерные данные практически в реальном времени. Таким образом, вы можете увидеть распространение данных по конвейеру, которые не были найдены в исходных входных данных, но эти данные ничего не меняют и гарантируют, что вы сможете изучить семантику ваших операторов Pig Latin.
Как показано в примерах ниже, вы можете использовать ILLUSTRATE для проверки отношения или целого скрипта Pig.
Пример - Отношение
Этот пример демонстрирует, как использовать ILLUSTRATE с отношением. Обратите внимание, что оператор LOAD должен содержать схему (оператор AS).
grunt> visits = LOAD 'visits.txt' AS (user:chararray, url:chararray, timestamp:chararray);
grunt> DUMP visits;
(Amy,yahoo.com,19990421)
(Fred,harvard.edu,19991104)
(Amy,cnn.com,20070218)
(Frank,nba.com,20070305)
(Fred,berkeley.edu,20071204)
(Fred,stanford.edu,20071206)
grunt> recent_visits = FILTER visits BY timestamp >= '20071201';
grunt> user_visits = GROUP recent_visits BY user;
grunt> num_user_visits = FOREACH user_visits GENERATE group, COUNT(recent_visits);
grunt> DUMP num_user_visits;
(Fred,2)
grunt> ILLUSTRATE num_user_visits;
------------------------------------------------------------------------
| visits | user: chararray | url: chararray | timestamp: chararray |
------------------------------------------------------------------------
| | Fred | berkeley.edu | 20071204 |
| | Fred | stanford.edu | 20071206 |
| | Frank | nba.com | 20070305 |
------------------------------------------------------------------------
-------------------------------------------------------------------------------
| recent_visits | user: chararray | url: chararray | timestamp: chararray |
-------------------------------------------------------------------------------
| | Fred | berkeley.edu | 20071204 |
| | Fred | stanford.edu | 20071206 |
-------------------------------------------------------------------------------
------------------------------------------------------------------------------------------------------------------
| user_visits | group: chararray | recent_visits: bag({user: chararray,url: chararray,timestamp: chararray}) |
------------------------------------------------------------------------------------------------------------------
| | Fred | {(Fred, berkeley.edu, 20071204), (Fred, stanford.edu, 20071206)} |
------------------------------------------------------------------------------------------------------------------
--------------------------------------------------
| num_user_visits | group: chararray | long |
--------------------------------------------------
| | Fred | 2 |
--------------------------------------------------
Пример - Скрипт
Этот пример демонстрирует, как использовать ILLUSTRATE со скриптом Pig. Обратите внимание, что сам скрипт не должен содержать оператор ILLUSTRATE.
grunt> cat visits.txt Amy yahoo.com 19990421 Fred harvard.edu 19991104 Amy cnn.com 20070218 Frank nba.com 20070305 Fred berkeley.edu 20071204 Fred stanford.edu 20071206 grunt> cat visits.pig visits = LOAD 'visits.txt' AS (user, url, timestamp); recent_visits = FILTER visits BY timestamp >= '20071201'; historical_visits = FILTER visits BY timestamp <= '20000101'; DUMP recent_visits; DUMP historical_visits; STORE recent_visits INTO 'recent'; STORE historical_visits INTO 'historical'; grunt> exec visits.pig (Fred,berkeley.edu,20071204) (Fred,stanford.edu,20071206) (Amy,yahoo.com,19990421) (Fred,harvard.edu,19991104) grunt> illustrate -script visits.pig ------------------------------------------------------------------------ | visits | user: bytearray | url: bytearray | timestamp: bytearray | ------------------------------------------------------------------------ | | Amy | yahoo.com | 19990421 | | | Fred | stanford.edu | 20071206 | ------------------------------------------------------------------------ ------------------------------------------------------------------------------- | recent_visits | user: bytearray | url: bytearray | timestamp: bytearray | ------------------------------------------------------------------------------- | | Fred | stanford.edu | 20071206 | ------------------------------------------------------------------------------- --------------------------------------------------------------------------------------- | Store : recent_visits | user: bytearray | url: bytearray | timestamp: bytearray | --------------------------------------------------------------------------------------- | | Fred | stanford.edu | 20071206 | --------------------------------------------------------------------------------------- ----------------------------------------------------------------------------------- | historical_visits | user: bytearray | url: bytearray | timestamp: bytearray | ----------------------------------------------------------------------------------- | | Amy | yahoo.com | 19990421 | ----------------------------------------------------------------------------------- ------------------------------------------------------------------------------------------- | Store : historical_visits | user: bytearray | url: bytearray | timestamp: bytearray | ------------------------------------------------------------------------------------------- | | Amy | yahoo.com | 19990421 | -------------------------------------------------------------------------------------------
Сценарии Pig и идентификаторы задач MapReduce (только режим MapReduce)
Сложные скрипты Pig часто генерируют множество задач MapReduce. Чтобы помочь в отладке скрипта, Pig выводит сводку выполнения, показывающую, какие отношения (псевдонимы) сопоставлены с каждой задачей MapReduce.
JobId Maps Reduces MaxMapTime MinMapTIme AvgMapTime MaxReduceTime
MinReduceTime AvgReduceTime Alias Feature Outputs
job_201004271216_12712 1 1 3 3 3 12 12 12 B,C GROUP_BY,COMBINER
job_201004271216_12713 1 1 3 3 3 12 12 12 D SAMPLER
job_201004271216_12714 1 1 3 3 3 12 12 12 D ORDER_BY,COMBINER
hdfs://mymachine.com:9020/tmp/temp743703298/tmp-2019944040,
Статистика Pig
Статистики Pig — это фреймворк для сбора и хранения статистики на уровне скриптов для Pig Latin. Характеристики скриптов Pig Latin и результирующих задач MapReduce собираются во время выполнения скрипта. Эта статистика затем становится доступной для пользователей Pig и инструментов, использующих Pig (таких как Oozie), для получения после завершения работы.
Новые статистические данные Pig и существующие статистические данные Hadoop также могут быть доступны через файл истории задач Hadoop (и файл xml задач).
Java API
Несколько новых общедоступных классов упрощают интеграцию внешних инструментов, таких как Oozie, со статистикой Pig.
Статистика Pig доступна здесь: http://pig.apache.org/docs/r0.17.0/api/
Классы статистики находятся в пакете: org.apache.pig.tools.pigstats
- PigStats
- SimplePigStats
- EmbeddedPigStats
- JobStats
- TezPigScriptStats
- TezDAGStats
- TezVertexStats
- OutputStats
- InputStats
Класс PigRunner имитирует поведение класса Main, но возвращает пользователю объект статистики. По желанию вы можете вызвать API с реализацией обработчика прогресса, который будет вызываться временем выполнения Pig во время выполнения.
package org.apache.pig;
public abstract class PigRunner {
public static PigStats run(String[] args, PigProgressNotificationListener listener)
}
public interface PigProgressNotificationListener extends java.util.EventListener {
// just before the launch of MR jobs for the script
public void LaunchStartedNotification(int numJobsToLaunch);
// number of jobs submitted in a batch
public void jobsSubmittedNotification(int numJobsSubmitted);
// a job is started
public void jobStartedNotification(String assignedJobId);
// a job is completed successfully
public void jobFinishedNotification(JobStats jobStats);
// a job is failed
public void jobFailedNotification(JobStats jobStats);
// a user output is completed successfully
public void outputCompletedNotification(OutputStats outputStats);
// updates the progress as percentage
public void progressUpdatedNotification(int progress);
// the script execution is done
public void launchCompletedNotification(int numJobsSucceeded);
}
В зависимости от типа скрипта Pig, PigRunner.run() возвращает конкретный подкласс PigStats: SimplePigStats (режим MapReduce/локальный), TezPigScriptStats (режим Tez/локальный Tez) или EmbeddedPigStats (встроенный скрипт). SimplePigStats содержит карту JobStats, которая сохраняет статистику для каждой задачи MapReduce скрипта Pig. TezPigScriptStats содержит карту TezDAGStats, которая сохраняет статистику для каждого Tez DAG скрипта Pig, а TezDAGStats содержит карту TezVertexStats, которая сохраняет статистику для каждого узла внутри Tez DAG. В зависимости от типа выполнения, EmbeddedPigStats содержит карту SimplePigStats или TezPigScriptStats, которая сохраняет запущенную задачу Pig во встроенном скрипте.
Если вы выполняете Pig в режиме Tez (или в режиме Tez/MapReduce), передайте PigTezProgressNotificationListener, который расширяет PigProgressNotificationListener в PigRunner.run(), чтобы убедиться, что получаете уведомления как в режиме Tez, так и в режиме MapReduce.
Job XML
В конфигурации задачи включены следующие записи:
| Статистика Pig | Описание |
| pig.script.id | UUID скрипта. Все задачи, запущенные скриптом, имеют один и тот же идентификатор скрипта. |
| pig.script | Текст скрипта в кодировке base64. |
| pig.command.line | Командная строка, используемая для вызова скрипта. |
| pig.hadoop.version | Установленная версия Hadoop. |
| pig.version | Используемая версия Pig. |
| pig.input.dirs | Список входных каталогов для задачи, разделённых запятыми. |
| pig.map.output.dirs | Список выходных каталогов на фазе map задачи, разделённых запятыми. |
| pig.reduce.output.dirs | Список выходных каталогов на фазе reduce задачи, разделённых запятыми. |
| pig.parent.jobid | Список идентификаторов родительских задач, разделённых запятыми. |
| pig.script.features | Список функций Pig, используемых в скрипте. |
| pig.job.feature | Список функций Pig, используемых в задаче. |
| pig.alias | Псевдоним, связанный с задачей. |
Обработчик уведомлений о ходе выполнения Pig
Pig предоставляет возможность зарегистрировать обработчик для получения уведомлений о событиях во время выполнения скрипта. События включают создание плана MapReduce, запуск скрипта, прогресс скрипта, завершение скрипта, отправку задачи, запуск задачи, завершение задачи и сбой задачи.
Для регистрации обработчика задайте параметр pig.notification.listener на полное имя класса реализации org.apache.pig.tools.pigstats.PigProgressNotificationListener. Класс должен существовать в пути поиска классов процесса, отправляющего задачу Pig. Если параметр pig.notification.listener.arg установлен, значение будет передано в конструктор класса-реализации, который принимает один строковый аргумент.
PigUnit
PigUnit — это простой фреймворк xUnit, который позволяет легко тестировать ваши скрипты Pig. С помощью PigUnit вы можете выполнять unit-тестирование, регрессионное тестирование и быструю разработку прототипов. Если вы запускаете Pig в локальном режиме, настройка кластера не требуется.
Сборка PigUnit
Чтобы скомпилировать PigUnit, выполните команду, показанную ниже, из Pig trunk. Компиляция создаст файл pigunit.jar.
$pig_trunk ant pigunit-jar
Запуск PigUnit
Вы можете запустить PigUnit, используя локальный или режим MapReduce Pig.
Локальный режим
PigUnit по умолчанию запускается в локальном режиме Pig. Локальный режим быстрый и позволяет использовать вашу локальную файловую систему в качестве кластера HDFS. Локальный режим не требует реального кластера, но каждый раз создается новый локальный.
Другие режимы
PigUnit также работает в режимах MapReduce/Tez/Tez_local Pig. Режимы MapReduce/Tez требуют использования кластера Hadoop и установки HDFS. Он включается, когда система Java устанавливает свойство pigunit.exectype в определённые значения (mr/tez/tez_local): например, -Dpigunit.exectype=mr или System.getProperties().setProperty("pigunit.exectype", "mr"), что означает, что PigUnit будет работать в режиме mr. Кластер, который вы выбираете для запуска тестов mr/tez, должен быть указан в CLASSPATH (аналогично переменной HADOOP_CONF_DIR).
Пример PigUnit
Многие примеры PigUnit доступны в тестах PigUnit.
Приведённый здесь пример вычисляет N самых популярных запросов. Скрипт Pig top_queries.pig похож на Популярность фраз запроса в учебном пособии по Pig. Он ожидает входной файл запросов и параметр n (n равно 2 в нашем случае для выполнения топ-2).
Настройка теста для этого скрипта проста, поскольку аргумент и входные данные задаются двумя текстовыми массивами. То же самое относится к ожидаемому выходу скрипта, который будет сравниваться с фактическим результатом выполнения скрипта Pig.
Java-тест
@Test
public void testTop2Queries() {
String[] args = {
"n=2",
};
PigTest test = new PigTest("top_queries.pig", args);
String[] input = {
"yahoo",
"yahoo",
"yahoo",
"twitter",
"facebook",
"facebook",
"linkedin",
};
String[] output = {
"(yahoo,3)",
"(facebook,2)",
};
test.assertOutput("data", input, "queries_limit", output);
}
top_queries.pig
data =
LOAD 'input'
AS (query:CHARARRAY);
queries_group =
GROUP data
BY query;
queries_count =
FOREACH queries_group
GENERATE
group AS query,
COUNT(data) AS total;
queries_ordered =
ORDER queries_count
BY total DESC, query;
queries_limit =
LIMIT queries_ordered $n;
STORE queries_limit INTO 'output';
Запуск
Тест можно выполнить с помощью JUnit (или любого другого фреймворка Java для тестирования). Требуется:
- pig.jar
- pigunit.jar
Тест занимает около 25 секунд и должен пройти успешно. В случае ошибки (например, изменить параметр n на n=3), отображается различие в выводе:
junit.framework.ComparisonFailure: null expected:<...ahoo,3)
(facebook,2)[]> but was:<...ahoo,3)
(facebook,2)[
(linkedin,1)]>
at junit.framework.Assert.assertEquals(Assert.java:81)
at junit.framework.Assert.assertEquals(Assert.java:87)
at org.apache.pig.pigunit.PigTest.assertEquals(PigTest.java:272)
Мокинг
Иногда вам нужно смоделировать данные в определённых псевдонимах. Используя мокинг PigTest, вы можете переопределить псевдоним повсюду, где он назначается. Если вы не знаете схему (или хотите сохранить свой тест динамичным), вы можете использовать PigTest.getAliasToSchemaMap() для определения схемы. Если вы решили пойти по этому пути, вы должны кэшировать карту для конкретного скрипта, чтобы обеспечить эффективное выполнение.
@Test
public void testTop2Queries() {
String[] args = {
"n=2",
};
PigTest test = new PigTest("top_queries.pig", args);
String[] mockData = {
"yahoo",
"yahoo",
"yahoo",
"twitter",
"facebook",
"facebook",
"linkedin",
};
//You should cache the map if you can
String schema = test.getAliasToSchemaMap().get("data");
test.mockAlias("data", mockData, schema);
String[] output = {
"(yahoo,3)",
"(facebook,2)",
};
test.assertOutputAnyOrder("queries_limit", output);
}
Советы по устранению неполадок
Ниже обсуждаются распространённые проблемы, с которыми вы можете столкнуться.
Путь поиска классов в режиме MapReduce
При использовании PigUnit в режиме MapReduce убедитесь, что $HADOOP_CONF_DIR кластера включен в ваш CLASSPATH.
MiniCluster генерирует его в build/classes.
org.apache.pig.backend.executionengine.ExecException: ERROR 4010: Cannot find hadoop configurations in classpath (neither hadoop-site.xml nor core-site.xml was found in the classpath). If you plan to use local mode, please put -x local option in command line
Файлы JAR UDF не найдены
Эта ошибка означает, что в вашей тестовой среде отсутствуют некоторые файлы JAR.
WARN util.JarManager: Couldn't find the jar for org.apache.pig.piggybank.evaluation.string.LOWER, skip it
Хранение данных
В настоящее время Pig отбрасывает все команды STORE и DUMP. Вы можете указать PigUnit сохранить эти команды и выполнить скрипт:
test = new PigTest(PIG_SCRIPT, args);
test.unoverride("STORE");
test.runScript();
Кэширование архива
Для работы кэширования архива ваша тестовая среда должна иметь параметры кэширования архива, указанные свойствами Java или в дополнительной XML-конфигурации в её CLASSPATH.
Если вы используете локальный кластер, вам нужно задать необходимые переменные среды перед его запуском:
export LD_LIBRARY_PATH=/home/path/to/lib
Планируемые улучшения
Улучшения и другие компоненты, основанные на PigUnit, которые можно создать в будущем.
Например, мы могли бы построить PigTestCase и PigTestSuite поверх PigTest, чтобы:
- Добавить понятие рабочих пространств для каждого теста.
- Удалить шаблонный код, появляющийся, когда существует более одного тестового метода.
- Добавить автономную утилиту, которая считывает конфигурации тестов и генерирует отчёт о тесте.
© 2007–2017 Apache Software Foundation
Licensed under the Apache Software License version 2.0.
https://pig.apache.org/docs/r0.17.0/test.html