<?xml version="1.0" encoding="utf-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom"><channel><title>Insight IT</title><link>https://www.insight-it.ru/</link><description></description><atom:link href="https://www.insight-it.ru/tag/razrabotka/feed/index.xml" rel="self"></atom:link><lastBuildDate>Mon, 29 Apr 2013 10:47:00 +0400</lastBuildDate><item><title>Горячая замена кода</title><link>https://www.insight-it.ru//theory/2013/goryachaya-zamena-koda/</link><description>&lt;p&gt;Относительно недавно почитывая RSS через доживающий свои дни Google
Reader, о предстоящем закрытии которого не написал только самый ленивый
IT-блоггер &lt;em&gt;(к слову, любопытно насколько
сильно просядет счетчик &lt;a href="/feed/"&gt;RSS-подписчиков Insight IT&lt;/a&gt; с текущих
16870, боюсь, что очень сильно...)&lt;/em&gt;, я наткнулся на статью под
заголовком &lt;strong&gt;"Горячее обновление кода не нужно?"&lt;/strong&gt; и с выводом, что мол и
правда особо не нужно, которая и подтолкнула меня поделиться своими
мыслями на эту тему.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Для начала давайте разберемся в том, что же вообще такое &lt;strong&gt;"горячая
замена кода"&lt;/strong&gt; &amp;nbsp;(&lt;em&gt;hot code replacement&lt;/em&gt;&amp;nbsp;или&amp;nbsp;&lt;em&gt;hot code swapping&lt;/em&gt;)? По
сути это возможность обновить (или откатить) код работающей программы
без её&amp;nbsp;перезапуска и, как следствие, периода недоступности, потери
состояния и повторной инициализации.&lt;/p&gt;
&lt;p&gt;В каких ситуациях это может быть полезно? Ответ следует из моего
импровизированного определения выше:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Когда простой &lt;em&gt;(downtime)&lt;/em&gt; неприемлем&lt;/li&gt;
&lt;li&gt;Когда есть какое-то состояние в памяти, которое не хочется терять&lt;/li&gt;
&lt;li&gt;Когда инициализация процесса трудоемка и занимает много времени, что
    чаще всего связано с восстановлением &amp;nbsp;состояния с диска или других
    внешних источников&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Ко многим клиент-серверным приложениям, в том числе и веб-сайтам,
предъявляют очень высокие требования по отказоустойчивости, то есть
простои как таковые не допустимы даже в экстренных случаях, не говоря
уже о регулярном обновлении компонентов системы. Но чтобы обеспечить
высокой уровень доступности, измеряемый количеством девяток после
запятой в 99.(9)%, одной горячей замены кода не достаточно, нужно в
любом случае обеспечить доступность всех данных и ключевых серверных
компонентов системы даже в случае выхода из строя сервера, стойки,
маршрутизатора и даже целого датацентра. Обычно это делается "на уровень
выше" относительно самого кода приложения, путем добавления в систему
как минимум резервных (активных или пассивных) копий всех компонентов и
балансировщика нагрузки, способного обнаруживать неполадки и
соответствующим образом перенаправлять поток запросов. Балансировщик
нагрузки также нуждается в выделении под него как минимум двух серверов
с переключением на уровне DNS. Возвращаясь к изначальной теме: если уж
приложение способно пережить экстренный сбой любого компонента, то и без
всякой горячей замены спокойно переживет его плановый перезапуск в связи
с обновлением. Хотя на практике даже при резервировании всех компонентов
небольшая доля запросов может быть потеряна или обработана за
неприемлемо длинный срок в процессе перемаршрутизации их потока.&lt;/p&gt;
&lt;p&gt;Казалось бы клиент-серверные приложения чаще всего не имеют состояния, в
том плане, что все состояние находится в какой-то внешней сущности вроде
СУБД, так что инициализировать особо нечего и состояние потерять не
жалко. И на самом деле часто так и бывает, в том же мире
&lt;a href="/tag/php/"&gt;PHP&lt;/a&gt;&amp;nbsp;довольно популярна практика: положить новую версию кода
в соседнюю папочку, поменять document root в конфиге nginx, попросить
nginx перечитать свой конфиг - максимум сбросится кэш &lt;a href="/tag/apc/"&gt;APC&lt;/a&gt;
или &lt;a href="/tag/xcache/"&gt;xcache&lt;/a&gt;, что мало кого волнует, так как побочным
эффектом будет просто несколько ответов на запросы медленнее обычного.&lt;/p&gt;
&lt;p&gt;А как быть с самой СУБД? Например, &lt;a href="/tag/redis/"&gt;Redis&lt;/a&gt; при запуске
зачитывает в память все данные прежде чем начать принимать запросы, что
может занимать сколько-то минут. Другие СУБД, которые могут отвечать на
запросы и по данным на диске, стартуют относительно быстро, но провал в
их производительности до того, как разогреется встроенный в них кэш,
заметен невооруженным глазом. Очень похожа ситуация и с брокерами
сообщений вроде &lt;a href="/tag/rabbitmq/"&gt;RabbitMQ&lt;/a&gt;: если они и хранят данные на
диске, то скорее как резервную копию. А&amp;nbsp;&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;,
Redis без персистентности&amp;nbsp;и другие хранилища данных в памяти вовсе могут
разогреваться после перезапуска неопределенно долго, так как наполняются
по мере поступления запросов на запись.&lt;/p&gt;
&lt;p&gt;В языках программирования, основанных на байт-коде и виртуальных
машинах, зачастую есть возможность осуществлять &lt;em&gt;горячее обновление
кода&lt;/em&gt;&amp;nbsp;без перезапуска самой виртуальной машины. Когда говорят про
&lt;a href="/tag/erlang/"&gt;Erlang&lt;/a&gt;,&amp;nbsp;очень часто упоминают эту возможность как одно
из ключевых преимуществ платформы, так как она хорошо сочетается с её
системой легковесных не зависящих от ОС процессов и встроенного в
виртуальную машину эффективного хранилища данных в памяти (ETS). В мире
&lt;a href="/tag/java/"&gt;Java&lt;/a&gt; это тоже возможно, но используется намного реже и
позиционируется скорее как инструмент для отладки. В момент подмены кода
в работающей виртуальной машине языка программирования с точки зрения ОС
ничего не меняется: все открытые соединения, файловые дескрипторы и
выделенная оперативная память остаются за ней, то есть она выступает
своего рода посредником между одновременно загруженными двумя версиями
кода, одна из которых будет выгружена из памяти, как только закончит
свою работу и передаст все "дела" новой. Хотя это очень поверхностное
описание, на практике всплывает масса нюансов вроде миграции состояний
процессов в обе стороны, совместимости протоколов взаимодействия и пр.
Плановый перезапуск в данной схеме нужен лишь для обновления самой
виртуальной машины, что обычно требуется намного реже, чем обновление
кода приложения.&lt;/p&gt;
&lt;p&gt;Возможность горячей замены кода на уровне виртуальной машины, казалось
бы, выглядит очень привлекательно для разработки обсуждавшихся выше
инфраструктурных компонентов, от балансировщика нагрузки до различных
хранилищ данных, что позволило бы не терять регулярно в
производительности при обновлениях из-за сброса кэша и переустановки
сетевых соединений. Но в реальности таких продуктов можно пересчитать по
пальцам, почему? Все просто: удобство требует жертв - избегая
периодических провалов в производительности из-за минимизации
перезапусков процессов при обновлении, приходится проигрывать в
производительности постоянно по сравнению с нативным кодом. Для
инфраструктуры обычно оказывается приоритетнее постоянная
производительность, что практически по-умолчанию означает разработку на
одном из диалектов &lt;a href="/tag/c/"&gt;C/C++&lt;/a&gt;, где подобная схема с подменой кода
на лету хоть и возможна, но сложна в реализации ввиду отсутствия
популярных стабильных решений.&lt;/p&gt;
&lt;p&gt;Подводя итог: &lt;strong&gt;горячая замена кода - скорее удобство, чем жизненная
необходимость&lt;/strong&gt;. Удобство при разработке, позволяющее не
инициализировать программу заново при каждом изменении в коде. Удобство
при эксплуатации, позволяющее не терять текущее состояние в памяти и
минимизировать время простоя каждого отдельного компонента системы.
Удобство при поиске сложно воспроизводимых багов, так как есть
возможность на ходу загрузить отладочную &lt;em&gt;(debug)&lt;/em&gt; сборку на проблемной
боевой машине. Но многие проекты прекрасно себе живут и без всего этого,
стоит оно того или нет - сугубо индивидуальное решение.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Mon, 29 Apr 2013 10:47:00 +0400</pubDate><guid>tag:www.insight-it.ru,2013-04-29:theory/2013/goryachaya-zamena-koda/</guid><category>hot code replacement</category><category>hot code swapping</category><category>горячая замена кода</category><category>горячее обновление кода</category><category>инициализация</category><category>отладка</category><category>перезапуск</category><category>разработка</category><category>эксплуатация</category></item><item><title>Основы Erlang: синтаксис и пунктуация</title><link>https://www.insight-it.ru//erlang/2012/osnovy-erlang-sintaksis-i-punktuaciya/</link><description>&lt;p&gt;Мои теоретичесие рассуждения о &lt;a href="https://www.insight-it.ru/erlang/2012/erlang-v-internet-proektakh/"&gt;месте Erlang в &lt;del&gt;современном мире&lt;/del&gt; Интернете&lt;/a&gt;&amp;nbsp;Вы
можете почитать в отдельной статье. Если сомневаетесь интересно Вам это
все или нет - то прочтите сначала её. Сегодня я постараюсь вернуться с
небес на землю и пройтись по азам этого пугающего многих языка
программирования. Коротко и по делу.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Установка ничем особым не выделяется, дистрибутив рекомендую брать
&lt;a href="https://www.insight-it.ru/goto/767abd85/" rel="nofollow" target="_blank" title="https://www.erlang-solutions.com/downloads/download-erlang-otp"&gt;отсюда&lt;/a&gt;,
если до сих пор пользуетесь отсутствующей в списке ОС - лучше сначала
исправить этот факт.&lt;/p&gt;
&lt;p&gt;После установки в &lt;code&gt;$PATH&lt;/code&gt; окажутся исполняемые файлы:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;erl&lt;/strong&gt; - одновременно интерактивная консоль и запуск приложений;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;erlc&lt;/strong&gt; - компилятор в байт-код для виртуальной машины BEAM или
    нативный код посредством HiPE, напрямую использовать не придется
    практически.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Со всем что будет обсуждаться в этой статье можно эксперементировать
просто в интерактивной консоли, которая запускается просто командой
&lt;strong&gt;erl&lt;/strong&gt; без аргументов.&lt;/p&gt;
&lt;h2 id="punktuatsiia"&gt;Пунктуация&lt;/h2&gt;
&lt;p&gt;Сразу скажу, что пунктуация в Erlang довольно своеобразна, больше похожа
на русский язык, чем на другие языки программирования. По крайней мере я
именно этой ассоциацией пользовался, когда запоминал.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Все функции заканчиваются &lt;strong&gt;точкой&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;После каждого выражения в функции - &lt;strong&gt;запятая;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Все ветви кода &lt;code&gt;(case, if, ...)&lt;/code&gt;, кроме последней, заканчиваются
    &lt;strong&gt;точкой с запятой&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;После заголовка функции и условий ветвления пишется &lt;strong&gt;стрелка&lt;/strong&gt; &lt;code&gt;-&amp;gt;&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Маленькая демонстрация:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nf"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
  &lt;span class="nv"&gt;Z&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nv"&gt;X&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="nv"&gt;X&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;
    &lt;span class="nv"&gt;Y&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="nv"&gt;Z&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="nv"&gt;Y&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="n"&gt;true&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;
      &lt;span class="nv"&gt;Z&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt; &lt;span class="nv"&gt;Y&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;К слову, функции возвращают результат выполнения последнего выражения, в
данном случае оно представляет собой весь блок &lt;code&gt;if&lt;/code&gt;, а &lt;code&gt;end&lt;/code&gt;
обозначает его окончание (не функции).&lt;/p&gt;
&lt;h2 id="sintaksis"&gt;Синтаксис&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Foo&lt;/code&gt; - все что начинается с английской заглавной буквы -
    переменная, специально объявлять ничего не нужно&lt;/li&gt;
&lt;li&gt;&lt;code&gt;_&lt;/code&gt;&amp;nbsp;- сам знак нижнего подчеркивания и все что с него
    начинается - особый случай переменной, значение которой не значимо
    для программы и при первой возможности "выкидывается"&lt;/li&gt;
&lt;li&gt;Цифры в основном как обычно, есть научная нотация в духе &lt;code&gt;1.23e4&lt;/code&gt;
    (1.23 умножить на 10 в степени 4) и системы исчисления с другим
    основанием, скажем двоичная - &lt;code&gt;2#101010&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;foo&lt;/code&gt; - с строчной буквы начинаются &lt;em&gt;атомы&lt;/em&gt;, по сути константы,
    используются повсеместно:&lt;ul&gt;
&lt;li&gt;названия функций и модулей&lt;/li&gt;
&lt;li&gt;&lt;code&gt;true&lt;/code&gt; и &lt;code&gt;false&lt;/code&gt; - булевые значения&lt;/li&gt;
&lt;li&gt;&lt;code&gt;ok&lt;/code&gt; - типичный результат успешный результат выполнения&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;code&gt;?FOO&lt;/code&gt;&amp;nbsp;- хоть официально и называются константами, но по сути -
    макросы, перед компиляцией заменяются на заранее определенный кусок
    кода&lt;strong&gt;&amp;nbsp;&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;{foo, bar}&lt;/code&gt; - кортеж, набор данных фиксированной длины&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[foo, bar]&lt;/code&gt; - простой однонаправленный список произвольной длины&lt;/li&gt;
&lt;li&gt;&lt;code&gt;"foo"&lt;/code&gt; - текстовая строка, представленная в виде
    однонаправленного списка (что не эффективно с точки зрения
    потребления памяти, до 4 байт на символ)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&amp;lt;"foo"&amp;gt;&amp;gt;&lt;/code&gt; - бинарная строка, может содержать что угодно,
    в.т.ч. и текст; все что не цифры по возможности лучше хранить в этом
    типе данных.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sopostavlenie-pattern-matching"&gt;Сопоставление &lt;em&gt;(pattern matching)&lt;/em&gt;&lt;/h2&gt;
