Поиск на сайте: Расширенный поиск


Новые программы oszone.net Читать ленту новостей RSS
CheckBootSpeed - это диагностический пакет на основе скриптов PowerShell, создающий отчет о скорости загрузки Windows 7 ...
Вы когда-нибудь хотели создать установочный диск Windows, который бы автоматически установил систему, не задавая вопросо...
Если после установки Windows XP у вас перестала загружаться Windows Vista или Windows 7, вам необходимо восстановить заг...
Программа подготовки документов и ведения учетных и отчетных данных по командировкам. Используются формы, утвержденные п...
Red Button – это мощная утилита для оптимизации и очистки всех актуальных клиентских версий операционной системы Windows...
OSzone.net Microsoft Разработка приложений Языки программирования Разбор файлов журналов с помощью F#, MapReduce и Windows Azure RSS

Разбор файлов журналов с помощью F#, MapReduce и Windows Azure

Текущий рейтинг: 0 (проголосовало 0)
 Посетителей: 946 | Просмотров: 2323 (сегодня 0)  Шрифт: - +

Как давнего программиста на Python меня заинтриговало интервью с Доном Сайми (Don Syme), архитектором языка F#. В этом интервью Дон упомянул, что «некоторые рассматривают [F#] как строго типизированную разновидность Python, вплоть до различий в синтаксисе». Это поразило меня, и я решил, что этот вопрос стоит изучить глубже.

Как оказалось, F# — совершенно новый и очень интересный язык программирования, который до сих пор остается загадкой для многих разработчиков. F# предлагает те же преимущества в эффективности труда программистов, что и Ruby/Python в последние годы. F# — подобно Ruby и Python — высокоуровневый язык с минимальным синтаксисом и элегантностью выражения. Но настоящая уникальность F# заключается в том, что он сочетает в себе эти практичные средства с изощренной системой логического распознавания типов (type-inference system) и многими достижениями из мира функционального программирования. Это размещает F# в классе с несколькими узлами.

Но новый высокопродуктивный язык программирования — не единственная на сегодня новая интересная технология.

Широкое распространение облачных платформ вроде Windows Azure делают доступными распределенные хранилища и компьютерные ресурсы как крупным компаниям, так и разработчикам-одиночкам. Наряду с облачными хранилищами появились полезные инструменты наподобие горизонтально масштабируемого алгоритма MapReduce, которые позволяют быстро писать код, способный эффективно анализировать и сортировать потенциально гигантские наборы данных.

Этот подход удобен для отладки на скорую руку F#-программ. Такие инструменты дают возможность, написав несколько строк кода и развернув их в облаке, манипулировать гигабайтами данных. Просто замечательно.

В этой статье я поделюсь с вами некоторыми из своих находок в области F#, Windows Azure и MapReduce. Я покажу, как можно использовать F# и алгоритм MapReduce для разбора файлов журналов в Windows Azure. Сначала мы рассмотрим некоторые методики создания прототипов (prototyping), чтобы уменьшить сложность программирования MapReduce, а затем перенесем результаты нашего труда в… облако.

Азы работы с F#

Один из новых стилей работы, ставших доступными .NET-программистам с появлением F#, — рабочий процесс Interactive, привычный многим программистам на Perl, Python и Ruby. При таком стиле программирования часто используют среду интерактивного кодирования вроде оболочки самого Python или отдельный инструмент, например IPython. Это позволяет разработчику импортировать класс из модуля, создать его экземпляр, а затем, используя командную строку, изучить его методы и данные.

Распространенный способ интерактивной разработки, который станет привычным .NET-программистам, — простое написание кода в Visual Studio и передача его фрагментов в окно F# Interactive для выполнения. Фрагменты отправляются нажатием комбинации клавиш Alt+Enter применительно к текущему выделенному тексту. Кроме того, нажатие Alt+' позволяет отправить в это окно единственную строку. Пример использования этой методики показан на рис. 1.

*

Рис. 1. Использование окна F# Interactive

Этот подход удобен для отладки на скорую руку F#-программ; кроме того, в разрабатываемом вами скрипте на F# доступны и IntelliSense, и выполнение из командной строки.

