Статьи

Создание системы визуального мониторинга на основе .NET для Hadoop

Резюме

Универсальный Hadoop не предоставляет никаких готовых систем визуального мониторинга, которые бы сообщали о состоянии всех узлов в кластере Hadoop. В этой лаборатории JNBridge демонстрируется, как создать приложение мониторинга на основе .NET, которое использует существующий продукт Microsoft Windows для предоставления снимка всего кластера Hadoop в режиме реального времени.

Загрузите исходный код для этой лаборатории на  www.jnbridge.com/labs . 

визуализатор

Вступление

Один из идеалов распределенных вычислений — иметь кластер машин, который самоконтроля, самовосстановления и самообеспечения. Если что-то идет не так, система сообщает об этом, пытается устранить проблему и, если ничего не работает, сообщает о проблеме администратору — и все это без сбоев. Распределенные системы, такие как Hadoop, настолько популярны, отчасти потому, что они приближаются к этим идеалам до такой степени, что раньше их было мало. В частности, Hadoop является расширяемым, избыточным (хотя и не очень мелкозернистым), простым в использовании и надежным. Тем не менее, он не идеален, и любой администратор Hadoop знает о важности дополнительного мониторинга для поддержания надежного кластера.

Часть этого мониторинга поступает от встроенных веб-серверов Hadoop. Они имеют прямой доступ к внутренним компонентам кластера и могут сообщить вам, какие задания выполняются, какие файлы находятся в распределенной системе, а также различные другие важные сведения, хотя и в несколько тупом формате электронных таблиц. Ряд пакетов Hadoop также поставляется с универсальными приложениями для мониторинга распределенной системы, такими как Ganglia, но они не интегрированы с самим Hadoop. Наконец, есть такие продукты, как Apache Ambari от Hortonworks, которые выполняют значительный визуальный мониторинг, но привязаны к версиям Hadoop определенных компаний. В этой лабораторной работе мы рассмотрим основы создания пользовательского приложения, интегрированного в структуру вашего собственного кластера Hadoop. В частности, будучи JNBridge, мы заинтересованы в строительстве.NET-приложение для мониторинга, которое взаимодействует через TCP-соединение с Hadoop на основе Java с помощью JNBridgePro. Чтобы ускорить процесс создания графического интерфейса для нашего приложения мониторинга, мы будем использовать Microsoft Visio для простого создания визуальной модели кластера Hadoop. Таким образом, мы можем создать элементарное приложение для мониторинга, которое также работает как визуализатор кластера.

Приложение, которое мы стремимся создать для этой лаборатории, довольно простое. Он будет представлять собой графическое представление логической топологии кластера, где каждый рабочий узел отображает свое состояние (ОК или не ОК), объем использованного локального пространства HDFS и часть используемых преобразователей и преобразователей. Мы не ищем здесь точных цифр — эта информация доступна через веб-серверы — скорее, наша цель — создать схему, которую можно использовать для быстрого определения состояния различных компонентов кластера.

Прежде чем мы начнем, имейте в виду две вещи: 1. Мы не предлагаем наше решение или наш код в качестве реальной опции для мониторинга вашего кластера Hadoop. Мы просто предлагаем определенные инструменты, которые можно использовать при создании собственного приложения для мониторинга. 2. Наше решение было разработано для дистрибутива Hadonworks HDP 1.3 Hadoop 1.2.

Даже в нашем ограниченном тестировании мы заметили явное отсутствие переносимости между различными дистрибутивами Hadoop и версиями, особенно в том, что касается расположения каталогов и спецификаций shell-скрипта. Надеемся, что наши объяснения достаточно ясны, чтобы вы могли приспособиться к потребностям своего кластера, но это не всегда так. Мы также собираемся предположить, что вы знакомы с Hadoop и Visio, поскольку подробное объяснение любой системы и ее внутренней логики сделало бы эту работу намного более длительной, чем необходимо.

Что вам нужно

  1. Apache Hadoop (мы использовали дистрибутив Hortonworks, хотя любой будет работать с некоторыми усилиями)
  2. Visual Studio 2012
  3. Microsoft Visio 2013
  4. Visio 2013 SDK
  5. JNBridgePro 7.0

Копаться в Hadoop