&lt;p&gt;Очень мощная концепция &lt;em&gt;сопоставления&lt;/em&gt; используется в &lt;strong&gt;Erlang&lt;/strong&gt; на
каждом углу. В базовом варианте работает примерно так:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;ok&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nv"&gt;Result&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;foo&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Если в функции foo все прошло нормально, то она возвращает, например
&lt;code&gt;{ok, 123}&lt;/code&gt;, и переменной &lt;code&gt;Result&lt;/code&gt; окажется лишь значение &lt;code&gt;123&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Если же возникла какая-то проблема, то она вернет что-то другое, скажем
&lt;code&gt;{error, timeout}&lt;/code&gt;, приложение столкнется с несоответствием левой и
правой части (атомы &lt;strong&gt;ok&lt;/strong&gt; и &lt;strong&gt;error&lt;/strong&gt; разные) и прекращает свое
выполнение (если бы было чего выполнять).&lt;/p&gt;
&lt;p&gt;Базовый принцип, надеюсь, понятен. Подобным образом выбирается какую из
реализаций функции использовать, в какую ветвь &lt;strong&gt;case&lt;/strong&gt; идти и т.п. В
общем есть много других более сложных применений, но о них в другой раз.&lt;/p&gt;
&lt;h2 id="spiski"&gt;Списки&lt;/h2&gt;
&lt;p&gt;Со списками есть три особые операции:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;[Head | Tail ] = [1, 2, 3, 4]&lt;/code&gt; - вытащить элемент с головы
    списка, работает по принципу сопоставления, в &lt;code&gt;Head&lt;/code&gt; окажется
    &lt;code&gt;1&lt;/code&gt;, а в &lt;code&gt;Tail&lt;/code&gt; - &lt;code&gt;[2, 3, 4]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[1, 2] ++ [3, 4]&lt;/code&gt; - конкатенация, результатом будет &lt;code&gt;[1, 2, 3, 4]&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;[N&amp;nbsp;*&amp;nbsp;N&amp;nbsp;|| N&amp;nbsp;&amp;lt;- [1,&amp;nbsp;2,&amp;nbsp;3], N &amp;gt; 1]&lt;/code&gt; - выглядит замороченно, по
    сути это обычный отображение &lt;em&gt;(map)&lt;/em&gt; с фильтрацией &lt;em&gt;(filter)&lt;/em&gt; - то
    есть выражение перед &lt;code&gt;||&lt;/code&gt; применяется к каждому элементу списка,
    значение которых попадает в переменную &lt;strong&gt;N&lt;/strong&gt;, а после запятой -
    условие, накладываемое на &lt;strong&gt;N&lt;/strong&gt;; таким образом результат будет &lt;strong&gt;[4,
    9]&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="binarnye-stroki"&gt;Бинарные строки&lt;/h2&gt;
