пятница, 19 ноября 2010 г.

пятница, 12 ноября 2010 г.

MapReduce. Основы

MapReduce - модель программирования для параллельной обработки данных. Про MapReduce уже написано и сказано много. Самые лучшие материалы я прикладываю ниже.
Видеолекция посвященная MapReduce и распределенной файловой системе HDFS:


Cloudera Hadoop Training: MapReduce and HDFS from Cloudera on Vimeo.

Документ от Google, в котором впервые был описан MapReduce:




Код ниже описывает простейшую MapReduce программу, которая подсчитывает количество вхождений определенного слова в документах. На вход map подается название документа и его содержание. Map разбивает содержание документа на список слов и пересылает каждое слово на reduce вместе с 1. MapReduce фреймворк производит группировку всех получаемых данных по ключу и формирует список значений. Ключ и данный список передается на нашу reduce функцию, которая производит суммирование полученного списка и пересылает результат.


map(String input_key, String input_value):
  // input_key: название документа
  // input_value: содержание документа
  for each word w in input_value:
    Emit(w, 1);
reduce(String output_key, Iterator intermediate_values):
  // output_key: слово
  // output_values: список кол-ва вхождений слова
  int result = 0;
  for each v in intermediate_values:
    result += v;
  Emit(result);


Ниже представлена схема процесса обработки данных.



Самый интересный момент в данной программе состоит в том, почему она пересылает единичку с каждым словом, а не строит например HashMap, подсчитывает общее количество слов и уже потом отсылает свой список. MapReduce фреймворк избавляет нас от необходимости создавать какие-то структуры в оперативной памяти и делать предварительные группировки. Ведь объем данных, пересылаемых на map шаг может составлять более сотни мегабайт. На одном вычислительном узле, как правило запускается одновременно map и reduce задачи (map задач значительно больше). Поэтому использование например 64 Мб на каждую из map задач может вести к падению общей производительности. 
Но такая возможность остается при помощи применения комбинаторов. Комбинаторы как раз занимаются обработкой данных после map шага и перед reduce шагом для уменьшения количества пересылаемых данных. 
Например, по закону Зипфа слова "the" в английском языке будут встречаться чаще других слов и какому-то узлу будет приходить значительно больше данных, чем другим узлам. Если мы предварительно сольем все одинаковые ключи, то пересылаемых данных может стать меньше.


Представленных материалов достаточно, чтобы разобраться, что же такое MapReduce, но
недостаточно для того, чтобы начать писать настоящие MapReduce программы.
В следующем посте мы с вами разберем, как писать MapReduce программы.

четверг, 11 ноября 2010 г.

Spring Roo. Что за зверь?

Spring Roo - набор утилит и плагинов, который позволяет ускорить и упростить разработку Spring-приложений. Особенно хорошо он подходит для людей, которые впервые сталкиваются с разработкой приложений на Spring.

Установка
  1. Необходимо скачать набор бинарных утилит - это ядро самого Spring Roo - http://www.springsource.com/products/spring-community-download. Необходимо добавить /bin папку данных утилит в PATH.
  2. Если вы работаете под Eclipse, то поставить SpringSource Tool Suite, как плагин или в виде отдельной сборки - http://www.springsource.com/developer/sts. Я рекомендую вариант плагина.
  3. Maven - http://maven.apache.org/download.html, а также плагин к Eclipse m2Eclipse.
Вы можете просмотреть видео по установке Spring Roo, если возникли какие-то затруднения http://s3.springsource.com/MRKT/roo/2010-01-Five_Minutes_Roo.mov.

Первый проект
Инструкция по созданию тестового проекта представлена на http://static.springsource.org/spring-roo/reference/html/intro.html#intro-first-steps. Думаю, что там нет ничего сложного.

Мой опыт работы
Консоль
Центральным элементом Roo является её консоль. В консоли качественно реализована функция suggest. Единственное, что иногда консоль может выдавать большее количество подсказок.

Использование аспектов AspectJ и кодогенерация
В Roo аспекты использованы очень удачно. Они генерируются автоматически по аннотациям классов. Если какой-либо из этих аспектов не нужен, то необходимо удалить соответствующую аннотацию. В случае изменения данных в классе, эти аспекты автоматически пересоздаются. Редактировать вручную их можно, но изменения не сохранятся, при любом изменении произойдет перегенерация аспектов.
Например, Roo может выносить в аспекты следующие вещи:
  • геттеры и сеттеры
  • метод toString (с возможностью настройки того, какие поля будут в нем прописываться)
  • базовые вещи для Entity классов. Это например id поле, аннотация того, что класс является сущностью. EntityManager и т.д.
  • стандартные методы контроллеров
  • генерация finder-методов. Roo может генерировать практически любые комбинации полей, по которым необходимо искать. 
Единственное, что тут непонятно для меня, так это почему автоматически не генерируются методы equals и hashCode.  UPDATE: Генерация данных методов вынесена в отдельный плагин http://code.google.com/p/spring-roo-equals-roo-addon/. Возможно, этот плагин войдет в новый релиз.
С аспектами возможно появление непредсказуемых багов в плане отладки. Там возможны некоторые затруднения с дебагом.

Добавление полей сущностям
Эта функция реализована на ура. Можно добавлять новые поля, как из консоли, так и из IDE. Roo все подхватывает и исправляет.

Scaffold
Roo предоставляет возможность Scaffold. Реализуется это при помощи установки аннотации @RooWebScaffold на класс модели. Scaffold - это автоматическая генерация UI по моделям. Это функция очень хороша, когда надо создать скелет UI в проекте с новыми технологиями. Можно посмотреть, как все работает и исправить на свой вкус. 
Сам скаффолд генерируется в виде *.jspx файлов и небольшой библиотечки тегов.
Хотя с исправлением скаффолда сейчас не все гладко, например, если вы в скаффолде укажете русские символы, то при следующем обновлении увидите заместо них "???". Это связано с тем, что проект ещё сыроват, особенно в плане поддержки других языков.
Естественно, что в каких-либо реальных проектах будет просто необходимо отказываться от скаффолда. 
С версии 1.1.0 возможен scaffold при помощи GWT.

Maven
Maven используется, как для поддержания зависимостей проекта от сторонних библиотек, так и для запуска проекта в сервлет-контейнере. 

Обновление
Начинал я работу со Spring Roo с версии 1.0.0. Во время моей работы Roo успел обновиться до версии 1.1.0. Изменения очень сильные, по сути пришлось пересоздавать проект. Подозреваю, что такая нестабильность сохранится и в ближайшее время, поэтому для серьезных проектов использовать Roo рано. 

Документация
Как и в Spring, документация здесь далеко не всегда полная и полезная.

Баги
Сталкивался с парой багов, связанных с UTF-8 кодировками. Они до сих пор не решены в 1.1.0 и будут решены в 1.1.1. Одна из них, кстати, благодаря мне.

вторник, 9 ноября 2010 г.

Maven Tomcat remote debugging under Windows

If you want to debug Java application, which is running through mvn tomcat:run on Windows, you MUST set environment variable MAVEN_OPTS without double quotes! It's some stupid problem that eats many time to resolve.

So use the following commands in your Windows cmd:

>set MAVEN_OPTS=-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000
>mvn tomcat:run
In the Linux use:
>MAVEN_OPTS="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=8000";
>export MAVEN_OPTS
>mvn tomcat:run