Для начала, чтобы получить как можно более полную информацию о кластере, нам нужно завладеть объектами NameNode и JobTracker — которые управляют частями Hadoop в HDFS и MapReduce соответственно — которые в настоящее время работают в кластере. Это предоставит богатые API-интерфейсы как JobTracker, так и NameNode, а также отдельных узлов кластера. Именно эти API-интерфейсы используют код JSP для создания страниц встроенного веб-сервера и предоставляют более чем достаточно информации для наших целей.

Однако получить доступ к этим объектам напрямую довольно сложно. В общем, Hadoop построен таким образом, чтобы конечный пользователь мог взаимодействовать с кластером только через определенные сокеты, которые только измеряют определенную информацию о кластере и допускают только определенную информацию. Таким образом, получая прямой доступ и используя API-интерфейсы запущенного NameNode и JobTracker — это не то, что вы должны делать. Это разумная мера предосторожности, но она усложняет получение информации, необходимой для приложения мониторинга. Конечно, естьorg.apache.hadoop.mapred.ClusterStatus класс, который передает информацию о состоянии по сети, но информации, которую он предоставляет, недостаточно для создания действительно надежного приложения для мониторинга. Наше решение этой дилеммы включает в себя легкий взлом самого Hadoop. Не беспокойтесь, вам не нужно будет перекомпилировать исходный код, но некоторые знания этого исходного кода и сценариев оболочки, используемых для его запуска, были бы полезны.

Наша цель — втиснуть себя между скриптами, которые запускают Hadoop, и процессом фактического создания экземпляров NameNode и JobTracker. При этом мы можем написать программу, которая пробивается сквозь огороженный сад и позволяет напрямую обслуживать эти объекты на стороне .NET. Технически подобный процесс может быть использован для кодирования аналогичного приложения для мониторинга на чистой Java, но здесь это не то, что нас интересует. Если что-то покажется немного неясным, надеюсь, вы получите лучшее представление о нашем решении, когда мы его объясним.

Когда  $HADOOP_INSTALL/hadoop/bin/hadoop скрипт вызывается для запуска NameNode и JobTracker, он просто запускается  NameNode.main() и  JobTracker.main(). Эти основные функции, в свою очередь, вызывают всего несколько строк кода для запуска двух главных узлов. Обратите внимание, что этот процесс обычно еще больше запутывается сценарием запуска, таким как  start-all.sh или, в нашем случае с Hortonworks  hadoop-daemon.sh, но все они в конечном итоге вызывают один и тот же  $HADOOP_INSTALL/hadoop/bin/hadoop сценарий. В нашем решении вместо вызова сценария NameNode.main() and  JobTracker.main()мы вместо этого вызываем основные функции наших собственных классов-оболочек, которые содержат код из исходных основных функций, в дополнение к настройке удаленных серверов на стороне Java JNBridgePro. Затем эти классы-обертки могут обслуживать экземпляры JobTracker и NameNode для нашего приложения для мониторинга на базе Windows.

Класс оболочки JobTracker выглядит следующим образом:

import java.io.IOException;
import java.util.Properties;
import org.apache.hadoop.mapred.JobConf;
import org.apache.hadoop.mapred.JobTracker;
import com.jnbridge.jnbcore.server.ServerException;
 
public class JnbpJobTrackerWrapper {
 
    private static JobTracker theJobTracker = null;
 