&lt;p&gt;C ними намного больше всяких трюков и преобразований, приведу наиболее
значимые:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;Binary = &amp;lt;&amp;lt;Integer:64&amp;gt;&amp;gt;&lt;/code&gt; - преобразовать целое число Integer
    в бинарную строку Binary длиной 64 бита (для примера, может быть
    любой&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&amp;lt;Integer1:32, Integer2:32&amp;gt;&amp;gt; =&amp;nbsp;Binary&lt;/code&gt; - распокавать обратно
    бинарную строку в целые числа, но уже два по 32 бита; чем-то похоже
    на операцию &lt;code&gt;[H | T]&lt;/code&gt; у списков, но намного более гибко&lt;/li&gt;
&lt;li&gt;&lt;code&gt;Binary3 = &amp;lt;&amp;lt;Binary1/binary, Binary2/binary&amp;gt;&amp;gt;&lt;/code&gt; - конкатенация
    бинарных строк, результат окажется в &lt;code&gt;Binary3&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;&amp;lt; &amp;lt;&amp;lt;(N * N)/integer&amp;gt;&amp;gt; || &amp;lt;&amp;lt;N&amp;gt;&amp;gt; &amp;lt;= &amp;lt;&amp;lt;1, 2, 3&amp;gt;&amp;gt;, N &amp;gt; 1 &amp;gt;&amp;gt;&lt;/code&gt;&amp;nbsp;- аналог последнего примера для списков, только для
    бинарных данных; результат аналогичен - &lt;code&gt;&amp;lt;&amp;lt;4, 9&amp;gt;&amp;gt;&lt;/code&gt;; к слову
    официально это называется &lt;em&gt;binary comprehensions&lt;/em&gt;, а для списков -
    &lt;em&gt;list comprehensions&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="zakliuchenie"&gt;Заключение&lt;/h2&gt;
&lt;p&gt;Очень многое пришлось опустить, иначе самое главное затерялось бы, да и
объем статьи сильно вырос. Подробности всегда можно найти на
&lt;a href="https://www.insight-it.ru/goto/547f742d/" rel="nofollow" target="_blank" title="http://www.erlang.org/"&gt;официальном сайте&lt;/a&gt;, в man'ах, да и просто
погуглив.&amp;nbsp;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Удачного освоения Erlang!&lt;/em&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Fri, 22 Jun 2012 01:27:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-06-22:erlang/2012/osnovy-erlang-sintaksis-i-punktuaciya/</guid><category>Erlang</category><category>Программирование</category><category>разработка</category></item><item><title>Как работает epoll?</title><link>https://www.insight-it.ru//linux/2012/kak-rabotaet-epoll/</link><description>&lt;p&gt;Слово epoll сейчас определенно на слуху, в первую очередь благодаря
росту популярности неблокирующих HTTP-серверов. При этом мало кто
пытается разобраться в том, что, собственно, за ним стоит и почему
использующие этот механизм продукты, среди которых достойное место
занимают, например, &lt;a href="/tag/nginx/"&gt;nginx&lt;/a&gt;, &lt;a href="/tag/node-js/"&gt;node.js&lt;/a&gt; и
&lt;a href="/tag/tornado/"&gt;Tornado&lt;/a&gt;, так значительно выигрывают в
производительности у ближайших альтернатив. Хотите копнуть глубже?
&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="o-chem-poidet-rech"&gt;О чем пойдет речь?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;epoll&lt;/strong&gt; является масштабируемой &lt;em&gt;неблокирующей&lt;/em&gt; системой
    уведомления о собятиях ввода-вывода в &lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt;. В
    отличии от более старых механизмов, у epoll время срабатывания не
    зависит от количества открытых файловых дескрипторов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;epoll&lt;/strong&gt; используется для обработки событий &lt;em&gt;неблокирующих&lt;/em&gt;
    TCP-сокетов, операционная система оповещает приложение когда один из
    сокетов "под наблюдением" готов получить или отправить сообщение. В
    традиционном же подходе на каждый сокет выделяется поток выполнения
    (thread), который блокируется до возвращения обращения к
    соответствующему сокету.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="card blue lighten-4"&gt;
&lt;p&gt;&lt;div class="card-content"&gt;
Сразу хочу предупредить, хоть на практике
&lt;a href="/tag/epoll/"&gt;epoll&lt;/a&gt;&amp;nbsp;и&amp;nbsp;используется чаще, существуют и альтернативные
реализации схожего подхода, например &lt;a href="/tag/kqueue/"&gt;kqueue&lt;/a&gt; в BSD
системах. Конечные продукты обычно используют библиотеку, абстрагирующуе
низкоуровневые вызовы, наиболее
распросраненные -&amp;nbsp;&lt;a href="/goto/http://software.schmorp.de/pkg/libev.html"&gt;libev&lt;/a&gt;
и &lt;a href="https://www.insight-it.ru/goto/cd2ee101/" rel="nofollow" target="_blank" title="http://libevent.org/"&gt;libevent&lt;/a&gt;.
&lt;/div&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;h2 id="chto-eto-daet"&gt;Что это дает?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Не нужно впустую тратить &lt;em&gt;системные ресурсы&lt;/em&gt; на создание,
    уничтожение и поддержания пула потоков выполнения.&lt;/li&gt;
&lt;li&gt;Один системный процесс может поддерживать существенно большее
    &lt;em&gt;количество TCP-соединений.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Длительные соединения&lt;/em&gt;, по которым редко поступают сообщения, не
    держат заблокированный поток и потребляют минимум системных
    ресурсов.&lt;/li&gt;
&lt;li&gt;Отсутствие проблем с &lt;em&gt;синхронизацией&lt;/em&gt; пула потоков и доступом к
    общей памяти.&lt;/li&gt;
&lt;li&gt;Возможность (но не необходимость) без дополнительных сложностей
    держать в памяти процесса какое-то общее состояние, если приложение
    того требует.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="obratnaia-storona-medali"&gt;Обратная сторона медали&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Потоки выполнения в блокирующей модели имеют относительно короткий
    жизненный цикл и рано или поздно освобождают выделенную им память,
    процесс обработки неблокирующих соединений живет существенно дольше
    и намного более уязвим для &lt;em&gt;утечек памяти&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;Использование одного системного процесса без пула потоков выполнения
    ограничивает приложение &lt;em&gt;использованием лишь одного процессорного
    ядра&lt;/em&gt;, что делает такой подход менее пригодным для приложений, в
    значительной мере использующих вычислительные ресурсы. В большинстве
    же случаев приемлемым решением является запуск нескольких одинаковых
    копий приложения на одном сервере по количеству процессорных ядер.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Ошибки в коде&lt;/em&gt; могут негативно повлиять на работу всего процесса
    приложения, в то время как в блокирующей модели потоки выполнения
    обычно достаточно изолированы друг от друга.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="na-paltsakh"&gt;На пальцах&lt;/h2&gt;
&lt;p&gt;Вернемся к изначальному вопросу статьи: &lt;em&gt;Как работает epoll?&lt;/em&gt; Давайте
попробуем разобрать на простом примере.&lt;/p&gt;
&lt;p&gt;Представьте себе &lt;strong&gt;пиццерию&lt;/strong&gt; &lt;em&gt;(физический сервер)&lt;/em&gt;. &lt;strong&gt;Вы&lt;/strong&gt; &lt;em&gt;(приложение
или HTTP-сервер)&lt;/em&gt; получаете &lt;strong&gt;заказы&lt;/strong&gt; &lt;em&gt;(обращения на сокет, например
HTTP-запрос)&lt;/em&gt; на выпечку &lt;strong&gt;пиццы&lt;/strong&gt; &lt;em&gt;(ответы на обращение, например
HTML-документы).&lt;/em&gt; Есть два сценария, по которым можно их обрабатывать.&lt;/p&gt;
&lt;h3 id="blokiruiushchii-traditsionnyi"&gt;Блокирующий (традиционный)&lt;/h3&gt;
&lt;p&gt;Вы принимаете заказ, ставите пиццу в &lt;strong&gt;печь&lt;/strong&gt; &lt;em&gt;(системные ресурсы,
в.т.ч. оперативная память, необходимые для обработки запроса)&lt;/em&gt; и
непрерыано наблюдаете за тем как пицца печется. Как только пицца
готова - вы берете её и отдаете в руки &lt;strong&gt;заказчику&lt;/strong&gt; (источник заказа,
например браузер), после чего принимаете следующий заказ. При
необходимости можно нанять &lt;strong&gt;помощников&lt;/strong&gt; &lt;em&gt;(потоки выполнения,
threads)&lt;/em&gt;, чтобы следить за выпеканием пицц.&lt;/p&gt;
&lt;p&gt;Вы ограничены как количеством печей, так и количеством помощников,
которые могут поместиться в вашей пиццерии.&lt;/p&gt;
&lt;h3 id="neblokiruiushchii-epoll-i-analogi"&gt;Неблокирующий (epoll и аналоги)&lt;/h3&gt;
&lt;p&gt;Вы принимаете заказ, ставит пиццу в печь и ставите &lt;strong&gt;таймер&lt;/strong&gt;
&lt;em&gt;(операционная система посредством epoll)&lt;/em&gt;, чтобы узнать когда пицца
испечется. После чего Вы возвращаетесь к приему заказов. Как только
прозвенел таймер - Вы идете к соответствующей печи, достаете пиццу и
отдаете заказчику, после чего снова возвращаетесь к приему заказов.&lt;/p&gt;
&lt;p&gt;При таком подходе Вы ограничены лишь количеством печей и не нуждаетесь в
помощниках, хотя если срабатывает несколько таймеров одновременно могут
появлятся дополнительные задержки. В качестве бонуса легко готовить
пиццы, требующие длительного времени выпекания.&lt;/p&gt;
&lt;h2 id="zakliuchenie_1"&gt;Заключение&lt;/h2&gt;
&lt;p&gt;Как Вы уже догадались, цель этого поста не научить читателя работать с
&lt;strong&gt;epoll&lt;/strong&gt; напрямую или посредством распространенных библиотек (для
большинства веб-разработчиков это не нужно), а дать общее представление
о блокирующих и неблокирующих сокетах, принципах их работы и основных
отличиях. При выборе ключевых технологий и проектировании архитектуры
интернет-проекта эти вопросы определенно стоит иметь ввиду.&lt;/p&gt;
&lt;p&gt;Буду рад услышать дополнения и поправки в комментариях, &lt;a href="/feed/"&gt;до новых встреч&lt;/a&gt;!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Fri, 17 Feb 2012 16:27:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-02-17:linux/2012/kak-rabotaet-epoll/</guid><category>epoll</category><category>kqueue</category><category>Linux</category><category>sockets</category><category>разработка</category></item><item><title>Новое поколение MapReduce в Apache Hadoop</title><link>https://www.insight-it.ru//storage/2011/novoe-pokolenie-mapreduce-v-apache-hadoop/</link><description>&lt;p&gt;В большом бизнесе использование нескольких больших кластеров с
финансовой точки зрения более&amp;nbsp;эффективно, чем много маленьких. Чем
больше машин в кластере, тем большими наборами данных он может
оперировать, больше задач могут выполняться одновременно. Реализация
&lt;a href="/tag/mapreduce/"&gt;MapReduce&lt;/a&gt; в &lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt;
&lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt; столкнулась с потолком масштабируемости на уровне
около 4000 машин в кластере. Разрабатывается следующее поколение Apaсhe
Hadoop MapReduce, &amp;nbsp;в котором появится общий планировщик ресурсов и
отдельный мастер для каждой отдельной задач, управляющий выполнением
программного кода. Так как простой оборудования по техническим причинам
обходится дорого на таком масштабе, высокий уровень доступности
проектируется с самого начала, ровно как и безопасность и
многозадачность, необходимые для поддержки одновременного использования
большого кластера многими пользователями. Новая архитектура также будет
более инновационной, гибкой и эффективной с точки зрения использования
вычислительных ресурсов.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="predistoriia"&gt;Предистория&lt;/h2&gt;
&lt;p&gt;Текущая реализация Hadoop MapReduce устаревает на глазах. Основываясь на
текущих тенденциях в размерах кластеров и нагрузок на них, JobTracker
требует кардинальных доработок, чтобы исправить его дефекты в области
масштабируемости, потребления памяти, многопоточности, надежности и
производительности. С точки зрения работы с Hadoop при каждом обновлении
кластера (даже если это просто багфикс), абсолютно все компоненты
кластера, так и приложений, которые на нем работают, должны быть
обновлены одновременно. Это так же очень неудобно, так как каждый раз
необходимо тестировать все приложения на совместимость с новой версией.&lt;/p&gt;
&lt;h2 id="trebovaniia"&gt;Требования&lt;/h2&gt;
&lt;p&gt;Прежде чем кардинально что-то менять в Hadoop mapreduce, необходимо
понять какие же основные требования предъявляются к вычислительным
кластерам на практике. Наиболее значительными требованиями к Hadoop
следующего поколения являются:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Надежность&lt;/li&gt;
&lt;li&gt;Доступность&lt;/li&gt;
&lt;li&gt;Масштабируемость - кластеры из как минимум 10 тысяч машин, 200 тысяч
    вычислительных ядер и даже больше&lt;/li&gt;
&lt;li&gt;Обратная и прямая совместимость - возможность быть уверенным, что
    приложение будет работать на новой версии так же, как оно работало
    на старой&lt;/li&gt;
&lt;li&gt;Контроль над обновлениями&lt;/li&gt;
&lt;li&gt;Предсказуемые задержки&lt;/li&gt;
&lt;li&gt;Эффективное использование ресурсов&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Среди менее значительных требований:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Поддержка альтернативных парадигм разработки (помимо MapReduce)&lt;/li&gt;
&lt;li&gt;Поддержка сервисов с коротким жизненным циклом&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Если учесть перечисленные выше требования, то становится очевидно, что
инфраструктура обработки данных в Hadoop должна быть кардинальным
образом изменена. В сообществе Hadoop люди в целом приходят к общему
мнению, что текущая архитектура MapReduce не способна решить текущие
задачи, которые перед ней ставится, и что требуется кардинальный
рефакторинг кодовой базы.&lt;/p&gt;
&lt;h2 id="mapreduce-sleduiushchego-pokoleniia"&gt;MapReduce следующего поколения&lt;/h2&gt;
&lt;p&gt;Фундаментальной идеей смены архитектуры является разделение двух
основных функций JobTracker'а на два отдельных части:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;управление ресурсами;&lt;/li&gt;
&lt;li&gt;планирования и мониторинга задач.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;В итоге появляется несколько новых ролей:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ResourceManager&lt;/strong&gt; управляет глобальным распределением
    вычислительных ресурсов между приложениями;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ApplicationMaster&lt;/strong&gt; управляет планированием и координацией внутри
    приложения;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NodeManager&lt;/strong&gt; управляет процессами в рамках одной машины.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ApplicationMaster представляет собой библиотеку, с помощью которой можно
получить у ResourceManager квоту на вычислительные ресурсы и работать с
NodeManager(ами) для выполнения и мониторинга задач.&lt;/p&gt;
&lt;p&gt;ResourceManager поддерживает иерархическим очереди приложений, которым
может гарантированно выделяться некоторый процент ресурсов кластера. Его
функционал ограничивается планированием, никакого мониторинга и
отслеживания задач не происходит, а также нет никаких гарантий
перезапуска задач, провалившихся из-за проблем с оборудованием или
кодом. Планирование основывается на требованиях, которые выставляет
приложение с помощью ряда запросов ресурсов (среди них: запросы на
вычислительные ресурсы, память, дисковое пространство, сетевой доступ и
т.п.). Обратите внимание, что это значительное изменение по сравнению с
текущей моделью слотов фиксированного размера, которая является одной из
основных причин неэффективного использования ресурсов кластера на данный
момент.&lt;/p&gt;
&lt;p&gt;NodeManager - это агент, который работает на каждой машине и несет
ответственность за запуск контейнеров приложений, мониторинг
используемых ими ресурсов (плюс отчет планировщику).&lt;/p&gt;
&lt;p&gt;По одному ApplicationMaster запускается для каждого приложения, они
ответственны за запрос необходимых ресурсов у планировщика, запуск
задач, отслеживание статусов, мониторинг прогресса и обработку сбоев.&lt;/p&gt;
&lt;h2 id="arkhitektura"&gt;Архитектура&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Следующее поколение MapReduce" class="responsive-img" src="https://www.insight-it.ru/images/mapreduce-nextgen.jpg" title="Следующее поколение MapReduce"/&gt;&lt;/p&gt;
&lt;h2 id="uluchsheniia-po-sravneniiu-s-tekushchei-realizatsiei-mapreduce"&gt;Улучшения по сравнению с текущей реализацией MapReduce&lt;/h2&gt;
&lt;h3 id="masshtabiruemost"&gt;Масштабируемость&lt;/h3&gt;
&lt;p&gt;Разделение управления ресурсами и прикладными задачами позволяет
горизонтально расширять кластер более просто и эффективно. JobTracker
проводит значительную часть времени пытаясь управлять жизненным циклом
каждого приложения, что часто может приводить к различным
происшествиям - переход к отдельному менеджеру для каждого приложения
является значительным шагом вперед.&lt;/p&gt;
&lt;p&gt;Масштабируемость особенно важна в свете текущих трендов в оборудовании -
на данный момент Hadoop может быть развернут на кластере из 4000 машин.
Но 4000 средних машин 2009го года (т.е. по 8 ядер, 16Гб памяти, 4Тб
дискового пространства) только вдвое менее &amp;nbsp;ресурсоемки, чем 4000 машин
2011го года (16 ядер, 48гб памяти, 24Тб дискового пространства). Помимо
этого с точки зрения операционных издержек было выгоднее работать в еще
больших кластере от 6000 машин и выше.&lt;/p&gt;
&lt;h3 id="dostupnost"&gt;Доступность&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ResourceManager использует&amp;nbsp;&lt;a href="https://www.insight-it.ru/goto/e7095d3/" rel="nofollow" target="_blank" title="http://hadoop.apache.org/zookeeper/"&gt;Apache ZooKeeper&lt;/a&gt; для обработки сбоев.
    Когда ResourceManager перестает работать, аналогичный процесс может
    быстро запуститься на другой машине благодаря тому, что состояние
    кластера было сохранено в ZooKeeper. При таком сценарии все
    запланированные и выполняющиеся приложения максимум лишь
    перезапустятся.&lt;/li&gt;
&lt;li&gt;ApplicationMaster - поддерживается создание точек восстановления на
    уровне приложений. ApplicationMaster может восстановить работу из
    состояния, сохраненного в HDFS, в случае сбоя.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="sovmestimost-protokola"&gt;Совместимость протокола&lt;/h3&gt;
&lt;p&gt;Это позволит различным версиям клиентов и серверов Hadoop общаться между
собой. Помимо решения многих существующих проблем с обновлением, в
будующих релизах появится возможность последовательного обновления кода
без простоя системы в целом - очень большое достижения с точки зрения
системного администрирования.&lt;/p&gt;
&lt;h3 id="innovatsionnost-i-gibkost"&gt;Инновационность и гибкость&lt;/h3&gt;
&lt;p&gt;Основным плюсом предложенной архитектуры является тот факт, что
MapReduce по сути становится просто пользовательской библиотекой.
Вычислительная же система (ResourceManager и NodeManager) становятся
полностью независимыми от специфики MapReduce.&lt;/p&gt;
&lt;p&gt;Клиенты получат возможность одновременного использования разных версий
MapReduce в одном и том же кластере. Это становится тривиальным, так как
отдельная копия ApplicationMaster'а запускается для каждого приложения.
Это дает гибкость в исправлении багов, улучшений и новых возможностей,
так как полное обновление кластер перестает быть обязательной
процедурой. Это позволяет клиентам обновлять их приложения до новых
версий MapReduce вне зависимости от обновлений кластера.&lt;/p&gt;
&lt;h3 id="effektivnost-ispolzovaniia-vychislitelnykh-resursov"&gt;Эффективность использования вычислительных ресурсов&lt;/h3&gt;
&lt;p&gt;ResourceManager использует общую концепцию для управления ресурсами и
планирования по отношению к каждому конкретному приложению. Каждая
машина в кластере на концептуальном уровне рассматривается просто как
набор ресурсов: память, процессор, ввод-вывод и др. Все машины
взаимозаменяемы и приложение может быть назначено на любую из них,
основываясь на доступных и запрашиваемых ресурсах. При этом приложения
работают в контейнерах, изолированно от других приложений, что дает
сильную поддержку многозадачности.&lt;/p&gt;
&lt;p&gt;Таким образом эта схема избавляет от текущего механизма map и reduce
слотов в Hadoop, который негативно влияет на эффективную утилизацию
вычислительных ресурсов.&lt;/p&gt;
&lt;h3 id="podderzhka-drugikh-paradigm-programmirovaniia-pomimo-mapreduce"&gt;Поддержка других парадигм программирования помимо MapReduce&lt;/h3&gt;
&lt;p&gt;В предложенной архитектуре используется общий механизм вычислений, не
привязанный конкретно к MapReduce, что позволит использовать и другие
парадигмы. Имеется возможность реализовать собственный
ApplicationMaster, способный запрашивать ресурсы у ResourceManager и
использовать их в соответствии с задачей, при этом сохраняются общие
принципы изоляции и гарантированного наличия полученных ресурсов. Среди
потенциально поддерживаемых парадигм можно назвать MapReduce, MPI,
Мaster-Worker, итеративные модели. Все они могут одновременно работать
на одном и том же кластере. Это особенно актуально для приложений
(например К-средний или Page Rank), где &lt;a href="https://www.insight-it.ru/python/2011/piccolo-postroenie-raspredelennykh-sistem-v-11-raz-bystree-hadoop/"&gt;другие подходы более чем на порядок эффективнее&lt;/a&gt; MapReduce.&lt;/p&gt;
&lt;h2 id="vyvody_1"&gt;Выводы&lt;/h2&gt;
&lt;p&gt;Apache Hadoop, и в частности Hadoop MapReduce - очень успешный
opensource проект по обработке больших объемов данных. Предложенный
Yahoo путь его переработки направлен на исправление недостатков
архитектуры текущей реализации, при этом повышая доступность,
эффективность использования ресурсов и предоставляя поддержку других
парадигм распределенных вычислений.&lt;/p&gt;
&lt;p&gt;Осталось дело за малым - собственно реализовать задуманное! :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.insight-it.ru/goto/336fc03c/" rel="nofollow" target="_blank" title="http://developer.yahoo.com/blogs/hadoop/posts/2011/02/mapreduce-nextgen/"&gt;Источник информации&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="/feed/"&gt;Подписаться на RSS можно здесь.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sat, 19 Feb 2011 21:23:00 +0300</pubDate><guid>tag:www.insight-it.ru,2011-02-19:storage/2011/novoe-pokolenie-mapreduce-v-apache-hadoop/</guid><category>Apache</category><category>Apache Hadoop</category><category>Hadoop</category><category>архитектура</category><category>кластер</category><category>кластеризация</category><category>кластерные вычисления</category><category>Масштабируемость</category><category>разработка</category><category>технологии</category></item><item><title>Инструменты для минимизации размера изображений</title><link>https://www.insight-it.ru//frontend/2011/instrumenty-dlya-minimizacii-razmera-izobrazhenijj/</link><description>&lt;p&gt;В то время как масштабируемость серверной части интернет проекта -
сложное дело, требующее тщательного планирования, большинству сайтов
можно обойтись существенно более простыми способами для повышения
визуального быстродействия с точки зрения пользователей. О небольшой
части из них я и хотел Вам сегодня рассказать.
&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="motivatsiia"&gt;Мотивация&lt;/h2&gt;
&lt;p&gt;Если воспользоваться инструментами для анализа времени загрузки страницы
(например Firebug или Chrome Developer Tools), то не сложно обратить
внимание на тот факт, что во многих случаях существенную часть ожидания
загрузки страницы проходит в процессе загрузки внешних файлов, требуемых
для рендеринга страницы:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Изображения&lt;/li&gt;
&lt;li&gt;Файлы стилей&lt;/li&gt;
&lt;li&gt;Файлы JS-скриптов&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;На этот интервал времени абсолютно никак не влияет используемый язык
программирования и баз данных, основных способов повлиять на него в
меньшую сторону несколько:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Вынести на отдельный (под)домен (позволяет браузеру качать больше
    файлов одновременно)&lt;/li&gt;
&lt;li&gt;Отредактировать HTML для избежания блокировок (так называемого
    "водопада")&lt;/li&gt;
&lt;li&gt;Настроить HTTP-сервер на предмет правильных заголовков Expires и
    Etags&lt;/li&gt;
&lt;li&gt;Воспользоваться для отдачи статики nginx или аналогом&lt;/li&gt;
&lt;li&gt;Сменить интернет-канал у сервера или сам сервер&lt;/li&gt;
&lt;li&gt;Воспользоваться услугами CDN (Content Delivery Network)&lt;/li&gt;
&lt;li&gt;Уменьшить размер передаваемых файлов&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Сейчас я хочу остановиться на последнем пункте в отношении изображений,
про скрипты, стили и остальные методы стоит поговорить отдельно в другой
раз.&lt;/p&gt;
&lt;h2 id="vybor-pravilnogo-formata-izobrazhenii"&gt;Выбор правильного формата изображений&lt;/h2&gt;
&lt;p&gt;Первым шагом по снижению объемов изображений должен быть выбор
адекватного назначению изображения формата:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;JPEG&amp;nbsp;- для всех фотографий&lt;/li&gt;
&lt;li&gt;GIF&amp;nbsp;- исключительно для анимации (например для крутящейся загрузки)&lt;/li&gt;
&lt;li&gt;PNG - для всего, что не является фотографией или анимацией: иконки,
    графики, элементы интерфейса&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="gif"&gt;GIF&lt;/h2&gt;
&lt;p&gt;На многих сайтах до сих пор по старинке используется этот формат
изображений, не смотря на то, что PNG при таком же качестве имеет
меньший размер файлов.&lt;/p&gt;
&lt;p&gt;Рецепт лежит на поверхности: конвертируйте все GIF в PNG. Проще всего
это сделать с помощью &lt;a href="https://www.insight-it.ru/goto/71cf44a6/" rel="nofollow" target="_blank" title="http://www.imagemagick.org/"&gt;ImageMagick&lt;/a&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# Конкретный файл&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;convert foo.gif foo.png

&lt;span class="c"&gt;# Все файлы в директории&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;mogrify -format png *.gif

&lt;span class="c"&gt;# Или&amp;nbsp;OptiPNG:&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;optipng *.gif
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Дальше все просто: работаем с этими изображениями как и с остальными
PNG, о чем пойдет речь ниже.&lt;/p&gt;
&lt;h2 id="png"&gt;PNG&lt;/h2&gt;
&lt;p&gt;К сожалению, многие редакторы изображений сохраняют PNG-файлы совершенно
не заботясь об их размере.&lt;/p&gt;
&lt;p&gt;Но за многие годы была разработана масса различных утилит, исправляющих
данную ситуацию. Основных принципа, на которых они основываются, четыре:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Удаление лишнего:&lt;/strong&gt; так как PNG - расширяемый формат, далеко не
    все данные и заголовки требуются для отображения изображения в
    браузере. Их можно смело выкинуть.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Изменение типа PNG:&lt;/strong&gt; использование только оттенков серого или
    произвольной палитры приемлемо для многих случаев, что по сравнению
    с полной гаммой существенно снижает размер изображения&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Использование подходящего "фильтра":&lt;/strong&gt; они являются шагом перед
    сжатием изображения, правильный фильтр позволяет компрессии работать
    эффективнее&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Оптимизация самой компрессии:&lt;/strong&gt; использование более эффективного
    алгоритма&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Примеры использования наиболее эффективных инструментов:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# optipng&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;optipng -o7 foo.png

&lt;span class="c"&gt;# pngcrush&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;pngcrush -rem alla -brute -reduce foo.png foo.png.temp
&lt;span class="nv"&gt;$ &lt;/span&gt;mv foo.png.temp foo.png

&lt;span class="c"&gt;# pngout&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;pngout foo.png

&lt;span class="c"&gt;# advpng&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;advpng -z4 foo.png
&lt;/pre&gt;&lt;/div&gt;
&lt;h2 id="jpeg"&gt;JPEG&lt;/h2&gt;
&lt;p&gt;В отличии от PNG и GIF каждое сохранение JPEG файла приходят к потерям
данных и, как следствие, снижению качества фотографии, без потерь могут
выполняться только изменение комментариев, метаданных и повороты на
90/180/270 градусов. Основным инструментом для минимизации JPEG без
потери качества является &lt;a href="https://www.insight-it.ru/goto/4ee62c2b/" rel="nofollow" target="_blank" title="http://www.phpied.com/installing-jpegtran-mac-unix-linux/"&gt;jpegtran&lt;/a&gt;, используется достаточно просто:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;# обычный режим&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;jpegtran -copy none source.jpg &amp;gt; destination.jpg

&lt;span class="c"&gt;# режим progressive&lt;/span&gt;
&lt;span class="nv"&gt;$ &lt;/span&gt;jpegtran -copy none -progressive source.jpg &amp;gt; destination.jpg
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Прогрессивный режим заслуживает отдельного внимания:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Основная особенность - в нормальных браузерах (не IE) такой JPEG
    быстро отображается в низком качестве, а по мере загрузки файла
    полностью качество изображения улучшается (обычный JPEG грузится
    сверху вниз)&lt;/li&gt;
&lt;li&gt;По объему файла этот тип JPEG начинает выигрывать у обычного начиная
    от размера файла в 10Кб&lt;/li&gt;
&lt;li&gt;Изображение менее 10Кб все равно слишком маленькое, чтобы от самого
    процесса прогрессивной загрузки был какой-либо толк&lt;/li&gt;
&lt;li&gt;Если хочется подробнее разобраться - читаем
    &lt;a href="https://www.insight-it.ru/goto/85664134/" rel="nofollow" target="_blank" title="http://yuiblog.com/blog/2008/12/05/imageopt-4/"&gt;здесь&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="zakliuchenie"&gt;Заключение&lt;/h2&gt;
&lt;p&gt;Использование простых инструментов, описанных выше, позволяет сократить
общий размер используемых на веб-странице изображений порой до 30%, а то
и больше. Эффект, который дает этот процесс, конечно же зависит от
"запущенности" ситуации, но в большинстве случаев тоже измеряется
десятками процентов от общего времени загрузки страницы. Чтобы
воспользоваться ими требуется всего несколько минут, что существенно
меньше, чем попытки оптимизировать код или запросы к базе данных, не
говоря уже о полной переработке архитектуры системы.&lt;/p&gt;
&lt;p&gt;Если кто-то знает более эффективные приемы по уменьшению размеров
изображений - прошу в комментарии. Про скрипты и стили поговорим
отдельно :)&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Основным источником информации послужила &lt;a href="https://www.insight-it.ru/goto/54bb0fc6/" rel="nofollow" target="_blank" title="http://www.phpied.com/big-list-image-optimization-tools/"&gt;статья Stoyan Stefanov&lt;/a&gt;,
которую я сильно подсократил до тех инструментов, которыми пользуюсь сам
на практике, и моментов, которые считаю интересными. Желающим покопаться
в этой тематике поглубже рекомендую изучить весь его блог - можно найти
много интересного. Про &lt;a href="/feed/"&gt;подписку на Insight IT&lt;/a&gt; тоже не
забываем)&lt;/em&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sun, 13 Feb 2011 10:44:00 +0300</pubDate><guid>tag:www.insight-it.ru,2011-02-13:frontend/2011/instrumenty-dlya-minimizacii-razmera-izobrazhenijj/</guid><category>gif</category><category>ImageMagick</category><category>jpeg</category><category>jpegtran</category><category>optipng</category><category>png</category><category>изображение</category><category>инструменты</category><category>клиентская оптимизация</category><category>компрессия</category><category>оптимизация</category><category>разработка</category><category>утилиты</category></item><item><title>Piccolo - построение распределенных систем в 11 раз быстрее Hadoop</title><link>https://www.insight-it.ru//python/2011/piccolo-postroenie-raspredelennykh-sistem-v-11-raz-bystree-hadoop/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/20aba73a/" rel="nofollow" target="_blank" title="http://piccolo.news.cs.nyu.edu/"&gt;Piccolo&lt;/a&gt; - это система для
распределенных вычислений, использующая новую ориентированную на данные
модель программирования для разработки приложений по параллельным
вычислениям в памяти в масштабах дата-центров. В отличии от существующих
моделей, основывающихся на &lt;em&gt;потоках&lt;/em&gt; данных, Piccolo позволяет
вычислениям выполняться на различных машинах, при этом имея общее
изменяющееся состояния через интерфейс таблиц пар "ключ-значение".
Традиционные ориентированные на данные модели (такие как используются в
&lt;a href="/tag/hadoop/"&gt;Apache Hadoop&lt;/a&gt;) предоставляют пользователю для работы
лишь единственный объект в определенный момент времени, когда в Piccolo
используется глобальная таблица состояний, одновременно доступная для
всех частей вычисления. Это позволяет пользователям указывать алгоритм
вычисления в интуитивно-понятной манере, очень похожей на разработку
программ для одного компьютера.&lt;!--more--&gt;&lt;/p&gt;
&lt;p&gt;Использование хранилища, позволяющего хранить в памяти пары
"ключ-значение", сильно отличается от канонического подхода
&lt;a href="/tag/mapreduce/"&gt;map-reduce&lt;/a&gt;, который основан на распределенных
файловых системах. Результаты впечатляют:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Эксперименты показали, что Piccolo очень быстр и отличные возможности
по масштабируемости для многих прикладных задач. Производительность
вычисления PageRank и k-средних выросла в 11 и 4 раза, соответственно,
по сравнению с Hadoop. Вычисление PageRank для связанного графа из 1
миллиарда страниц заняло лишь 70 секунд на 100 машинах в &lt;a href="/tag/ec2/"&gt;Amazon
EC2&lt;/a&gt;. Распределенная система по скачиванию веб-страниц
легко может полностью загрузить 100Мбит интернет-канал при работе на
12 машинах.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;При разработке на Piccolo программисты создают наборы прикладных
функций, которые принято называть ядром. Функции ядра запускаются
параллельно на нескольких вычислительных узлах, при этом у них есть
доступ к общему изменяемому состоянию, которое реализовано в виде набора
таблиц, располагающихся в оперативной памяти различных узлов системы.
Для доступа к этому состоянию используется примитивный интерфейс,
позволяющий узнать &lt;em&gt;(get)&lt;/em&gt; и изменить &lt;em&gt;(put)&lt;/em&gt; то или иное состояние.
Процесс отправки сообщений удаленным узлам, непосредственно имеющим в
памяти требуемые данные, полностью берет на себя сам код Piccolo.&lt;/p&gt;
&lt;p&gt;Предоставляя разработчикам доступ к глобальному общему состоянию,
Piccolo предлагает несколько привлекательных возможностей:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Алгоритмы, основанные на общем промежуточном состоянии, могут быть
    реализованы естественным, логичным и эффективным образом&lt;/li&gt;