Второй подход — вы вновь пишете код в Visual Studio, но потом копируете разделы кода из Visual Studio и напрямую вставляете их в автономную F# Interactive Console (рис. 2). В этом случае вы должны добавлять в конец вставленного кода две точки с запятыми. Это позволяет интерактивно взаимодействовать с кодом и дополнительно использовать преимущества выполнения из командной строки. Возможно, вы перейдете на этот вариант, когда привыкнете программировать в более интерактивном стиле.

*

Рис. 2. F# Interactive Console

Вы также можете вести интерактивную разработку на F#, запуская свой код непосредственно из Windows PowerShell; иначе говоря, передавая скрипт в fsi.exe (исполняемый файл F# Interactive Console) Одно из преимуществ такого подхода в том, что это позволяет быстро создавать прототипы скриптов и передавать результаты на стандартный вывод. Кроме того, можно итеративно изменять код в «облегченном» текстовом редакторе, например в Notepad++. На рис. 3 показан пример вывода от скрипта MapReduce, запускаемого из Windows PowerShell; этот скрипт я буду часто использовать в данной статье.

Рис. 3. Выполнение скрипта на F# в Windows PowerShell

PS C:\Users\Administrator\Desktop> & 'C:\Program Files (x86)\FSharp-2.0.0.0\bin\fsi.exe' mapreduce.fsscript
192.168.1.1, 11
192.168.1.2, 9
192.168.1.3, 8
192.168.1.4, 7
192.168.1.5, 6
192.168.1.6, 5
192.168.1.7, 5

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

Теперь, когда вы знаете азы работы в F#, давайте углубимся в какой-нибудь реальный код.

Разбор журналов в стиле MapReduce

В дополнение к ранее упомянутым преимуществам интерактивного программирования код на F# является четким и эффективным. Пример на рис. 4 состоит менее чем из 50 строк кода, но содержит все важные части алгоритма MapReduce для вычисления десяти наиболее часто встречающихся IP-адресов в наборе файлов журналов.

Рис. 4.Алгоритм MapReduce для разбора файла журнала

open System.IO
open System.Collections.Generic

// Map Phase
let inputFile = @"web.log"
let mapLogFileIpAddr logFile =
  let fileReader logFile =
    seq { use fileReader = new StreamReader(File.OpenRead(logFile))
      while not fileReader.EndOfStream do
        yield fileReader.ReadLine() }

  // Takes lines and extracts IP Address Out,
  // filter invalid lines out first
  let cutIp =
    let line = fileReader inputFile
    line
    |> Seq.filter (fun line -> not (line.StartsWith("#")))
    |> Seq.map (fun line -> line.Split [|' '|])
    |> Seq.map (fun line -> line.[8],1)
    |> Seq.toArray
  cutIp

// Reduce Phase
let ipMatches = mapLogFileIpAddr inputFile
let reduceFileIpAddr =
  Array.fold
    (fun (acc : Map<string, int>) ((ipAddr, num) : string * int) ->
      if Map.containsKey ipAddr acc then
        let ipFreq = acc.[ipAddr]
        Map.add ipAddr (ipFreq + num) acc
      else
        Map.add ipAddr 1 acc)
    Map.empty
    ipMatches

// Display Top 10 Ip Addresses
let topIpAddressOutput reduceOutput =
  let sortedResults =
    reduceFileIpAddr
    |> Map.toSeq
    |> Seq.sortBy (fun (ip, ipFreq) -> -ipFreq)
    |> Seq.take 10
  sortedResults
  |> Seq.iter(fun (ip, ipFreq) ->
    printfn "%s, %d" ip ipFreq);;

reduceFileIpAddr |> topIpAddressOutput

Эту автономную версию, которая впоследствии станет сетевой, можно разбить на три фазы: сопоставление (map phase), сокращение (reduce phase) и отображение (display phase).