    public static void main(String[] args) {
 
        Properties props = new Properties();
        props.put("javaSide.serverType", "tcp");
        props.put("javaSide.port", "8085");
        try {
            com.jnbridge.jnbcore.JNBMain.start(props);
        } catch (ServerException e) {
 
            e.printStackTrace();
        }
 
        try {
            theJobTracker = JobTracker.startTracker(new JobConf());
            theJobTracker.offerService();
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
 
    public static JobTracker getJobTracker()
    {
        return theJobTracker;
    }
}

И класс оболочки NameNode выглядит так:

import java.util.Properties;
import org.apache.hadoop.hdfs.server.namenode.NameNode;
import com.jnbridge.jnbcore.server.ServerException;
 
public class JnbpNameNodeWrapper {
 
    private static NameNode theNameNode = null;
 
    public static void main(String[] args) {
 
        Properties props = new Properties();
        props.put("javaSide.serverType", "tcp");
        props.put("javaSide.port", "8087");
        try {
            com.jnbridge.jnbcore.JNBMain.start(props);
        } catch (ServerException e) {
 
            e.printStackTrace();
        }
 
        try {
            theNameNode = NameNode.createNameNode(args, null);
            if (theNameNode != null)
            {
                theNameNode.join();
            }
        } catch (Throwable e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }
 
    public static NameNode getNameNode()
    {
        return theNameNode;
    }
}

Чтобы  $HADOOP_INSTALL/hadoop/bin/hadoop скрипт вызывал наши классы, мы изменяем следующие строки кода:

elif [ "$COMMAND" = "jobtracker" ] ; then
  #CLASS=org.apache.hadoop.mapred.JobTracker
  CLASS=com.jnbridge.labs.visio.JnbpJobTrackerWrapper
  HADOOP_OPTS="$HADOOP_OPTS $HADOOP_JOBTRACKER_OPTS"

и

elif [ "$COMMAND" = "namenode" ] ; then
#CLASS=org.apache.hadoop.hdfs.server.namenode.NameNode
CLASS=com.jnbridge.labs.visio.JnbpNameNodeWrapper
HADOOP_OPTS="$HADOOP_OPTS $HADOOP_NAMENODE_OPTS"

Строки замены находятся прямо под закомментированными оригинальными строками.

Чтобы завершить Java-часть этого решения, нам нужно добавить наши классы-обертки, а также JNBridge .jars в путь классов Hadoop. В нашем случае это означало просто добавить класс-оболочку .jars вместе с каталогом  jnbcore.jarи  bcel-5.1-jnbridge.jar в него  $HADOOP_INSTALL/hadoop/lib . Поскольку сценарии запуска Hadoop автоматически включают этот каталог как часть пути к классам Java, нам больше ничего не нужно делать. Сценарии запуска, поставляемые с дистрибутивом Hortonworks, работают точно так же, как и раньше, и кластер запускается без помех. Только теперь наши главные узлы прослушивают вызовы методов со стороны .NET нашего приложения для мониторинга.

Мониторинг на стороне Windows

Чтобы начать создавать прокси Java, нам нужно добавить .jars, которые содержат соответствующие классы, в путь к классам JNBridge. Ниже приведен скриншот из плагина JNBridge Visual Studio .jars, который мы добавили в путь к классам, используемый для создания прокси. Обратите внимание, что это включает в себя не только необходимые JNBridge .jars и Hadoop .jars (извлеченные из машин нашего кластера), но также и наш класс-упаковщик .jars (здесь он называется  proto1.jar).

Путь к классам

Отсюда нам нужно на самом деле выбрать те классы, которые нужно проксировать, чтобы они могли быть вызваны внутри нашего кода C # изначально. Самый простой способ сделать это — просто выбрать два класса-оболочки ( JnbpJobTrackerWrapper и  JnbpNameNodeWrapper) в левом окне прокси-инструмента JNBridge Visual Studio и нажать  Add+ кнопку. JNBridge позаботится об остальном автоматически.

классы

Теперь мы можем создать само приложение для мониторинга. Когда начинаете свой новый проект, обязательно добавьте правильные ссылки. Вам необходимо указать правильную  JNBShare.dll версию вашей .NET, DLL, созданную ранее выполненным вами процессом прокси-сервера JNBridge, и  Microsoft.Office.Interop.Visio.dll версию Microsoft Visio для вашей версии. Мы использовали Visio 2013 для этого проекта вместе с SDK (это более новая версия, чем та, что была в Visual Studio 2012). Кроме того, обязательно добавьте лицензию JNBridge .dll к вашему classpath. Вот как выглядели наши ссылки (обратите внимание, что  HadoopVis это имя мы дали нашему прокси-серверу Java .dll):

Ссылки

Общий поток нашего кода довольно прост: получите объекты JobTracker и NameNode, используйте их для построения внутреннего представления кластера, нарисуйте этот кластер в Visio и обновите этот чертеж с помощью последней информации о кластере.

Чтобы получить объекты JobTracker и NameNode, нам нужно подключиться к объектам-оберткам, работающим в нашем кластере. Мы делаем это следующим образом:

// Connect to the two Java sides
// The jobTracker side is automatically named "default"
JNBRemotingConfiguration.specifyRemotingConfiguration(JavaScheme.binary,
        "obiwan.local", 8085);
// We name the nameNode side "NameNode"
JavaSides.addJavaServer("NameNode", JavaScheme.binary, "obiwan.local", 8087);

Обратите внимание, что здесь мы подключаемся к двум сторонам Java, даже если они расположены на одной физической машине ( obiwan.local в нашем кластере). В JNBridgePro система должна знать, с какой стороной Java установить связь, чтобы нормально функционировать. Если у вас есть объект, который существует в одной удаленной JVM, и вы пытаетесь вызвать один из его методов, в то время как ваш код указывает на другую JVM, ваша программа потерпит крах. Чтобы управлять этим, используйте,  JavaSides.setJavaServer() чтобы указать на правильную JVM. Вы увидите, что это разбросано по всему нашему коду, когда мы переключаемся между указанием на JobTracker и JVM NameNode.

Как только мы соединились со стороной Java, нам просто нужно получить объекты и построить наше внутреннее представление кластера. Общий поток программы выглядит следующим образом:

JobTracker jobtracker = JnbpJobTrackerWrapper.getJobTracker();
java.util.Collection temp = jobtracker.activeTaskTrackers();
java.lang.Object[] tts = temp.toArray();
JavaSides.setJavaServer("NameNode");
NameNode namenode = JnbpNameNodeWrapper.getNameNode();
HadoopTree.buildTree(jobtracker, "obiwan.local", "obiwan.local", tts,
        namenode.getDatanodeReport(FSConstants.DatanodeReportType.ALL));
// closedFlag is True if a user closes the Visio window in use.
while (!closedFlag)
{
    JavaSides.setJavaServer("NameNode");
    DatanodeInfo[] dnReport = namenode.getDatanodeReport(
            FSConstants.DatanodeReportType.ALL);
    JavaSides.setJavaServer("default");
    HadoopTree.updateTree(jobtracker.activeTaskTrackers().toArray(),
            jobtracker.blacklistedTaskTrackers().toArray(), dnReport);
    System.Threading.Thread.Sleep(3000);
}

buildTree() И  updateTree() методы создания и обновления внутреннего представления кластера и держать его в  HadoopTree классе. Эти методы также вызывают  VisioDrawer класс, который, в свою очередь, рисует это внутреннее представление в Visio. Мы не будем вдаваться в подробности о том, как HadoopTree Класс строит наше внутреннее представление кластера. Простой алгоритм построения дерева, который мы используем, не очень подходит для нашего текущего обсуждения, но мы рекомендуем вам взглянуть на наш код, особенно если вам интересно, какие методы мы используем для извлечения информации из объектов JobTracker и NameNode (хотя некоторые из этих методов можно увидеть в приведенном выше фрагменте кода). Имейте в виду, что существует несколько способов получить информацию о кластере из этих объектов, и мы рекомендуем вам изучить опубликованные API-интерфейсы, чтобы выяснить, как получить информацию, которую вы хотите для своего приложения. Напомним, что API для NameNode в настоящее время не публикуется как часть официального Hadoop API, поэтому вам придется вернуться к исходному коду, чтобы выяснить, какие методы вызывать.API для NameNode также значительно отличается от API для JobTracker, поэтому не ожидайте схожей функциональности между ними.

Рисуем все в Visio

Когда у нас есть внутреннее представление кластера, нам нужно нарисовать его в Visio, чтобы завершить наше элементарное приложение для мониторинга / визуализации. Мы начнем с открытия нового экземпляра Visio, создания нового документа и добавления новой страницы:

// Start application and open new document
VisioApp = new Application();
VisioApp.BeforeDocumentClose += new EApplication_BeforeDocumentCloseEventHandler(quit);
ActiveWindow = VisioApp.ActiveWindow;
ActiveDoc = VisioApp.Documents.Add("");
ActivePage = ActiveDoc.Pages.Add();
ActivePage.AutoSize = true;

Затем мы открываем наш собственный сетевой шаблон (который мы включили в код для вашего использования) и извлекаем все мастера, которые нам нужны, чтобы нарисовать нашу диаграмму кластера Hadoop:

// Open visual templates
networkTemplate = VisioApp.Documents.OpenEx(@"$Template_Directory\NetTemplate.vstx",
        (short)VisOpenSaveArgs.visOpenHidden);
Document pcStencil = VisioApp.Documents["COMPME_M.VSSX"];
Document networkStencil = VisioApp.Documents["PERIME_M.VSSX"];
Shape PageInfo = ActivePage.PageSheet;
PageInfo.get_CellsSRC((short)VisSectionIndices.visSectionObject,
        (short)VisRowIndices.visRowPageLayout,
        (short)(VisCellIndices.visPLOPlaceStyle)).set_Result(VisUnitCodes.visPageUnits,
                (double)VisCellVals.visPLOPlaceTopToBottom);
PageInfo.get_CellsSRC((short)VisSectionIndices.visSectionObject,
        (short)VisRowIndices.visRowPageLayout,
        (short)(VisCellIndices.visPLORouteStyle)).set_Result(VisUnitCodes.visPageUnits,
                (double)VisCellVals.visLORouteFlowchartNS);
ActivePage.SetTheme("Whisp");
 
// Get all the master shapes
masterNode = pcStencil.Masters.get_ItemU("PC");
slaveNode = networkStencil.Masters.get_ItemU("Server");
rack = networkStencil.Masters.get_ItemU("Switch");
dynamicConnector = networkStencil.Masters.get_ItemU("Dynamic connector");
 
// Open data visualization template and shape
slaveBase = VisioApp.Documents.OpenEx(@"$Template_Directory\DataGraphicTemplate.vsdx",
        (short)Microsoft.Office.Interop.Visio.VisOpenSaveArgs.visOpenHidden);
slaveDataMaster = slaveBase.Pages[1].Shapes[1].DataGraphic;

В этом фрагменте есть две важные вещи, которые не встречаются во многих примерах с использованием Visio. Сначала эти два утверждения:

PageInfo.get_CellsSRC((short)VisSectionIndices.visSectionObject,
        (short)VisRowIndices.visRowPageLayout,
        (short)(VisCellIndices.visPLOPlaceStyle)).set_Result(VisUnitCodes.visPageUnits,
                (double)VisCellVals.visPLOPlaceTopToBottom);
PageInfo.get_CellsSRC((short)VisSectionIndices.visSectionObject,
        (short)VisRowIndices.visRowPageLayout,
        (short)(VisCellIndices.visPLORouteStyle)).set_Result(VisUnitCodes.visPageUnits,
                (double)VisCellVals.visLORouteFlowchartNS);

Эти операторы говорят Visio, как планировать диаграмму по мере ее отрисовки. Первая инструкция говорит Visio создать чертеж сверху вниз (с главными узлами сверху и подчиненными узлами снизу), а вторая говорит Visio упорядочить все в шаблоне в стиле потоковой диаграммы (мы обнаружили, что это наиболее логичный вид кластера). Логично, что мы делаем, редактируем два значения в Shapesheet текущей страницы, на которые Visio ссылается при принятии решений по макету для этой страницы.

Второе, на что мы хотим обратить ваше внимание, это следующие строки:

slaveBase = VisioApp.Documents.OpenEx(@"$Template_Directory\DataGraphicTemplate.vsdx",
        (short)Microsoft.Office.Interop.Visio.VisOpenSaveArgs.visOpenHidden);
slaveDataMaster = slaveBase.Pages[1].Shapes[1].DataGraphic;

Этот код открывает предыдущий проект Visio (который мы также включили в наш код), в котором мы просто привязали серию DataGraphics к одному Shape. Эти DataGraphics можно затем удалить из старого проекта и привязать к Shapes в нашем новом проекте. Наши готовые DataGraphics используются для отображения информации об отдельных узлах в кластере, включая пространство HDFS, используемые преобразователи / редукторы и общее состояние TaskTracker и DataNode. Мы должны создать эти DataGraphics заранее, так как они не могут быть созданы программно.

Затем мы можем нарисовать кластер на странице, которую мы создали. Опять же, мы собираемся пропустить эту часть процесса, поскольку это в основном стандартный код Visio. Представление кластера рисуется в основном с использованием Page.DropConnected() метода, и, поскольку мы уже рассказали Visio, как форматировать чертеж, нам не нужно слишком много возиться с его макетом. Все, что нам нужно сделать, это вызвать Page.Layout() после того,  как все фигуры нарисованы, чтобы убедиться, что все выровнено правильно.

Последний интересный момент, который мы хотим затронуть, это обновление чертежа самыми последними данными из кластера. Сначала нам нужно получить последние данные из кластера и обновить наше внутреннее представление кластера:

public static void updateTree(Object[] taskNodeInfo, Object[] deadTaskNodes,
        DatanodeInfo[] dataNodeInfo)
{
    JavaSides.setJavaServer("NameNode");
    foreach (DatanodeInfo dn in dataNodeInfo)
    {
        HadoopNode curNode;
        leaves.TryGetValue(dn.getHostName(), out curNode);
        if (dn.isDecommissioned())
        {
            curNode.dataActive = false;
        }
        else
        {
            curNode.setHDSpace(dn.getRemainingPercent());
            curNode.dataActive = true;
        }
    }
    JavaSides.setJavaServer("default");
    foreach (TaskTrackerStatus tt in taskNodeInfo)
    {
        HadoopNode curNode;
        leaves.TryGetValue(tt.getHost(), out curNode);
        curNode.setMapUse(tt.getMaxMapSlots(), tt.countOccupiedMapSlots());
        curNode.setReduceUse(tt.getMaxReduceSlots(), tt.countOccupiedReduceSlots());
        curNode.taskActive = true;
    }
    foreach (TaskTrackerStatus tt in deadTaskNodes)
    {
        HadoopNode curNode;
        leaves.TryGetValue(tt.getHost(), out curNode);
        curNode.taskActive = false;
    }
    VisioDrawer.updateData(leaves);
}

Как только данные собраны, чертеж Visio обновляется:

public static void updateData(Dictionary<string, HadoopNode> leaves)
{
    foreach (KeyValuePair<string, HadoopNode> l in leaves)
    {
        HadoopNode leaf = l.Value;
        Shape leafShape = leaf.getShape();
        // Update HDFS information
        if (leaf.dataActive)
        {
            leafShape.get_CellsSRC(243, 20, 0).set_Result(0, leaf.getHDSpace());
            leafShape.get_CellsSRC(243, 0, 0).set_Result(0, 1);
        }
        // If the DataNode has failed, turn the bottom checkmark to a red X
        else
        {
            leafShape.get_CellsSRC(243, 0, 0).set_Result(0, 0);
        }
        // Update mapred information
        if (leaf.taskActive)
        {
            leafShape.get_CellsSRC(243, 17, 0).set_Result(0, leaf.getMapUse());
            leafShape.get_CellsSRC(243, 18, 0).set_Result(0, leaf.getReduceUse());
            leafShape.get_CellsSRC(243, 12, 0).set_Result(0, 1);
        }
        // If the Tasktracker has failed, turn the bottom checkmark to a red X
        else
        {
            leafShape.get_CellsSRC(243, 12, 0).set_Result(0, 0);
        }
    }
}

Логически мы просто меняем определенные значения в каждой форме Shapes, которые связаны с DataGraphics, которую мы добавили ранее. Какие ячейки таблицы форм соответствуют тому, какой DataGraphic нужно было решить заранее, когда мы создали DataGraphic вручную. Таким образом, мы можем обратиться к этим индексам непосредственно в нашем коде.

Этот процесс обновления (как вы видели в предыдущем фрагменте кода) выполняется в простом while система опроса петли, которая обновляется каждые три секунды. Мы использовали этот метод вместо стратегии обратного вызова / обработки событий в основном для простоты реализации. Классы NameNode и JobTracker не реализуют интерфейс слушателя для уведомления, когда значения изменяются. В результате, чтобы добавить эту функциональность, нам пришлось бы сделать значительно больше взлома Hadoop, чем мы уже сделали. Мы могли бы также реализовать асинхронную систему обновления в чистом C #, которая бы использовала события для уведомления графического объекта об обновлении, но для этого все равно требовался бы опрос на стороне Java для изменений где-то в пределах нашего потока программы. Такая система снизит нагрузку на Visio, уменьшив количество раз, которое мы рисуем на страницу, но не повысит общую эффективность. Хотя оба способа реализации обратных вызовов являются интересными упражнениями,они несколько выходят за рамки этой лаборатории.

The Result

For our small, four-virtual-machine cluster, this is the result (as you saw above):

визуализатор

Here a Map/Reduce job is running such that 100% of the Mappers are in use and none of the Reducers are being used yet. Also, notice that the middle worker node has used up almost all of its local HDFS space. That should probably be addressed.

For larger, enterprise-size clusters Visio will likely become an even less viable option for handling the visualization, but for our proof-of-concept purposes it works just fine. For larger clusters, building a visualizer with WPF would probably be the better answer for a .NET-based solution.

We hope this lab has been a springboard for your own ideas related to creating Hadoop monitoring/visualization applications.

~Ian Heinzman