&lt;li&gt;Асинхронные online приложения получают возможность иметь
    &lt;em&gt;оперативный&lt;/em&gt; доступ к новым и изменившимся данным, расположенным на
    других узлах системы&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;В Piccolo используется ряд оптимизаций, обеспечивающий не только удобное
использование интерфейса к таблице состояний, но и его быстроту:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Локальность&lt;/strong&gt; - для обеспечения выполнения локальности исполнения,
    таблицы явным образом разбиваются на части, располагающиеся на
    разных машинах. В пользовательском коде при взаимодействии с
    таблицами доступна настройка локальности, обеспечивающая выполнение
    кода на том же узле, где располагаются даннын.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Балансировка нагрузки&lt;/strong&gt; - далеко не вся нагрузка равномерна, часто
    какая-то часть вычислений требует намного больше ресурсов, чем все
    остальные. Ожидание без дела пока такая задача будет выполнена
    впустую тратит ценное время и ресурсы. Для решения данной проблемы
    Piccolo может мигрировать часть задач с загруженных машин на
    простаивающие, при этом сохраняя настройки локальности и
    корректность выполнения программы.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Обработка сбоев&lt;/strong&gt; - сбои оборудования неизбежны и обычно они
    случаются в самые критические моменты. Piccolo делает создание
    контрольных точек и восстановление простым и быстрым, обеспечивая
    быстрое восстановление в случае сбоев.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Синхронизация&lt;/strong&gt; - управление корректной синхронизацией и
    обновлениями в условиях распределенной системы может быть сложным и
    медленным. Piccolo позволяет пользователям поручить реализацию
    логики синхронизации системе. Вместо явной блокировки таблиц при
    выполнении обновлении данных, пользователи могут присоединять
    аккумулирующие функции к таблицам: они используются автоматически
    системой для корректного комбинирования параллельных обновлений
    ячеек таблиц.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Проект реализован в виде библиотеки для &lt;a href="/tag/python/"&gt;Python&lt;/a&gt; и
&lt;a href="/tag/c/"&gt;C++&lt;/a&gt;. Более детально примеры использования и принципы работы
системы разбираются в источниках информации (правда на английском), не
поленитесь - загляните. Вместо заключения хотелось бы по традиции
порекомендовать подписаться на &lt;a href="/feed/"&gt;RSS блога&lt;/a&gt;, если Вы еще этого не
сделали.&lt;/p&gt;
&lt;h3 id="istochniki-informatsii"&gt;Источники информации&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/1ccc4a5b/" rel="nofollow" target="_blank" title="http://www.cs.nyu.edu/~power/"&gt;Russell Power&lt;/a&gt; - автор проекта Piccolo&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/9d1ef591/" rel="nofollow" target="_blank" title="http://www.usenix.org/event/osdi10/tech/full_papers/Power.pdf"&gt;Piccolo: Building Fast, Distributed Programs with Partitioned Tables&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Проект был презентован на&amp;nbsp;&lt;a href="https://www.insight-it.ru/goto/5b92a3e0/" rel="nofollow" target="_blank" title="http://www.usenix.org/event/osdi10/tech/"&gt;OSDI10&lt;/a&gt;:&amp;nbsp;&lt;a href="https://www.insight-it.ru/goto/389782f7/" rel="nofollow" target="_blank" title="https://docs.google.com/viewer?url=http%3A%2F%2Fwww.usenix.org%2Fevent%2Fosdi10%2Ftech%2Fslides%2Fpower.pdf"&gt;презентация&lt;/a&gt; и&amp;nbsp;&lt;a href="https://www.insight-it.ru/goto/90a31eff/" rel="nofollow" target="_blank" title="http://piccolo.news.cs.nyu.edu/osditalk.mp4"&gt;видео&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sat, 12 Feb 2011 23:49:00 +0300</pubDate><guid>tag:www.insight-it.ru,2011-02-12:python/2011/piccolo-postroenie-raspredelennykh-sistem-v-11-raz-bystree-hadoop/</guid><category>C++</category><category>piccolo</category><category>Python</category><category>вычисления</category><category>Масштабируемость</category><category>разработка</category><category>распределенные вычисления</category></item><item><title>HighLoad++ 2010</title><link>https://www.insight-it.ru//event/2010/highload-2010/</link><description>&lt;p&gt;&lt;img alt="HighLoad++ Logo" class="left" src="https://www.insight-it.ru/images/highload-conference-logo.png" title="HighLoad++ Logo"/&gt;
25-26 октября прошла конференция &lt;a href="https://www.insight-it.ru/goto/727c9436/" rel="nofollow" target="_blank" title="http://www.highload.ru"&gt;HighLoad++ 2010&lt;/a&gt;,
посвященная разработке высоконагруженных систем. После конференции у
меня сразу родились планы на два поста: типичный отчет и описание
архитектуры Вконтакте. С порядком написания я, видимо, не прогадал -
получился один из самых успешных постов на &lt;strong&gt;Insight IT&lt;/strong&gt;. Остальные
доклады на мероприятии были, пожалуй, существенно менее животрепещущими
для общественности, но все же не менее интересными.
Приступим.&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="organizatsionnye-momenty"&gt;Организационные моменты&lt;/h2&gt;
&lt;p&gt;Прежде чем переходить собственно к рассказу о докладах, хочется сразу
высказаться по организационным вопросам, чтобы далее не отвлекаться.
Возможно организаторы учтут при проведении последующих мероприятий.&lt;/p&gt;
&lt;p&gt;Во-первых, участие в конференции: цены конечно не самые высокие для
двухдневных конференций, но все равно слегка зашкаливают - лично я бы не
пошел на данное мероприятие за такие деньги, даже не смотря на то что
тематика полностью совпадает со сферой моих профессиональных интересов.
За кого-то заплатил работодатель, а мне вот пришлось доставать
бесплатное участие через знакомых знакомых... &lt;em&gt;(спасибо добрым людям,
если вдруг читают :) )&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Во-вторых, удивила ситуация со связью со внешним миром: интернет был на
очень хорошем для конференций уровне - тупил местами, но в целом
стабильно работал, а вот мобильная связь не работала практически
совсем - уезжал домой с почти севшим телефоном.&lt;/p&gt;
&lt;p&gt;Политика организовывать не ставить два потенциально интересных доклада
параллельно меня очень порадовал - послушал в живую все, что хотел. А
небольшая давка в первом зале в начале первого дня мне кажется была
очень даже справедливой платой за отсутствие необходимости разрываться
на части.&lt;/p&gt;
&lt;p&gt;С едой все было в порядке, очереди конечно великоваты не смотря на два
обеда в разное время, но всегда можно было обойти данное неудобство
(перейти в другой "раздаточный пункт" или залезть на сцену, хоть и не
разрешали).&lt;/p&gt;
&lt;p&gt;Еще очень порадовало, что презентации первого дня конференции были уже
доступны участникам еще за пару часов до окончания первого дня. Но вот с
оставшимися презентациями и видео с мероприятия видимо произошла
какая-то заминка и я так и не получил ссылку на них до сих пор, судя по
всему они так и не доступны.&lt;/p&gt;
&lt;h2 id="den-pervyi"&gt;День первый&lt;/h2&gt;
&lt;p&gt;Основной особенностью первого дня было выделение целого зала под
англоязычные доклады зарубежных коллег. Как я уже писал, желающих
послушать иностранцев, было очень много - и в первой половине дня люди
толпились чуть ли не в коридоре, но ближе к вечеру ситуация
стабилизировалась.&lt;/p&gt;
&lt;p&gt;После приветственного слова Олега Бунина (одного из основных
организаторов конференции) слово взял &lt;a href="https://www.insight-it.ru/goto/c9ed5ba0/" rel="nofollow" target="_blank" title="http://www.timetobleed.com"&gt;Joe
Damato&lt;/a&gt;, которого позиционировали как
известного хакера, активно работающего над развитием &lt;a href="/tag/ruby/"&gt;Ruby&lt;/a&gt;.
Темой выступления был обзор различных инструментов и приемов для анализа
ситуации в серверном &lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt;-окружении. Некоторые моменты
были мне известны и ранее, но в целом больше половины доклада было для
меня очень интересно и ново. Перечислять упомянутые им приемы я, честно
говоря, не вижу смысла - будет просто дублирование презентации. Если
ранжировать доклады первого дня по интересу лично для меня, то это
выступление заняло бы, пожалуй, второе место.&lt;/p&gt;
&lt;p&gt;Вторым докладчиком был также приверженец секты Рубистов, &lt;a href="https://www.insight-it.ru/goto/6a62c9ef/" rel="nofollow" target="_blank" title="http://jamesgolick.com/"&gt;James
Golick&lt;/a&gt;, один из основателей социальной сети
для фетишистов (простите за отсутствие ссылки). Основной фишкой доклада
было "разоблачение мифов", в частности об облачных вычислениях и NoSQL.
Количество пользователей этой социальной сети, но они очень активны и
генерируют достаточно много контента (особенно по Российским меркам).
Проект изначально располагался в компании, которая предоставляла услуги
managed hosting (хостинг на арендуемых серверах + за тебя
администрируют), но они посчитали, что слишком много переплачивают за
этот самый "managed", и решили поддаться тренду и переехать в облако
(&lt;a href="/tag/amazon/"&gt;Amazon&lt;/a&gt; &lt;a href="/tag/ec2/"&gt;EC2&lt;/a&gt;). По деньгам получилось не сильно
дешевле, но больше всего из расстроила производительность виртуальных
машин (кажется, был слайд со скоростью доступа к дисковой подсистеме,
выставляющий облако не в лучшем свете). Второй эпопеей в их проекте были
попытки оптимизировать подсистему хранения данных путем перенесения ее
части в NoSQL хранилище: пробовали &lt;a href="/tag/mongodb/"&gt;MongoDB&lt;/a&gt; (выкинули
из-за блокировок на операциях удаления) и &lt;a href="/tag/cassandra/"&gt;Cassandra&lt;/a&gt;
(выкинули из-за медленного случайного чтения). Финальным решением стал
&lt;a href="/tag/redis/"&gt;Redis&lt;/a&gt; + &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;, просто и со вкусом - их
всецело устраивает на данный момент, как я понял.&lt;/p&gt;
&lt;p&gt;Третьим выступал &lt;a href="https://www.insight-it.ru/goto/aab04203/" rel="nofollow" target="_blank" title="http://www.facebook.com/robert"&gt;Robert Johnson&lt;/a&gt; из
&lt;a href="/tag/facebook/"&gt;Facebook&lt;/a&gt;, доклад был практически таким же, как и в
ГУ-ВШЭ за несколько дней до этого - о нем &lt;a href="https://www.insight-it.ru/event/2010/facebook-how-we-scaled-to-500-000-000-users-by-robert-johnson/"&gt;я уже
писал&lt;/a&gt;,
так что подробно останавливаться не буду. Основным отличием были
дополнительные технические детали, но подавляющее большинство из них и
так уже были описаны в статье &lt;a href="https://www.insight-it.ru/highload/2010/arkhitektura-facebook/"&gt;"Архитектура
Facebook"&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;После обеда выступал Patrice Pelland из &lt;a href="/tag/microsoft/"&gt;Microsoft&lt;/a&gt;,
доклад&amp;nbsp; был о том, как работают их облачные сервисы (видимо live,
skydrive и прочие). Естественно все на их же продуктах, большинство
названий я даже не слышал. Единственное, что запомнил из выступления - у
мелкомягких есть даже клон &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;, но с какими-то
дополнительными плюшками. Это был единственный доклад, после которого
никто не захотел задать даже одного вопроса, что в целом наглядно
продемонстрировало незаинтересованность аудитории в платных решениях. В
твиттере после этого выступления проскользнула обиженная фраза
докладчика, что-то в духе: "До них просто не дошло, о чем я говорил".&lt;/p&gt;
&lt;p&gt;После этого недоразумения от MS началась длинная серия докладов от
людей, причастных к созданию &lt;a href="/tag/postgresql/"&gt;PostgreSQL&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Simon Riggs из &lt;a href="https://www.insight-it.ru/goto/8078c405/" rel="nofollow" target="_blank" title="http://www.2ndquadrant.com/"&gt;2nd Quadrant&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Robert Treat из &lt;a href="https://www.insight-it.ru/goto/556109e4/" rel="nofollow" target="_blank" title="http://www.omniti.com"&gt;Omni TI&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Bruce Momjian из &lt;a href="https://www.insight-it.ru/goto/37e2eb7f/" rel="nofollow" target="_blank" title="http://www.enterprisedb.com/"&gt;EnterpriseDB&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Было 5 выступлений о PostgreSQL подряд:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Повышение производительности&lt;/li&gt;
&lt;li&gt;Управление репликацией&lt;/li&gt;
&lt;li&gt;Масштабирование&lt;/li&gt;
&lt;li&gt;Быстрая смена версии средствами pg_update&lt;/li&gt;
&lt;li&gt;Потоковая репликация&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;В целом очень актуальные доклады, если Вы плотно работаете с PostgreSQL
в своем проекте или на своей работе. Я вообще тоже когда стоит выбор
между доступными реляционными СУБД чаще всего склоняюсь к PostgreSQL, но
доклады были детализированными не там, где нужно, и было скучновато. В
этой секции порадовали три вещи:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;очень качественный английский у докладчиков&lt;/li&gt;
&lt;li&gt;забавная манера выступления Роберта, особенно про красные кроки
    (что-то типа галош)&lt;/li&gt;