Первой фазой является сопоставление. Функция mapLogFileIpAddr принимает файл журнала как параметр. В этой функции определена другая функция, fileReader, в которой используется методика функционального программирования для отложенного получения строки текста из файла (впрочем, языки вроде C# и Python тоже позволяют делать это). Далее функция cutIp разбирает каждую строку ввода, отбрасывает строки комментариев и возвращает IP-адрес и целое число (1).

Это эффективная методика обработки данных. Выделите весь блок кода, отвечающего за сопоставление, и выполните его в окне F# Interactive вместе со строкой:

let ipMatches = mapLogFileIpAddr inputFile

Вы увидите следующий вывод:

val ipMatches : seq<string * int>

Заметьте, что на данный момент никаких операций не выполнялось и что файл журнала не считывался. Единственное, что было сделано, — оценено выражение. Благодаря этому выполнение откладывается до тех пор, пока в нем не появится реальная потребность, и данные не извлекаются в память только ради того, чтобы оценить выражение. Это эффективная методика обработки данных, и ее эффективность станет особенно заметной, когда вам понадобится разбор гигантских файлов журналов, размеры которых исчисляются гигабайтами или терабайтами.

Если вы хотите прочувствовать разницу, просто добавьте line в функцию cutIp, чтобы она выглядела так (Примечание. строка |> Seq.toArray для конструкции функции совсем необязательна; в нашем примере она специально используется для убыстрения работы функции, если бы ее не было, функция просто бы работала медленно, как, например, функция mapLogFileIpAddr.):

let cutIp =
  let line = fileReader inputFile
  line
  |> Seq.filter (fun line -> not (line.StartsWith("#")))
  |> Seq.map (fun line -> line.Split [|' '|])
  |> Seq.map (fun line -> line.[8],1)
  |> Seq.toArray
cutIp

Если вы отправите этот код интерпретатору F# и предоставите большой файл журнала, содержащий несколько гигабайт данных, то можете прогуляться и выпить чашечку кофе, так как ваш компьютер будет занят чтением всего файла и генерацией для него сопоставлений «ключ-значение» в памяти.

В следующей части конвейера данных я принимаю вывод от предыдущей и отправляю результаты в анонимную функцию, которая подсчитывает число вхождений IP-адресов в последовательности. Все значения добавляются в структуру данных Map через рекурсию. Этот стиль программирования может оказаться трудным в понимании для разработчиков — новичков в функциональном программировании, поэтому вы, возможно, захотите вставить выражения print внутрь анонимной функции, чтобы видеть, что именно она делает.

При императивном программировании вы могли бы добиться того же, обновляя изменяемый словарь, в котором каждый IP-адрес хранится как ключ, перебирая последовательность IP-адресов в цикле, а потом обновляя счетчик для каждого адреса.

Последняя фаза не имеет ничего общего с алгоритмом MapReduce, но полезна при изучении скриптов на этапе создания прототипов. Результаты фазы сопоставления передаются из структуры данных Map в Seq, сортируются, а затем выводятся 10 наиболее часто встречающихся. Заметьте, что при таком стиле конвейеризации данных результаты одной операции перетекают в другую безо всякого цикла for.

MapReduce и Windows Azure

Закончив проверку прототипа, пора заняться его переносом в среду, напоминающую производственную. В качестве примера я перенес программу из настольной системы в Windows Azure.

Для начала будет полезно посмотреть на примеры F#-кода для Windows Azure по ссылке code.msdn.microsoft.com/fsharpazure и установить шаблоны Windows Azure. Особенно интересен пример webcrawler, где рабочая роль F# использует хранилище двоичных объектов и очереди. Этот проект стоит тщательно изучить, если вас интересует более «продвинутое» применение F# в сочетании Windows Azure.

Я не стану детально рассматривать конфигурирование фермы MapReduce со множеством узлов. Вместо этого я представлю общий обзор. Вся специфика изложена в статье Джоша Твиста (Josh Twist) в журнале MSDNMagazine «Synchronizing Multiple Nodes in Windows Azure» (msdn.microsoft.com/magazine/gg309174).

Сконфигурировать ферму MapReduce в Windows Azure можно несколькими способами. Один из примеров использования рабочих ролей F#, которые равномерно распределяются между рабочими ролями сопоставления (Map Workers) и сокращения (Reduce Workers), показан на рис. 5. Сделать это очень легко: вы просто копируете и вставляете функцию сопоставления в Map Worker, а функцию сокращения — в Reduce Worker.

*

Рис. 5. Ферма MapReduce в Windows Azure

Детальное объяснение распределенного алгоритма и его возможных реализаций отлично представлено в презентации MapReduce, подготовленной Джеффом Дином (Jeff Dean) и Санжаем Гемаватом (Sanjay Ghemawat) (labs.google.com/papers/mapreduce-osdi04-slides/). Однако в примере на рис. 5 показано, что рабочие роли F# параллельно используют несколько файлов журналов. Потом они возвращают свой вывод, состоящий из ключей IP-адресов со значением 1, через Windows Azure AppFabric Service Bus рабочим ролям сокращения или с помощью записи на диск.

Далее рабочие роли сокращения считывают эти промежуточные данные и выдают суммарный счетчик пар «ключ-значение», записывая их в хранилище двоичных объектов. Каждая такая роль создает собственный отчет, и все эти отчеты надо объединить перед сортировкой и отображением главной рабочей ролью (Master Worker).

Создание и публикация рабочей роли

Закончив прототип и планирование высокоуровневой архитектуры, создайте необходимый проект в Visual Studio 2010 и опубликуйте его в Windows Azure.

Создание рабочей роли F# — не столь простой процесс, как хотелось бы, поэтому давайте разберем все необходимые этапы. Сначала вам потребуется скачать ранее упомянутые шаблоны Windows Azure F#. Затем вы должны создать проект Visual F# для Windows Azure. Я присвоил проекту имя AzureFSharpProject.

После этого у вас появится возможность создать рабочую роль F#, как показано на рис. 6.

*

Рис. 6. Создание рабочей роли F#

В этот момент вы можете поместить свою функцию сопоставления в роль Map Worker, а функцию сокращения в роль Reduce Worker. Затем создайте дополнительные рабочие роли для других ролей Map Worker и Reduce Worker в зависимости от масштаба ваших потребностей в обработке данных. Канонический справочник — документ Google MapReduce по ссылке labs.google.com/papers/-mapreduce.html. В нем подробно описываются архитектура MapReduce, возможные проблемы и сценарии применения.

Когда вы будете готовы к публикации в Windows Azure, щелкните правой кнопкой мыши свой проект и выберите Publish | Create Service Package Only, как показано на рис. 7.

*

Рис. 7. Публикация в Windows Azure

Наконец, вам потребуется зарегистрироваться на портале управления Windows Azure и через его интерфейс создать рабочую роль (рис. 8).

*

Рис. 8. Конфигурирование новой рабочей роли

В этот момент вы можете подключать свои узлы так, как считаете нужным, и обрабатывать алгоритмом MapReduce журналы в облаке. Конечно, этот же подход легко применим к источникам данных, отличных от простых файлов журналов. Универсальный F#-алгоритм MapReduce — наряду с интерактивными средствами, которые я продемонстрировал при его кодировании, — можно использовать практически для любой работы, связанной с разбором, сопоставлением и сокращением.

Дальнейшие шаги

F# — мощный язык программирования, который позволяет решать многие задачи с помощью как небольших блоков кода, так и более сложных программ, составляемых из этих блоков. В этой статье я продемонстрировал, как, написав всего 50 строк кода на F#, можно превратить алгоритм MapReduce в анализатор журналов на основе Windows Azure.

Что касается реализации MapReduce в Windows Azure, то, вероятно, вам стоит прочитать еще пару интересных статей по этой тематике. Сначала обратите внимание на статью «Building a Scalable, Multi-Tenant Application for Windows Azure» в MSDN, где обсуждаются рабочие роли и MapReduce (msdn.microsoft.com/library/ff966483). Потом прочтите статью Хуана Диаз (Juan Diaz) «Comparison of the use of Amazon’s EC2 and Windows Azure, cloud computing and implementation of MapReduce», в блоге по ссылке (bit.ly/hBQFSt).

Если вы еще не освоили F#, то, надеюсь, эта статья подтолкнет вас к тому, чтобы попробовать поработать на этом языке. А если вам интересно прослушать все интервью Дона Сайми (Don Syme), отправляйтесь в блог Simple-Talk (bit.ly/eI74iO).

Автор: Ноа Гифт  •  Иcточник: MSDN Magazine  •  Опубликована: 17.10.2011
Нашли ошибку в тексте? Сообщите о ней автору: выделите мышкой и нажмите CTRL + ENTER


Оценить статью:
Вверх
Комментарии посетителей
Комментарии отключены. С вопросами по статьям обращайтесь в форум.