&lt;li&gt;активная реклама новых вкусностей PostgreSQL 9.0, релиз которой я по
    каким-то причинам проворонил - надо будет обязательно попробовать ее
    в деле&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;После кофе-брейка я пошел на больше всего понравившийся мне доклад (за
первый день) - выступал &lt;a href="https://www.insight-it.ru/goto/217e612/" rel="nofollow" target="_blank" title="http://www.phpied.com/"&gt;Stoyan Stefanov&lt;/a&gt; из
Yahoo! Темой доклада была заявлена неочевидная формулировка "Progressive
Downloads and Rendering", хотя на самом деле все свелось к грамотно
построенному докладу о клиентской оптимизации: несколько вводных
картинок, один слайд с базовыми приемами и много-много примеров
очевидных и не очень случаев, когда с точки зрения пользователя сайт
начинает тупить, даже если серверная часть проекта написано грамотно и
работает достаточно быстро. По некоторым аспектам, в частности про
кроссбраузерному использованию data:URL+MHTML, он ссылался на русские
источники, а также очень позитивно отзывался о &lt;a href="https://www.insight-it.ru/goto/209c3c57/" rel="nofollow" target="_blank" title="http://sunnybear.moikrug.ru/"&gt;Николае
Мациевском&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Последним, что я посетил в первый день, была "открытая встреча" c James
Golick и Joe Damato про сам &lt;a href="/tag/ruby/"&gt;Ruby&lt;/a&gt;. Ожидал большего: в итоге
Joe вообще не выступил, а большая часть времени ушла на разжёвывание
базовых возможностей языка и несколько мелких холиваров.&lt;/p&gt;
&lt;h2 id="den-vtoroi"&gt;День второй&lt;/h2&gt;
&lt;p&gt;На второй день я немного проспал и приехал ближе к концу первого
доклада: оказалось, что я не один такой - людей было раза в три меньше,
чем за день до этого. Выбор потока куда пойти был легок: в первом зале
все утро было посвящено &lt;a href="/tag/python/"&gt;Python&lt;/a&gt;, с которым я последнее
время довольно плотненько работал.&lt;/p&gt;
&lt;p&gt;После докладов на английском "отечественные" выступления смотрелись
совсем блекло. Конец выступления Андрея Смирнова про
&lt;a href="/tag/twisted/"&gt;Twisted&lt;/a&gt; не принес мне хоть какой-либо полезной
информации, тем более мне все равно больше по душе
&lt;a href="/tag/tornado/"&gt;Tornado&lt;/a&gt;. Вопрос про их сравнение от одного из слушателей
вызвал у докладчика рассказать историю о том, как будущий автор Tornado
тусовался в сообществе Twisted, а потом взял и сделал свой продукт.&lt;/p&gt;
&lt;p&gt;Следующий доклад был про профилирование памяти в &lt;a href="/tag/python/"&gt;Python&lt;/a&gt;
от Антона Грицая - начал он историю очень издалека, с того что такое
утечки памяти, какие бывают "сборщики мусора", какие есть варианты
искать утечки в &lt;a href="/tag/python/"&gt;Python&lt;/a&gt; и чем они плохи, собственно до
"дела" он дошел лишь к концу доклада. Было предложено пользоваться
продуктом под названием &lt;a href="https://www.insight-it.ru/goto/f077b18a/" rel="nofollow" target="_blank" title="http://guppy-pe.sourceforge.net/"&gt;heapy&lt;/a&gt;,
который обладает широким спектром возможности, но при этом документация
сильно хромает.&lt;/p&gt;
&lt;p&gt;Последним докладом в секции про &lt;a href="/tag/python/"&gt;Python&lt;/a&gt; было выступление
трех бравых ребят из HeadHunter, которые рассказывали про их внутренний
продукт под названием Frontik, представляющий собой надстройку над
&lt;a href="/tag/tornado/"&gt;Tornado&lt;/a&gt;, аггрегирующую данные с нескольких
HTTP-сервисов. В целом идея мне понравилась, но ввиду исторических
причин реализация у них накручена очень муторно:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;основной формат передачи данных - &lt;a href="/tag/html/"&gt;XML&lt;/a&gt; по HTTP&lt;/li&gt;
&lt;li&gt;генерация HTML посредством &lt;a href="/tag/xslt/"&gt;XSLT&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;регулярные выражения где надо и где не надо (для повышения
    производительности)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Основным событием оставшейся части второго дня, как Вы уже наверное
поняли, был аншлаг с участием Вконтакте и лично Павлом Дуровым в главной
роли. Результаты подробно расписаны в статье &lt;a href="https://www.insight-it.ru/highload/2010/arkhitektura-vkontakte/"&gt;"Архитектура
Вконтакте"&lt;/a&gt;,
повторяться не буду, с Вашего позволения.&lt;/p&gt;
&lt;p&gt;Остальные доклады я застал лишь частями, так как блуждал по залам без
особого энтузиазма, да и в толпе вокруг Павла чуток потусовался.
Расскажу вкратце запомнившиеся моменты:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Юрий Востриков из Mail.ru рассказывал про
    &lt;a href="https://www.insight-it.ru/goto/4cece2af/" rel="nofollow" target="_blank" title="http://opensource.mail.ru"&gt;Tarantool/Silverbox&lt;/a&gt; - еще после их
    технологического форума подумываю попробовать этот продукт в деле,
    но после этого выступления понял, что пока рановато: не известно ни
    об одном успешном применении вне компании-разработчика, да и
    библиотеки с реализацией полноценного протокола есть далеко не под
    все языки программирования.&lt;/li&gt;
&lt;li&gt;На доклад про реализацию одного из топовых приложений Вконтакте на
    &lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt; я попал почти к самой сессии вопросов-ответов,
    запомнился только тот факт, что после того как компания, в которой
    работал докладчик, передала приложение заказчику - они почти сразу
    же переписали его на &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt;. Заставляет задуматься.&lt;/li&gt;
&lt;li&gt;В третьем, дополнительном, зале во второй половине дня расположился
    тренинг Start in Garage для людей, планирующих сделать свой стартап;
    ребята рассказывали весело и непринужденно, но по сути все было
    очень примитивно - ушел минут через 20 после начала на аншлаг
    вконтакте.&lt;/li&gt;
&lt;li&gt;Про &lt;a href="https://www.insight-it.ru/goto/e72a7ec5/" rel="nofollow" target="_blank" title="http://www.scalaxy.ru"&gt;Scalaxy&lt;/a&gt; было бы интересно написать
    отдельную статью, больно часто они всплывают на конференциях и в
    онлайн-сообществах. На этот раз рассказывали о том, как они выделяют
    избыточные дисковые массивы для виртуальных машин (которые они
    собственно в аренду сдают). Технология называется Vast Sky, родом
    откуда-то из Азии, позволяет легко выделять заданное количество
    блоковых устройств на разных дисковых системах и подключать их к
    виртуальной машине в виде софтверного RAID. В сочетании с их QDR
    Infiniband от Voltaire работает очень даже шустро (по крайней мере
    если верить их бенчмаркам по сравнению с альтернативными
    технологиями).&lt;/li&gt;
&lt;li&gt;Scalaxy же запускает сервис ddosme, предназначенный для нагрузочного
    тестирования интернет-проектов. Попал опять только на
    вопросы-ответы, из них понял, что они предлагают через прокси
    походить по своему ресурсу, затем на основе логов составляются
    маршруты движения ботов по сайту и тестирование запускается на
    нужных мощностях. Сколько стоит не понял.&lt;/li&gt;
&lt;li&gt;Последним докладом, который я застал краем глаза, было обсуждение
    основных косяков, мешающих 1С-Битрикс обслуживать пристойное
    количество пользователей - для меня совершенно не актуальный вопрос,
    так что после этого я начал собираться в сторону выхода и отправился
    смотреть &lt;a href="https://www.insight-it.ru/event/2010/socialnaya-set/"&gt;"Социальная сеть"&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="zakliuchenie"&gt;Заключение&lt;/h2&gt;
&lt;p&gt;Впечатления от конференции очень положительные: большинство докладов
хотя бы немного полезны, рекламы вообще минимум, организация на уровне.
По-прежнему не знаю стоит ли она своих денег, но потраченного времени
точно стоит.&amp;nbsp; Надеюсь в следующем году будет по-проще попасть.&lt;/p&gt;
&lt;p&gt;Хотелось бы видеть больше докладов не о конкретных инструментах и
технологиях, а о их применении в рамках построения общей архитектуры
проекта или решения конкретных нетривиальных задач. Доклады в духе "у
нас вот такая классная штука есть, но стоит денег" и "приходите к нам
работать, чтобы попробовать в деле эту технологию" как обычно скучны, но
вроде их было довольно мало (надеюсь докладчики хотябы платят
организатором за возможность порекламироваться?). Приглашенные
иностранные гости - ход очень классный, мне кажется основной ключ успеха
прошедшего мероприятия, в этом направлении определенно стоит двигаться -
хотелось бы увидеть представителей известных проектов (Google, Ebay,
Amazon, Flickr, Twitter, Baidu, QQ и.т.д.) и людей, решающих реально
нетривиальные задачи, вроде Joe Damato.&lt;/p&gt;
&lt;p&gt;В любом случае спасибо организаторам за два с толком проведенных дня :)&lt;/p&gt;
&lt;p&gt;Да, думаю Вы уже заметили, что блог Insight IT снова потихоньку
возвращается к жизни, так что &lt;a href="/feed/"&gt;подписываться на RSS никогда не поздно&lt;/a&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sun, 31 Oct 2010 23:24:00 +0300</pubDate><guid>tag:www.insight-it.ru,2010-10-31:event/2010/highload-2010/</guid><category>highload</category><category>высоконагруженные системы</category><category>конференции</category><category>Масштабируемость</category><category>мероприятия</category><category>разработка</category></item><item><title>Facebook: how we scaled to 500 000 000 users by Robert Johnson</title><link>https://www.insight-it.ru//event/2010/facebook-how-we-scaled-to-500-000-000-users-by-robert-johnson/</link><description>&lt;p&gt;Буквально только что вернулся после насыщенного дня, большую часть
которого я провел на &lt;a href="https://www.insight-it.ru/goto/8f4b055f/" rel="nofollow" target="_blank" title="http://2010.russianinternetweek.ru/"&gt;RIW2010&lt;/a&gt; (о
котором я надеюсь успеть полноценно написать в воскресенье), а вечером я
очень рад что собрался таки съездить на выступления Robert Johnson под
названием &lt;a href="https://www.insight-it.ru/goto/ff11ad2b/" rel="nofollow" target="_blank" title="http://styleru.timepad.ru/event/3571"&gt;"Facebook: how we scaled to 500 000 000
users"&lt;/a&gt; в ГУ-ВШЭ (где я собственно
на данный момент и учусь в магистратуре). Сейчас же я хотел бы
сосредоточиться именно на последнем мероприятии, благо оно мало того что
было существенно более качественным, чем остальные выступления, на
которых я был последнее время, так еще и очень сильно коррелирует как в
целом с общей нитью данного блога, так и с последним постом в
частности.
&lt;!--more--&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;Прежде чем читать дальше, настоятельно рекомендую
ознакомиться с &lt;a href="https://www.insight-it.ru/highload/2010/arkhitektura-facebook/"&gt;архитектурой
Facebook&lt;/a&gt;
(которую я обновил немного), здесь я постараюсь особо не повторяться и
рассказать лишь об общих впечатлениях и новых фактах, которые мне
удалось услышать и выяснить.&lt;/em&gt;\&lt;/p&gt;
&lt;p&gt;Само выступление длилось всего пол часа, было абсолютно без технических
подробностей - немного понтов о своих достижениях в плане аудитории и
нагрузки (собственно говоря первым слайдом был график роста аудитории по
годам), а затем базовые вещи оb построении высоконагруженных систем в
духе мол, что масштабироваться надо горизонтально, внимательно следить
за SPOF, быстро двигаться вперед с использованием небольших итераций в
разработке и.т.п. Аудитория слушала с очень напряженными лицами - для
многих определенно было много незнакомых слов и вообще довольно суровое
скороговорочное американское произношение мало кому давалось легко на
слух.&lt;/p&gt;
&lt;p&gt;Технических вопросов было довольно мало (что впрочем не удивительно,
т.к. мероприятие проходило в гуманитарном ВУЗе) - превалировали вопросы
в духе "что вы делаете с профилями умерших людей" (есть процедура когда
друзья/родственники сообщают и если оказывается правдой то специальным
образом перенастраивают аккаунт, чуть ли не несколько миллионов таких
случаев было), "как работает фича Х" (из интересных фич - скрытие фоток
твоих бывших boy/girl friend'ов через face recognition), "как выглядит
типичный день разработчика в Facebook" (2/3 пишут код, остальное -
всякие остальные виды деятельности), "какие планы развития в России и
мире" или "что думаете о конкурентах" (их позиция - делать лучший
продукт на рынке и аудитория сама подтянется), еще спрашивали снимался
ли он в фильме, о котором последнее время в рунете слухи ходят. Недавно
еще у них открылся небольшой венчурный фонд для инвестиций в социальные
проекты. Вообще сессия публичных ответов-вопросов длилась около часа и
потом еще где-то с полчаса он активно общался с людьми лично, тоже с ним
поговорил немного.&amp;nbsp; Под конец общение почти превратилось в фотосессию, я
тоже вот решил за компанию сфотографироваться:&lt;/p&gt;
&lt;p&gt;&lt;img alt='"Robert Johnson and Ivan Blinkov"' class="responsive-img" src="https://www.insight-it.ru/images/Robert-Johnson-and-Ivan-Blinkov.jpg" title="Robert Johnson and Ivan Blinkov"/&gt;&lt;/p&gt;
&lt;p&gt;Пожалуй хватит воды, перейдем к делу, собственно что же нового для себя
я узнал на мероприятии:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;С примерно первой половины года их официальная активная аудитория
    повысилась с 400 до 500 миллионов человек&lt;/li&gt;
&lt;li&gt;Штат инженеров (т.е. по-нашему разработчиков и сис. администраторов)
    увеличился до \~500 человек, примерно стало понятно как они
    распределены:&lt;ul&gt;
&lt;li&gt;Основной принцип: много небольших узкоспециализированных команд,
    которым даны полномочия принимать решения и проводить полностью
    продукт от стадии идеи до стадии реализации&lt;/li&gt;
&lt;li&gt;Около половины работают в "продуктовых" командах, до 5-10
    человек в каждой (фотографии, поиск, личные сообщения, и.т.п.)&lt;/li&gt;
&lt;li&gt;Ряд команд, занимающихся общими вопросами (например 4 человека
    работают над оптимизацией &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;, еще есть команды
    по безопасности, приватности, производительности)&lt;/li&gt;
&lt;li&gt;Нестрогий менеджмент, 2 уровня управления&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Используются аппаратные балансировщики нагрузки от
    &lt;a href="https://www.insight-it.ru/goto/26d35856/" rel="nofollow" target="_blank" title="http://www.f5.com"&gt;F5&lt;/a&gt; + некое опенсорсное решение, сказал что
    возможно &lt;a href="/tag/nginx/"&gt;nginx&lt;/a&gt;, но он не уверен&lt;/li&gt;
&lt;li&gt;Виртуализация совсем не используется - на таком масштабе она не
    актуальна&lt;/li&gt;
&lt;li&gt;MySQL-сервера используют подключенные напрямую массивы дисков
    (direct attached storage)&lt;/li&gt;
&lt;li&gt;По вопросам мониторинга кое-где используются nagios и ganglia, но
    большая часть данной подсистемы написано самостоятельно&lt;/li&gt;
&lt;li&gt;Десятки тысяч серверов и десятки гигабит трафика, более точных цифр,
    к сожалению, не дали&lt;/li&gt;
&lt;li&gt;Коммерческого программное обеспечение практически не используется,
    по большей части собственные разработки и в ключевых местах
    opensource&lt;/li&gt;
&lt;li&gt;Сам спросил про датацентры:&lt;ul&gt;
&lt;li&gt;Santa Clara, California - master (названия мест плохо расслышал,
    поправьте если ошибаюсь)&lt;/li&gt;
&lt;li&gt;Ashburn, Virginia - read-only slave&lt;/li&gt;
&lt;li&gt;За пределами США присутствие очень небольшое, по паре стоек в
    нескольких странах - если я правильно понял, то для кэширования
    статики, т.е. своя CDN&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Помимо этого мне было интересно про репликацию между ними:&lt;ul&gt;
&lt;li&gt;Используется модифицированный механизм встроенной репликации
    MySQL&lt;/li&gt;
&lt;li&gt;Основные доработки:&amp;nbsp; передача помимо собственно данных списка
    идентификаторов объектов, которые следует инвалидировать из-за
    текущего обновления + какая-то хитрая система расстоновки флагов
    о текущем состоянии процесса репликации&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;DDoS их особо не волнует - сколько-либо серьезных попыток они не
    встречали, защита аппаратная на уровне ДЦ, как я понял&lt;/li&gt;
&lt;li&gt;Намного больше внимания уделяется модерации контента и борьбе со
    спамом&lt;/li&gt;
&lt;li&gt;Развертывание делается максимально плавно, как в плане обновления
    софта, так и в плане выкатывания новых версий кода сайта (упоминал в
    статье про архитектуру)&lt;/li&gt;
&lt;li&gt;Их позиция касательно opensource:&lt;ul&gt;
&lt;li&gt;Активно использовать и возвращать взамен с улучшениями&lt;/li&gt;
&lt;li&gt;Facebook выгодно возвращать вносимые изменения в популярные
    opensource проекты, так как они не считают их конкурентным
    преимуществом (ну и лицензии никто не отменял)&lt;/li&gt;
&lt;li&gt;Если это не делается, то чаще всего т.к. либо используются
    "грязные хаки и костыли", которые никому кроме них не нужны,
    либо так как разработчикам не хватает времени привести патч в
    удобоваримый вид&lt;/li&gt;
&lt;li&gt;Свои проекта также активно публикуются, так как организации
    вроде Apache Software Foundation берут на себя многие вопросы по
    поддержке и развитию кода&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Apache Hadoop как уже многие писали используется как хранилище и
    оффлайновый обработчик данных вроде логов, Hive родился как
    надстройка для упрощения доступа&lt;/li&gt;
&lt;li&gt;Хоть сотрудники Facebook и реализовали проект Cassandra, про который
    активно спрашивали в комментариях как тут, так и на хабре, но они
    его практически не используют у себя. Как известно он опубликован в
    opensource и поддерживается ASF. В Facebook он
    используется (использовался?) только как хранилище для &lt;em&gt;поиска&lt;/em&gt; по
    внутренним сообщениям, мотивация: очень быстрая запись,
    недостаточная производительность операций случайного чтения&lt;/li&gt;
&lt;li&gt;На вопрос про основной дистрибутив линукс и вендоров оборудования он
    был не особо уверен, но сказал что скорее всего использутся CentOS и
    они работают с несколькими основными вендорами серверов (HP, IBM,
    Dell) - свое оборудование (как Google) они не изобретают, так как не
    считают целесообразным&lt;/li&gt;
&lt;li&gt;Используется довольно сильно модифицированное ядро ОС, особенно по
    части сетевого стека&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sat, 23 Oct 2010 01:23:00 +0400</pubDate><guid>tag:www.insight-it.ru,2010-10-23:event/2010/facebook-how-we-scaled-to-500-000-000-users-by-robert-johnson/</guid><category>Facebook</category><category>HSE</category><category>Robert Johnson</category><category>ВШЭ</category><category>выступление</category><category>лекция</category><category>масштабирование</category><category>мероприятие</category><category>разработка</category></item><item><title>Мероприятия всякие разные</title><link>https://www.insight-it.ru//event/2010/meropriyatiya-vsyakie-raznye/</link><description>&lt;p&gt;Не знаю как во всем в мире, но в Москве пора айтишных и не очень
конференций и мероприятий - это осень. Посещать их я еще не совсем
обленился, а вот с написанием отчетов все как-то не складывалось. К
сожалению, бюджет не позволил сходить на платные мероприятия, особенно
Highload++. В общем в итоге я решил написать этот краткий обзорный пост
по мероприятиям, на которые меня занесло этой осенью. Обо многом пишу
спустя большое количество времени - возможны неточности и провалы в
памяти.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h3 id="mailru-technology-forum"&gt;&lt;a href="https://www.insight-it.ru/goto/24f5cd74/" rel="nofollow" target="_blank" title="http://techforum.mail.ru/"&gt;Mail.ru Technology Forum&lt;/a&gt;&lt;/h3&gt;
&lt;div class="right"&gt;
&lt;div class="card light-blue"&gt;
&lt;div class="card-content white-text"&gt;
14 сентября
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Честно говоря я подъехал на мероприятие лишь к обеду и не досидел до
конца, так что могу лишь прокомментировать середину, то есть самый
разгар.&lt;/p&gt;
&lt;p&gt;В первую очередь я пошел в технологическую секцию, где Tom
Preston-Werner, сооснователь и тех. директор проекта
&lt;a href="https://www.insight-it.ru/goto/ecdadcf9/" rel="nofollow" target="_blank" title="http://www.github.com"&gt;GitHub&lt;/a&gt;, рассказывал о том, как устроен их
проект, какие технологии и костыли они используют. Если в двух словах,
то у них используются три протокола: http, git и ssh, для каждого
используется свой маршрут обработки запроса внутри системы. Основными
продуктами, которые они используют являются &lt;a href="/tag/ruby-on-rails/"&gt;Ruby on Rails&lt;/a&gt;, &lt;a href="/tag/unicorn/"&gt;Unicorn&lt;/a&gt;, &lt;a href="/tag/haproxy/"&gt;HAProxy&lt;/a&gt;, и собственно git и sshd. Вообще возможно стоило бы под эту историю написать отдельный пост - детали явно выходят за рамки данного повествования, а доклад и правда был интересным.
Постараюсь вернуться к этой истории как только появится возможность.&lt;/p&gt;
&lt;p&gt;Следующими в этом зале выступали представители самого mail.ru - честно
говоря у меня хватило терпения слушать их очередное расхваливание
Imagine Framework,&amp;nbsp; который можно посмотреть только устроившись к ним на
работу, только первые минут 15 наверное и я благополучно перекочевал во
второй зал, где основной тематикой были социальные игры. Вообще за
последний год мне довелось немного поработать в данной области и секция
могла бы оказаться интересной, но качество докладов тоже было не на
высоте - ничего нового ни про монетизацию, ни про привлечение аудитории
услышать не удалось. В основном доклады представляли собой либо кейсы,
основанные на конкретных не очень успешных приложениях, либо на каких-то
общих рекомендациях и так лежащих на поверхности.&lt;/p&gt;
&lt;p&gt;Кстати еще на одном из докладов представители мэйла заикались о некой
NoSQL базе данных их разработки, которую они опубликовали под opensource
лицензией - впоследствии попытался найти, но на
http://opensource.mail.ru какая-то другая муть расположена, а гуглится
что-то совсем не то. Если кто в курсе - поделитесь ссылкой, пожалуйста.&lt;/p&gt;
&lt;h3 id="mit-way-by-richard-kivel"&gt;&lt;a href="https://www.insight-it.ru/goto/13d0a982/" rel="nofollow" target="_blank" title="http://www.mitef.ru/index.php?option=com_content&amp;amp;view=article&amp;amp;id=238:spb-forum-09-2010&amp;amp;catid=3:upcoming-events-&amp;amp;Itemid=71"&gt;"MIT Way" by Richard Kivel&lt;/a&gt;&lt;/h3&gt;
&lt;div class="right"&gt;
&lt;div class="card light-blue"&gt;
&lt;div class="card-content white-text"&gt;
20 сентября
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Ричард в целом продемонстрировал себя как успешного бизнесмена в сфере
информационных и био технологий, но при этом практическая ценность его
выступления была невелика. Он является презедентом MIT Enterprise Forum,
а также председателем правления Rhapsody Biologics. Выступление
проходило в здание ГУ-ВШЭ при поддержке HSE Inc.&lt;/p&gt;
&lt;p&gt;Основными моментами его выступления были следующие тезисы:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Один из основных ресурсов бизнесмена - сеть его знакомств и деловых
    контактов, особенно если речь идет о международном бизнесе.&lt;/li&gt;
&lt;li&gt;Нельзя бояться ошибиться, когда пытаешься создать успешный бизнес -
    у большинства людей это получается далеко не с первой и не со второй
    попытки.&lt;/li&gt;
&lt;li&gt;Очень важно уметь нанимать людей, которые умнее тебя - если ты
    будешь самым интеллектуалом в офисе, то врядли твой бизнес сможет
    работать самостоятельно.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Все просто и понятно, но все же еще раз обратить внимание на данные
вопросы не помешало, да и дополнительная возможность послушать вживую
выступление на качественном английском никогда не бывает лишней.&lt;/p&gt;
&lt;p&gt;В итоге правда оказалось, что основная цель данной лекции была вовсе не
научить делать технологический бизнес, а привлечь дополнительных
участников в сообщество MIT EF, представительство которого недавно
открылось и в России. Мотивацией для присоединения к сообществу было как
раз расширение сети бизнес-знакомств и контактов, особенно зарубежом.
Членские взносы составляют довольно приличную сумму по меркам московских
студентов (которых было большинство в зале) - что-то в районе 150\$/год.&lt;/p&gt;
&lt;h3 id="startup-weekend-brainstorm"&gt;&lt;a href="https://www.insight-it.ru/goto/dbd42edb/" rel="nofollow" target="_blank" title="http://moscow.startupweekend.org/archives/655"&gt;Startup Weekend Brainstorm&lt;/a&gt;&lt;/h3&gt;
&lt;div class="right"&gt;
&lt;div class="card light-blue"&gt;
&lt;div class="card-content white-text"&gt;
25 сентября
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Мероприятие являлось по сути подготовкой к самому Startup Weekend, о
котором я напишу чуть ниже. Организатором обоих мероприятий является
компания &lt;a href="https://www.insight-it.ru/goto/ef462f5b/" rel="nofollow" target="_blank" title="http://www.glavstart.ru"&gt;Главстарт&lt;/a&gt;, целью которой является
расширение рынка технологических стартапов, для чего они проводят эти
самые мероприятия, занимаются подбором экспертов и менторов, а также
помогают проектам получить посевные инвестиции.&lt;/p&gt;
&lt;p&gt;Как не трудно догадаться, подготовительная часть под названием
Брейншторм направлена на генерацию идей для интернет-проектов.
Участников мероприятия разбили на группы по интересам, около 20 человек
на группу, где под руководством массовика-затейника и эксперта они
придумывали различные идеи проектов, сервисов, целевых аудиторий и их
потребностей и проблем. За почти целый день у каждой группы получилось
около 10 более-менее продуманных идей, из которых гипотетически могли бы
вырости проекты на следующем этапе - самом Startup Weekend.&lt;/p&gt;
&lt;p&gt;Сами идеи проектов позвольте не озвучивать - многое не помню, да и
большинство из не прошедшх отбор были на грани бреда.&lt;/p&gt;
&lt;h3 id="yet-another-conference"&gt;&lt;a href="https://www.insight-it.ru/goto/50b6b9aa/" rel="nofollow" target="_blank" title="http://company.yandex.ru/public/yac/"&gt;Yet Another Conference&lt;/a&gt;&lt;/h3&gt;
&lt;div class="right"&gt;
&lt;div class="card light-blue"&gt;
&lt;div class="card-content white-text"&gt;
1 октября
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Наверное самое серьезное из мероприятий, попавших в данный обзор.
Организатором конференции являлся Яндекс, попал я опять не к самому
открытию ибо пробки и проблемы с парковкой. С организационной точки
зрения все замечательно, особенно для бесплатной конференции, разве что
еду в перерывах сметали слишком быстро :).&lt;/p&gt;
&lt;p&gt;Первый доклад, на который я пришел где-то к середине, вел инженер из
Google и рассказывал про data races и инструмент для их поиска
ThreadSanitizer - вроде все понятно и на самом деле слабо пересекается с
областью моих интересов. Вторым докладом в этой секции шел Intel и уже
через 15 секунд после начала стало понятно, что будет сплошная реклама
их линейки проектов для разработки многопоточных приложений - сразу же
встал и сбежал в соседнюю секцию.&lt;/p&gt;
&lt;p&gt;В другом зале была самореклама уже продукта Яндекса, но уже несколько
более завуалированная. Речь шла об их собственном веб-сервере Phantom,
который они используют в баннерокрутилке. Основной его фишкой является
приоритезация хэндлеров запросов в рамках одного сервера. Написан с нуля
на плюсах, с использованием корутин и чуть ли не вообще без
использования каких-либо библиотек. Основной плюс: в отличии от других
докладчиков, рекламирующих свое детище, они хотябы обещали открыть
исходные коды продукта как только допилят поддержку протокола FastCGI.&lt;/p&gt;
&lt;p&gt;После перерыва я вернулся в первый зал, где началась длинная секция про
системы хранения и обработки большого объема данных, я прослушал три
доклада:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/apache-hadoop/"&gt;Apache Hadoop&lt;/a&gt; и прочие проекты вокруг него,
    выступал Константин Швачко из Yahoo.&lt;/strong&gt; Жалко, что в этом проекте так
    мало всего изменилось за тот год, что я с ним не работал, даже
    решение проблемных ситуаций с NameNode толком не решили видимо.
    Слушал и думал "сколько же я уже раз это все слышал и сам
    рассказывал другим".&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Собственная реализация Map Reduce от Яндекса, Александр
    Дмитриев.&lt;/strong&gt; Визуально красиво сделанная презентация, судя по
    твиттеру очень многим понравилось, правда за этим всем терялась суть
    доклада - слушал честно говоря краем уха, так как судя по всему
    публиковать в opensource данный проект они пока не планируют.
    Специфичная реализация публично-известного подхода, реально
    приспособленная только под конкретные задачи Яндекса - впечатление
    осталось именно такое.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Евгений Поляков из Яндекса рассказывал о распределенной
    хэш-таблице &lt;a href="https://www.insight-it.ru/goto/8c78fdc4/" rel="nofollow" target="_blank" title="http://www.ioremap.net/projects/elliptics"&gt;Elliptics Network&lt;/a&gt;.&lt;/strong&gt; Об Эллиптикс я ни разу ранее не слышал, а докладчик рассказывал очень вкусно о
    данном проекте. Основным плюсом данной системы хранения данных
    является модульность: особенно интересна возможность использовать
    различные технологии записи данных на диск, а также различные
    интерфейсы и протоколы, с помощью которых можно получать доступ к
    данным. Постараюсь на досуге подробнее изучить вопрос и если
    обнаружится что-то интересное - опубликовать свое более детальное
    впечатление о данном проекте.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Поводом сбежать с данной секции стал некий разработчик системы
статистики для ЖЖ из SUP Fabrik - молодой человек еле ворочал языком,
что делало практически невозможным понимание сути доклада. В другом зале
как раз началась медийная секция, опять полная саморекламы. Докладчик из
проекта &lt;a href="https://www.insight-it.ru/goto/b986924b/" rel="nofollow" target="_blank" title="http://www.videomost.com"&gt;videomost.com&lt;/a&gt; (видео-конференции) в
целом сосредоточил свое внимание на том, что видео-конференции - это
очень сложно, что популярные технологии, часто используемые в
видео-трансляциях, там работают плохо - и вообще будущее за
проприетарными специализированными протоколами, кодеками и системами. В
повестке доклада значились способы обхода firewall'ов и NAT'а - но в
докладе все ограничилось лишь большой красивой диаграммкой и фразой
что-то в духе "в нашем проекте аж 14 способов решать эти проблемы", без
каких-либо деталей.&lt;/p&gt;
&lt;p&gt;Второй доклад медийной секции вел Richard Cole, продукт менеджер из
Skype, показывал много красивых фотографий с людьми, пользующимися Skype
в разных ситуациях. По делу у него был только одно сообщение: скоро для
широкой публики будет доступен их &lt;a href="https://www.insight-it.ru/goto/51f3342e/" rel="nofollow" target="_blank" title="http://developer.skype.com/"&gt;SDK&lt;/a&gt;,
который сейчас находится в стадии бета-тестирования.&lt;/p&gt;
&lt;h3 id="startup-weekend"&gt;&lt;a href="https://www.insight-it.ru/goto/f568665e/" rel="nofollow" target="_blank" title="http://moscow.startupweekend.org/"&gt;Startup Weekend&lt;/a&gt;&lt;/h3&gt;
&lt;div class="right"&gt;
&lt;div class="card light-blue"&gt;
&lt;div class="card-content white-text"&gt;
1-3 октября
&lt;/div&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Это мероприятие еще не закончилось, я написал этот пост как раз во
второй день - по идее в самый разгар. Как уже возможно стало понятно:
основная суть мероприятия заключается в превращении идей
интернет-проектов в готовые команды и прототипы. По идее здесь можно
найти недостающих членов команды, получить советы экспертов, заключить
менторское соглашение и найти посевного инвестора. Вчера были
выступления представителей идей/проектов, сегодня - приехали "эксперты":
сначала выступали в elevator pitch, потом общение с представителями
проектов в формате speeddating, потом консультации по расписанию.
Выглядит это все хаотично, организаторы пытаются каким-то образом
способствовать созданию проектов, но все равно мотивации явно не
хватает, чтобы по сути с незнакомыми людьми сделать хоть сколько-нибудь
стоящий проект. Что из всего этого выйдет станет ясно завтра, возможно
обновлю пост, если будет что сказать.&lt;/p&gt;
&lt;h2 id="zakliuchenie_1"&gt;Заключение&lt;/h2&gt;
&lt;p&gt;В целом это очень здорово, что количество и качество подобных
мероприятий в России лишь растет с каждым годом. Полезность конечно не
всегда высока, но часто выносишь что-то новое и интересное для себя.
Расстраивает разве что тот факт, что количество откровенно рекламных
докладов очень велико, но для бесплатных мероприятий это вполне
объяснимо и терпимо.&lt;/p&gt;
&lt;p&gt;В планах посещения мероприятий в этом году остался разве что Google
Developer Day, подтверждение участия еще не пришло, но надеюсь все же
попасть и не забыть написать отчет.&lt;/p&gt;
&lt;p&gt;Если Вы дочитали до конца, но не подписаны на RSS - &lt;a href="/feed/"&gt;сейчас самое подходящее время, чтобы это сделать&lt;/a&gt; :)&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sat, 02 Oct 2010 17:44:00 +0400</pubDate><guid>tag:www.insight-it.ru,2010-10-02:event/2010/meropriyatiya-vsyakie-raznye/</guid><category>Apache Hadoop</category><category>Brainstorm</category><category>Git</category><category>GitHub</category><category>HAProxy</category><category>Imagine Framework</category><category>Mail.ru</category><category>Mail.ru Technology Forum</category><category>Map Reduce</category><category>MIT</category><category>Phantom</category><category>Richard Kivel</category><category>Ruby on Rails</category><category>sshd</category><category>Startup Weekend</category><category>ThreadSanitizer</category><category>YAC</category><category>Yet Another Conference</category><category>конференция</category><category>мероприятия</category><category>разработка</category><category>хранилища данных</category></item><item><title>Hadoop для разработчика</title><link>https://www.insight-it.ru//storage/2008/hadoop-dlya-razrabotchika/</link><description>&lt;p&gt;Для разработки приложений, работающих с использованием Hadoop, или же
алгоритмов для MapReduce framework'а совсем не нужен полномасштабный
кластер. На самом же деле для запуска всей системы, описанной мной в
&lt;a href="https://www.insight-it.ru/storage/2008/hadoop/"&gt;одном из предыдущих постов&lt;/a&gt;, вполне
достаточно одного компьютера и буквально минут 15 свободного времени,
как потратить их для решения этой задачи я Вам и поведаю.
&lt;!--more--&gt;
Рассказывать я буду на примере своего &lt;a href="/tag/gentoo-linux/"&gt;Gentoo
Linux&lt;/a&gt;, но большая часть этого повествования будет
справедлива и для других unix-like операционных систем.&lt;/p&gt;
&lt;h3 id="podgotovka"&gt;Подготовка&lt;/h3&gt;
&lt;p&gt;Перед тем, как приступить собственно говоря к установке
&lt;a href="https://www.insight-it.ru/goto/30a7481/" rel="nofollow" target="_blank" title="http://hadoop.apache.org/core/"&gt;Hadoop&lt;/a&gt;, необходимо выполнить два
элементарных действия, необходимых для правильного функционирования
системы:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;открыть доступ одному из пользователей по &lt;code&gt;ssh&lt;/code&gt; к этому же
    компьютеру без пароля, можно например создать отдельного
    пользователя для этого &lt;code&gt;hadoop&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$$&lt;/span&gt; useradd -m -n hadoop
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Далее действия выполняем от его имени:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$$&lt;/span&gt; su hadoop
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Генерируем RSA-ключ для обеспечения аутентификации в условиях
отсутствия возможности использовать пароль:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$$&lt;/span&gt; hadoop@localhost ~ &lt;span class="nv"&gt;$ &lt;/span&gt;ssh-keygen -t rsa -P &lt;span class="s2"&gt;""&lt;/span&gt;
Generating public/private rsa key pair.
Enter file in which to save the key &lt;span class="o"&gt;(&lt;/span&gt;/home/hadoop/.ssh/id_rsa&lt;span class="o"&gt;)&lt;/span&gt;:
Your identification has been saved in /home/hadoop/.ssh/id_rsa.
Your public key has been saved in /home/hadoop/.ssh/id_rsa.pub.
The key fingerprint is:
7b:5c:cf:79:6b:93:d6:d6:8d:41:e3:a6:9d:04:f9:85 hadoop@localhost
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;И добавляем его в список авторизованных ключей:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$$&lt;/span&gt; cat ~/.ssh/id_rsa.pub &amp;gt;&amp;gt; ~/.ssh/authorized_keys
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Этого должно быть более чем достаточно, проверить работоспособность
соединения можно просто написав:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$$&lt;/span&gt; ssh localhost
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Не забываем предварительно инициализировать &lt;strong&gt;sshd&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$$&lt;/span&gt; /etc/init.d/sshd start
&lt;/pre&gt;&lt;/div&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Помимо этого необходимо убедиться в наличии установленной JVM версии
    1.5.0 или выше, а также узнать директорию, где она располагается,
    вариантов сделать это множество, я нашел ее просто заглянув в самое
    логичное место - &lt;code&gt;/usr/lib&lt;/code&gt;, но при желании никто не может Вам
    помешать воспользоваться услугами, например, &lt;code&gt;slocate&lt;/code&gt;. Найденную
    директорию с JVM лучше запомнить или записать куда-нибудь, для меня
    она оказалась: &lt;code&gt;/usr/lib/jvm/sun-jdk-1.6&lt;/code&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="ustanovka"&gt;Установка&lt;/h3&gt;
&lt;p&gt;Установка начинается с получения копии исходного кода системы, способов
для этого существует несколько. Я перепробовал практически все, самую
адекватную версию мне удалось получить из SVN. Для ее получения
необходимо выполнить следующую команду:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;svn checkout http://svn.apache.org/repos/asf/hadoop/core/branches/branch-0.16 ~
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;branch-0.16&lt;/strong&gt; - последняя доступная версия на данный момент, для
определения ее номера достаточно заглянуть &lt;a href="https://www.insight-it.ru/goto/99e3d37e/" rel="nofollow" target="_blank" title="http://svn.apache.org/repos/asf/hadoop/core/branches/"&gt;по тому же адресу&lt;/a&gt;
браузером. Предполагается, что Hadoop будет располагаться прямо в
&lt;code&gt;/home/hadoop&lt;/code&gt;, но запросто можно использовать и другую директорию.&lt;/p&gt;
&lt;p&gt;Сразу же стоит скомпилировать различные дополнительные компоненты
системы, особенно это актуально из-за &lt;a href="/tag/hbase/"&gt;HBase&lt;/a&gt;, но и помимо
него соберется много чего интересного, например plug-in для отличной IDE
под названием &lt;strong&gt;&lt;a href="https://www.insight-it.ru/goto/b7976bc5/" rel="nofollow" target="_blank" title="http://www.eclipse.org"&gt;Eclipse&lt;/a&gt;&lt;/strong&gt; или &lt;a href="https://www.insight-it.ru/goto/9253da15/" rel="nofollow" target="_blank" title="http://hadoop.apache.org/core/docs/r0.16.0/hod.html"&gt;Hadoop On
Demand&lt;/a&gt;. Задача
также элементарна:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~ &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ant clean jar compile-contrib
&lt;/pre&gt;&lt;/div&gt;
&lt;h3 id="nastroika"&gt;Настройка&lt;/h3&gt;
&lt;p&gt;Конфигурационные файлы можно редактировать в произвольном порядке, самое
главное ничего не забыть :)&lt;/p&gt;
&lt;h4&gt;conf/hadoop-env.sh&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nb"&gt;export &lt;/span&gt;&lt;span class="nv"&gt;JAVA_HOME&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;/usr/lib/jvm/sun-jdk-1.6
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Единственная обязательная переменная окружения - &lt;code&gt;JAVA_HOME&lt;/code&gt;,
здесь как раз пригодится заранее найденный путь до JVM, все
остальное - по желанию.&lt;/p&gt;
&lt;h4&gt;conf/hadoop-site.xml&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;hadoop.tmp.dir&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;/home/hadoop/data/${user.name}&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;A base for other temporary directories.&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;fs.default.name&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;hdfs://localhost:54310&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;The name of the default file system.  A URI whose
  scheme and authority determine the FileSystem implementation.  The
  uri's scheme determines the config property (fs.SCHEME.impl) naming
  the FileSystem implementation class.  The uri's authority is used to
  determine the host, port, etc. for a filesystem.&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;mapred.job.tracker&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;localhost:54311&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;The host and port that the MapReduce job tracker runs
  at.  If "local", then jobs are run in-process as a single map
  and reduce task.
  &lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;dfs.replication&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;1&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;Default block replication.
  The actual number of replications can be specified when the file is created.
  The default is used if replication is not specified in create time.
  &lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Этот конфигурации файл является одним из ключевых, таким образом он
выглядит для конфигурации, состоящей из одного компьютера
(позаимствован из &lt;a href="https://www.insight-it.ru/goto/f1c9004a/" rel="nofollow" target="_blank" title="http://www.michael-noll.com/tutorials/running-hadoop-on-ubuntu-linux-single-node-cluster/"&gt;англоязычного мануала&lt;/a&gt;
на ту же тему).&lt;/p&gt;
&lt;h4&gt;src/contrib/hbase/conf/hbase-site.xml&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;hbase.master&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;localhost:60000&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;The host and port that the HBase master runs at&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;hbase.rootdir&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;/hbase&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;location of HBase instance in dfs&lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Как не сложно заметить, этот файл необходим для функционирования
&lt;strong&gt;HBase&lt;/strong&gt;, по-моему все просто и очевидно, &lt;code&gt;&amp;lt;description&amp;gt;&lt;/code&gt; говорят
сами за себя.&lt;/p&gt;
&lt;h3 id="zapusk"&gt;Запуск&lt;/h3&gt;
&lt;p&gt;Начать стоит с ознакомления с кратким описанием доступных команд Hadoop,
сделать это можно просто набрав &lt;code&gt;~/bin/hadoop&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;Usage: hadoop &lt;span class="o"&gt;[&lt;/span&gt;--config confdir&lt;span class="o"&gt;]&lt;/span&gt; COMMAND
where COMMAND is one of:
  namenode -format     format the DFS filesystem
  secondarynamenode    run the DFS secondary namenode
  namenode             run the DFS namenode
  datanode             run a DFS datanode
  dfsadmin             run a DFS admin client
  fsck                 run a DFS filesystem checking utility
  fs                   run a generic filesystem user client
  balancer             run a cluster balancing utility
  jobtracker           run the MapReduce job Tracker node
  pipes                run a Pipes job
  tasktracker          run a MapReduce task Tracker node
  job                  manipulate MapReduce &lt;span class="nb"&gt;jobs&lt;/span&gt;
&lt;span class="nb"&gt;  &lt;/span&gt;version              print the version
  jar             run a jar file
  distcp   copy file or directories recursively
  daemonlog            get/set the log level &lt;span class="k"&gt;for&lt;/span&gt; each daemon
 or
  CLASSNAME            run the class named CLASSNAME
Most commands print &lt;span class="nb"&gt;help &lt;/span&gt;when invoked w/o parameters.
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Первым делом необходимо отформатировать &lt;em&gt;Namenode&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;~/bin/hadoop namenode -format
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;И дело останется лишь за малым, запустить на выполнение пару
bash-скриптов, которые без вашего дальнейшего участия &lt;em&gt;инициализируют&lt;/em&gt;
всю систему, включая HBase:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;~/bin/hadoop/start-all.sh &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; ~/src/contrib/hbase/bin/start-hbase.sh
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Как только они закончат все необходимые действия, у Вас появится
возможность удостовериться, что все в порядке. Самым простым способом
является запуск клиента &lt;em&gt;Hbase Shell&lt;/em&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;~/bin/src/contrib/hbase/bin/hbase shell
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Если в ответ Вы получили соответствующее приглашение клиента, значит все
было сделано верно!&lt;/p&gt;
&lt;p&gt;Вот собственно говоря и все, псевдо-кластер функционирует, доступ к
HBase имеется, можно приступать к разработке :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;P.S.:&lt;/strong&gt; Остановка системы производится по тому же принципу скриптами
&lt;code&gt;stop-all.sh&lt;/code&gt; и &lt;code&gt;stop-hbase.sh&lt;/code&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Tue, 26 Feb 2008 00:15:00 +0300</pubDate><guid>tag:www.insight-it.ru,2008-02-26:storage/2008/hadoop-dlya-razrabotchika/</guid><category>gentoo linux</category><category>Hadoop</category><category>HBase</category><category>HDFS</category><category>MapReduce</category><category>ПО</category><category>развертывание</category><category>разработка</category><category>установка</category></item><item><title>Шаблонизация</title><link>https://www.insight-it.ru//php/2008/shablonizaciya/</link><description>&lt;p&gt;Наверняка Вы часто замечали, что в пределах одного сайта все (или
покрайней мере большинство) страниц имеют много общего: структуру,
расположение элементов, дизайн и так далее. Основным различием обычно
является лишь содержание. Естественно, что делается это не спроста:
именно общие компоненты сайта создают в голове посетителей тот самый
образ, который производит общее подсознательное впечатление о сайте, а
также позволяет посетителям отличать сайт А от сайта Б.&lt;/p&gt;
&lt;p&gt;Продолжая разговор, начатый еще в
&lt;a href="https://www.insight-it.ru/php/2008/obshhaemsya-s-bazojj-dannykh/"&gt;одной&lt;/a&gt; из &lt;a href="https://www.insight-it.ru/dzhentelmenskij-nabor-php-programmista/"&gt;предыдущих
статей&lt;/a&gt;, рассмотрим организацию интерфейса между двумя другими составляющими практически любого
интернет-проекта: скриптов (все так же на примере PHP) и страницами,
отправляемыми посетителям посредством http-сервера.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;С точки зрения веб-разработчика было бы как минимум не логично мешать в
кучу постоянные части страниц с динамическими. Для этого существует
множество причин, в том числе, например, экономия вычислительной
мощности сервера на отсутствии необходимости каждый раз заново
генерировать статичные элементы или неминуемое сокращение объемов кода,
который необходимо написать, в случае если статический и динамический
контент разделены. Отделенную подобным образом статическую часть страниц
(слегка модифицированную с целью обозначить правила, по которым будет
проводиться "заполнение" ее динамическим контентом) принято называть
словом &lt;em&gt;"шаблон"&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Наверняка у Вас уже возникло два вполне логичных вопроса:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Как можно разделить таким образом контент?&lt;/li&gt;
&lt;li&gt;Как потом восстановить страницу в исходном виде?&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Вариантов ответа на каждый из них можно придумать множество: начиная с
банальных вариаций на тему применения &lt;strong&gt;echo&lt;/strong&gt;, заканчивая применением
достаточно серьезных готовых решений вроде широкораспространенного
&lt;a href="https://www.insight-it.ru/goto/2915d764/" rel="nofollow" target="_blank" title="http://smarty.php.net"&gt;&lt;strong&gt;Smarty&lt;/strong&gt;&lt;/a&gt; или существенно более эффективного
&lt;a href="https://www.insight-it.ru/goto/8c8929a1/" rel="nofollow" target="_blank" title="http://alexeyrybak.com/blitz/blitz_ru.html"&gt;&lt;strong&gt;Blitz&lt;/strong&gt;&lt;/a&gt;. Каждый из них
имеет свои сильные и слабые стороны, но в целом любой из них можно
оценить по двум критериям: производительности и удобстве организации
кода.&lt;/p&gt;
&lt;p&gt;Какие-либо цифры оценки производительности приводить не буду, так как,
во-первых, в Сети можно найти много benchmark'ов, посвященных этой теме,
а, во-вторых, просто-напросто вовсе не о цифрах я хотел с Вами
поговорить. Как известно самым производительным по крайней мере с
теоретической точки зрения является метод под названием &lt;strong&gt;php mess&lt;/strong&gt;, заключается он в следующем: вся страница размещается в рамках
одного файла, при этом статическая часть документа пишется просто "как
есть" в соответствии с необходимым стандартом, а изменяемые части
организуются размещенным в необходимых местах PHP-кодом, окруженным
стандартной конструкцией &lt;code&gt;&amp;lt;?php&amp;nbsp;&amp;nbsp;&amp;nbsp;?&amp;gt;&lt;/code&gt;. Но огромнейший недостаток
очевиден - огромное количество информации расположенной в одном файле,
при отсутствии какого-либо более четкого разделения PHP-кода и
остального содержимого, чем указанная выше конструкция, приводит к
постоянной путанице в коде, а также существенным затратам времени
программиста при попытках исправить ту или иную часть документа.&lt;/p&gt;
&lt;p&gt;На противоположной стороне нашей шкалы &lt;em&gt;удобство-производительность&lt;/em&gt; я
бы расположил уже упомянутое выше решение под названием &lt;strong&gt;Smarty&lt;/strong&gt;.
Представляет оно собой целую систему, реализованную также на PHP, и
предоставляющую огромное количество возможностей по решению нашей
задачи. Шаблоны хранятся в отдельных файлах, для определения мест
расположения динамического контента используется специальный синтаксис,
который прост как три копейки, так как разрабатывался с расчетом не на
программистов, а по принципу "чем проще, тем лучше". Именно этот факт
сделал &lt;strong&gt;Smarty&lt;/strong&gt; одним из самых (если не самым) распространенных
движков шаблонизации (или как их принято правильно называть "Template
Engine"). Но, к сожалению, за удобство приходится платить, в этом случае
производительностью: вся система сама по себе громоздка и состоит из
множества файлов, между которыми все данные так или иначе передаются, а
так как написано она на PHP (который является далеко не самым
производительным языком программирования, в основном в силу своей
интерпритируемости и некоторых других особенностей), конкуренции в плане
производительности многим другим вариантам решения нашей задачи
&lt;strong&gt;Smarty&lt;/strong&gt; составить не в состоянии.&lt;/p&gt;
&lt;p&gt;Одним из лучших "компромиссных" вариантов, которые доступны на данный
момент, могу назвать также упомянутый выше &lt;strong&gt;Blitz&lt;/strong&gt;. Реализован он в
виде модуля PHP, написанного на языке &lt;strong&gt;C&lt;/strong&gt;, что является залогом его
отличной производительности. При этом общая его концепция близка к
&lt;strong&gt;Smarty&lt;/strong&gt;: шаблоны также хранятся в отдельных файлах и подчинены
незамысловатому синтаксису (который вообще можно понять и запомнить
буквально за 15-20 минут, прочитав статью, &lt;a href="https://www.insight-it.ru/goto/8c8929a1/" rel="nofollow" target="_blank" title="http://alexeyrybak.com/blitz/blitz_ru.html"&gt;ссылку на
которую&lt;/a&gt; я уже приводил
выше), а в PHP-скриптах после установки становится доступен специальный
класс для управления модулем. Но основное достоинство этого решения
является одновременно и его основным недостатком - редкий хостинг имеет
этот модуль в списке предустановленных (видимо в силу своей не очень
обширной известности, обусловленной ), а доступ к http-серверу и
PHP-интерпретатору, который необходим для установки PHP-модулей,
предоставляется чаще всего только на дорогих тарифах виртуального
хостинга или на различных вариантах VPS или арендуемых серверов.&lt;/p&gt;
&lt;p&gt;Помимо этого некоторые энтузиасты берутся на написание "собственных"
&lt;em&gt;Template Engine&lt;/em&gt;, базирующихся на различных вариантов использования
PHP-функций вроде &lt;strong&gt;preg_replace&lt;/strong&gt;. Если честно такие попытки редко
заканчиваются успехом: в лучшем случае удается добиться удобства
использования самим разработчиком, но чаще всего в ущерб
производительности. Заниматься подобными экспериментами я Вам не
советую, вместо этого я предлагаю написать &lt;em&gt;"обертку"&lt;/em&gt; к приглянувшемуся
распространенному &lt;em&gt;Template Engine&lt;/em&gt;, что позволит не только сделать его
использование более удобным конкретно для Вас, но и позволит заменить
его на другой с минимальными затратами сил и времени (например в случае,
если модуль &lt;strong&gt;Blitz&lt;/strong&gt; недоступен).&lt;/p&gt;
&lt;h3 id="razrabatyvaem-obertku"&gt;Разрабатываем "обертку"&lt;/h3&gt;
&lt;p&gt;Сразу скажу, что цели привести конкретный пример пригодного для
реального использования кода я перед собой не ставлю в этой части моего
повествования. Я лишь хочу показать направление, в котором можно
провести разработку с целью облегчения собственной же жизни, т.е.
предоставить Вам альтернативу простому использованию тех или иных
решений в том виде, в котором они предоставлены разработчиками.&lt;/p&gt;
&lt;p&gt;Если Ваш выбор всетаки пал на написание "оболочки", не смотря на
принесение в жертву несущественной части производительности, то стоит
для начала определиться: а что же мы будем "заворачивать"? В качестве
примера я, пожалуй, буду использовать &lt;strong&gt;Blitz&lt;/strong&gt;, как самый оптимальный
вариант (по крайней мере с моей точки зрения). Начать стоит как обычно с пустой заготовки для класса.&lt;/p&gt;
&lt;p&gt;Далее следует решить какие все же модификации мы будем производить для
собственного удобства над стандартным решением. Попробую привести
несколько примеров в отношении &lt;strong&gt;Blitz&lt;/strong&gt;, для начала хочу обратить
внимание, что при внимательном прочтении все той же статьи от
разработчика этого шаблонизатора, можно обнаружить, что модуль
показывает более высокие показатели производительности при однократном
вызове метода &lt;em&gt;set&lt;/em&gt;. Достичь это можно выполнением этого метода с
указанием в качестве одного из входных параметров "многоуровнего"
массива, составленного специальным образом (надеюсь Вы все же к этому
моменту уже успели прочитать неоднократно упоминавшуюся статью, и
представляете принцип работы модуля). Написание механизма составления
такого массива позволит как сократить время разработки, так и сэкономит
драгоценные миллисекунды, вычитаемые из свободного времени посетителей
сайта в процессе генерации страницы.&lt;/p&gt;
&lt;p&gt;В любом случае понадобится переменная для его хранения:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TemplateEngine&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
    &lt;span class="c1"&gt;//можно сразу указать указать путь к папке с шаблонами&lt;/span&gt;
    &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="nx"&gt;Blitz&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'./template/'&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$template&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s1"&gt;'.tpl'&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;А также метод, переопределяющий стандартный &lt;em&gt;set&lt;/em&gt; на метод, добавляющий
новые значения к нашему массиву (хотя можно и любое другое понравившееся
название использовать):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$caption&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$caption&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;После чего оригинальный &lt;em&gt;set&lt;/em&gt; можно использовать уже непосредственно
перед &lt;em&gt;parse&lt;/em&gt;, с указанием уже собранного массива в качестве параметра.
За компанию позволю произвести себе еще одну модификацию: в подавляющем
большинстве случаев &lt;em&gt;parse&lt;/em&gt; используется в совокупности с &lt;strong&gt;echo&lt;/strong&gt;,
чтобы не указывать каждый раз это слово - можно включить его прямо в наш
класс:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;count&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;array&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;array&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;engine&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Еще одним возможным вариантом модификации может стать обработка всех
(или какой-то части, если есть необходимость) динамических данных с
помощью какой-либо функции, например это актуально для
&lt;strong&gt;htmlspecialchars&lt;/strong&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;set&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$caption&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$caption&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;rawset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$caption&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nv"&gt;$caption&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;is_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;foreach&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="nv"&gt;$caption&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nv"&gt;$this&lt;/span&gt;&lt;span class="o"&gt;-&amp;gt;&lt;/span&gt;&lt;span class="na"&gt;html&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$array&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;htmlspecialchars&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$array&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;ENT_QUOTES&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Как нетрудно заметить, в методе используется рекурсия, так как структура
передаваемых параметром массивов неизвестна.&lt;/p&gt;
&lt;p&gt;Надеюсь написанный выше текст подтолкнет Вас к действию или хотябы
заставит задуматься над имеющимся выбором, если же Вы читали его лишь
"для общего развития", то тем более хочется сказать Вам огромное
&lt;em&gt;Спасибо за то, что дочитали до конца это повествование.&lt;/em&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sat, 26 Jan 2008 15:25:00 +0300</pubDate><guid>tag:www.insight-it.ru,2008-01-26:php/2008/shablonizaciya/</guid><category>blitz</category><category>PHP</category><category>Smarty</category><category>template</category><category>template engine</category><category>интернет</category><category>ООП</category><category>разработка</category><category>шаблон</category><category>шаблонизация</category></item></channel></rss>