<?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/twitter/feed/index.xml" rel="self"></atom:link><lastBuildDate>Sat, 31 Mar 2012 00:08:00 +0400</lastBuildDate><item><title>Twitter Storm</title><link>https://www.insight-it.ru//highload/2012/twitter-storm/</link><description>&lt;p&gt;&lt;em&gt;&lt;a href="https://www.insight-it.ru/goto/964382fd/" rel="nofollow" target="_blank" title="https://github.com/nathanmarz/storm/"&gt;Storm&lt;/a&gt; является распределенной
системой для выполнения вычислений в реальном времени.&lt;/em&gt; Она родилась в
рамках проекта Backtype, который специализировался на аналитике твитов и
который в июле 2011 был приобретен &lt;a href="/tag/twitter/"&gt;Twitter&lt;/a&gt;. Так же как
&lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; &lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt; предоставляет набор
базовых абстракций, инструментов и механизмов для пакетной обработки
данных, &lt;strong&gt;Twitter Storm&lt;/strong&gt; делает это для задачи обработки данных &lt;em&gt;в
режиме реального времени&lt;/em&gt;. Хотите узнать в чем их отличие?&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="otlichie"&gt;Отличие&lt;/h2&gt;
&lt;p&gt;Не смотря на то, что &lt;em&gt;Storm&lt;/em&gt; изначально появился на свет в процессе
неудачных попыток приспособить &lt;em&gt;Hadoop&lt;/em&gt; к задаче обработки данных в
реальном времени, сравнивать их некорректно. Никакой хак или патч не
сможет заставить Hadoop работать по-настоящему в режиме реального
времени, так как в его основе лежит фундаментально другая концепция и
набор принципов, которые актуальны лишь в контексте задачи пакетной
обработки данных. &lt;strong&gt;Storm&lt;/strong&gt; можно представить как &lt;strong&gt;"Hadoop для
вычислений в реальном времени"&lt;/strong&gt;, но по факту между ними нет практически
ничего общего, кроме изначально-распределенной природы, слегка похожей
архитектуры, работы внутри JVM и публичной доступности. Для понимания
задачи, которая стоит перед Storm, лучше взглянуть на то, как она обычно
решается.&lt;/p&gt;
&lt;p&gt;Традиционно, если перед проектом или бизнесом вставала задача обработки
какой-то информации в реальном времени, то она в итоге сводилась к
цепочке преобразований данных и распределялась по серверам, которые их
выполняют и передают результаты друг другу посредством сообщений и
очередей-посредников. При таком подходе &lt;em&gt;существенная&lt;/em&gt; часть времени
уходила на маршрутизацию сообщений, настройку и развертывание новых
промежуточных очередей и обработчиков, обеспечение отказоустойчивости и
надежности. По сути &lt;strong&gt;Storm&lt;/strong&gt; берет все вышеперечисленное на себя,
позволяя разработчикам сосредоточиться на реализации логики обработки
сообщений.&lt;/p&gt;
&lt;h2 id="osobennosti"&gt;Особенности&lt;/h2&gt;
&lt;p&gt;Итак, основные особенности Storm, вытекающие из требований к подобным
системам:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Три основных варианта использования, но ими он не ограничивается:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Обработка потоков сообщений&lt;/strong&gt; &lt;em&gt;(stream processing)&lt;/em&gt; в реальном
времени, с возможностью внесения изменений во внешние базы данных;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Постоянные вычисления&lt;/strong&gt;&amp;nbsp;&lt;em&gt;(continuous computation)&lt;/em&gt; на основе
источников данных с публикацией результатов произвольным клиентам в
реальном времени;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Распределенные удаленные вызовы&lt;/strong&gt; &lt;em&gt;(distributed RPC)&lt;/em&gt; с
выполнением комплексных вычислений параллельно во время запроса.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Масштабируемость:&lt;/strong&gt; Storm может обрабатывать огромное количество
сообщений в секунду. Для масштабирование необходимо лишь добавить
сервера в кластер и увеличить параллельность в настройках топологии. В
одном из первых приложений для Storm обрабатывался 1 миллион сообщений в
секунду на кластере из 10 серверов, при этом выполнялось несколько сотен
запросов в секунду к внешней базе данных.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Гарантия отсутствия потерь данных:&lt;/strong&gt;&amp;nbsp;в отличии от других систем
обработки сообщений в реальном времени (например
&lt;a href="https://www.insight-it.ru/goto/9cb3bfa0/" rel="nofollow" target="_blank" title="http://incubator.apache.org/s4"&gt;S4&lt;/a&gt; от Yahoo!) это свойство изначально
является частью архитектуры Storm.&amp;nbsp;Для этого используется механизм
подтверждения&amp;nbsp;&lt;em&gt;(acknowledgement)&lt;/em&gt;&amp;nbsp;успешной обработки каждого конкретного
сообщения.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Стабильность:&lt;/strong&gt;&amp;nbsp;в то время как &lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt; позволительны
простои по несколько часов, так как он априори не является системой
реального времени, одной из основных целей Storm является стабильная
бесперебойная работа кластера, с максимально безболезненным его
управлением.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Защита от сбоев:&lt;/strong&gt;&amp;nbsp;если что-то пошло не так во время выполнения
вычисления, Storm переназначит задачи и попробует снова. В его задачи
входит обеспечение бесконечной работы вычислений (или до момента
запланированной или ручной остановки).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Независимость от языка программирования:&lt;/strong&gt; в то время как большая
часть системы написана на &lt;a href="/tag/clojure/"&gt;Clojure&lt;/a&gt; и работает в
&lt;a href="/tag/jvm/"&gt;JVM&lt;/a&gt;, сами компоненты системы могут быть реализованы на
любом языке, что удобно для проектов, использующих в основном другие
технологии.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;У Вас уже могло сложиться общее представление, о том что собой
представляет &lt;strong&gt;Twitter Storm&lt;/strong&gt; и насколько он актуален лично для Вас или
Вашего проекта. Если интерес все еще не погас, предлагаю перейти к
концепции, предлагаемой Storm для разработки приложений под эту
платформу.&lt;/p&gt;
&lt;h2 id="kontseptsiia"&gt;Концепция&lt;/h2&gt;
&lt;p&gt;Для начала пройдемся по основным абстракциям, которые используются в
Storm:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Поток&lt;/strong&gt; &lt;em&gt;(Stream)&lt;/em&gt;: неограниченный поток сообщений, представленных в
виде кортежей (произвольных именованный список значений). При этом все
кортежи в одном потоке должны иметь одинаковую схему: элемент на каждой
позиции должен иметь один и тот же тип данных и значение.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Струя воды из крана&lt;/strong&gt;&amp;nbsp;&lt;em&gt;(Spout)&lt;/em&gt;: источник потоков, который берет их из какой-то внешней системы.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Cтруя состояния&lt;/strong&gt;&amp;nbsp;&lt;em&gt;(state spout)&lt;/em&gt;: предоставляет распределенный доступ к некому общему состоянию, которое кэшируется в памяти на исполнителях и синхронно обновляется при внешних изменениях. Таким образом возможно избежать обращений к внешней базе данных при обработке каждого сообщения. В случае с Twitter этим общим состоянием является сам
социальный граф.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Молния&lt;/strong&gt; &lt;em&gt;(Bolt)&lt;/em&gt;: обрабатывает входящие потоки и создает исходящие
потоки, производя какую-либо обработку данных (по сути здесь реализуется
основная бизнес-логика). Помимо этого никто не запрещает использовать
при обработке какие угодно внешние сервисы вроде &lt;a href="/tag/subd/"&gt;СУБД&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Топология&lt;/strong&gt; &lt;em&gt;(Topology)&lt;/em&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;em&gt;(shuffle)&lt;/em&gt;,
каждый получит по копии &lt;em&gt;(all)&lt;/em&gt;, хэш по определенным полям сообщения
&lt;em&gt;(fields)&lt;/em&gt;, один поток получает все сообщения &amp;nbsp;&lt;em&gt;(global)&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Таким образом, для создания приложения для обработки данных в реальном
времени с использованием &lt;strong&gt;Storm&lt;/strong&gt;, необходимо:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Определить схему(ы) потока(ов) сообщений.&lt;/li&gt;
&lt;li&gt;Реализовать источник(и) сообщений, основанные на парсинге каких-то
    внешних данных (для Backtype это был Twitter firehose, поток всех
    твитов) или реакции на события (допустим действия пользователей в
    виде HTTP-запросов).&lt;/li&gt;
&lt;li&gt;Реализовать обработчик(и) сообщений, которые преобразуют входящие
    сообщения и либо создают новые потоки сообщений, либо как-то влияют
    на внешний мир, например изменяя что-то в базе данных (они
    используют &lt;a href="/tag/cassandra/"&gt;Cassandra&lt;/a&gt; для этого).&lt;/li&gt;
&lt;li&gt;Объединить реализованные компоненты в топологию и запустить её на
    кластере.&lt;/li&gt;
&lt;li&gt;При необходимости оптимизировать систему, включив общее состояние в
    топологию.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;С точки зрения разработчика приложения большего знать и не нужно, но
самое интересное происходит как раз дальше. Что собой представляет
Storm-кластер и как с его помощью исполняется реализованное описанным
выше способом приложение?&lt;/p&gt;
&lt;h2 id="arkhitektura"&gt;Архитектура&lt;/h2&gt;
&lt;p&gt;Проект очень сильно завязан на &lt;a href="/tag/zookeeper/"&gt;Zookeeper&lt;/a&gt; для
координации работы кластера, с чем он очень неплохо справляется. Все
остальные компоненты системы системы не содержат в себе состояния, что
обеспечивает их быстрый запуск, даже после &lt;code&gt;kill -9&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Storm Cluster" class="responsive-img" src="https://www.insight-it.ru/images/storm-cluster.png" title="Storm Cluster"/&gt;&lt;/p&gt;
&lt;p&gt;В остальном все достаточно просто:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Мастер-сервер &lt;em&gt;(Nimbus)&lt;/em&gt; отвечает за распространение кода,
    распределение задач и мониторинг сбоев.&lt;/li&gt;
&lt;li&gt;На каждом сервере в кластере запускается процесс-надсмотрщик
    &lt;em&gt;(Supervisor)&lt;/em&gt;, который запускает локально потоки исполнения,
    отвечающие за выполнение назначенных ему компонентов топологий.&lt;/li&gt;
&lt;li&gt;Передача сообщений между компонентами топологий осуществляется
    напрямую, посредством &lt;a href="/tag/zeromq/"&gt;ZeroMQ&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Топологии являются &lt;a href="/tag/thrift/"&gt;Thrift&lt;/a&gt;-структурами, а
    мастер-сервер - &lt;a href="/tag/thrift/"&gt;Thrift&lt;/a&gt;-сервисом, что позволяет
    осуществлять регистрацию топологий и другие операции программно из
    любого языка программирования.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Присутствующий в единственном экземпляре мастер-сервер является
единственной точкой отказа лишь на первый взгляд. По факту он
используется лишь для внесение изменений в кластер и топологии, так что
его непродолжительное отсутствие не повлияет на функционирование
запущенных вычислений. А так как состояние кластера хранится в
&lt;em&gt;Zookeeper&lt;/em&gt;, то запуск мастера на другой машине в случае аппаратного
сбоя - вопрос лишь грамотно настроенного мониторинга и максимум одной
минуты.&lt;/p&gt;
&lt;p&gt;Используемый механизм подтверждений успешной обработки сообщения
&lt;em&gt;(acknowledgement)&lt;/em&gt; гарантирует, что все сообщения, попавшие в систему,
рано или поздно будут обработаны, даже при локальных сбоях оборудования.
Хотя более глобальные катаклизмы вроде "потери" стойки все же могут
нарушить функционирование системы, про работу в нескольких датацентрах
речь также не идет.&lt;/p&gt;
&lt;h2 id="plany-na-budushchee"&gt;Планы на будущее&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Использование &lt;a href="https://www.insight-it.ru/goto/6984b642/" rel="nofollow" target="_blank" title="http://incubator.apache.org/mesos"&gt;Mesos&lt;/a&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;h2 id="podvodim-itogi"&gt;Подводим итоги&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;На самом деле подход, лежащий в основе Storm, не является чем-то
кардинально-новым. Помимо упоминавшегося выше S4 можно найти еще
несколько альтернатив, пускай и менее близких по идеологии. Подробнее
про эту тему можно узнать погуглив &lt;strong&gt;&lt;a href="https://www.insight-it.ru/goto/c81ea66c/" rel="nofollow" target="_blank" title="http://www.google.com/search?q=complex+event+processing"&gt;complex event processing&lt;/a&gt;&lt;/strong&gt;
или &lt;strong&gt;&lt;a href="https://www.insight-it.ru/goto/14ea9c79/" rel="nofollow" target="_blank" title="http://www.google.com/search?q=real-time+stream+processing"&gt;real-time stream processing&lt;/a&gt;&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Storm&lt;/strong&gt; выделяет из их числа простота, гибкость, масштабируемость и
отказоустойчивость в одном флаконе. Обеспечивает это в первую очередь
простая и понятная архитектура, основанная на (уже) проверенном временем
и многими проектами распределенном координаторе в виде &lt;strong&gt;Zookeeper&lt;/strong&gt;.&lt;/li&gt;
&lt;li&gt;Хоть за проектом и стоит крупный интернет-проект в лице
&lt;a href="https://www.insight-it.ru/highload/2011/arkhitektura-twitter-dva-goda-spustya/"&gt;Twitter&lt;/a&gt;,
он достаточно молод и нужно быть морально готовым к возможным сбоям и
неудачным моментам. Плюс не забывайте, что существенная часть написана
на &lt;strong&gt;Clojure&lt;/strong&gt; - для, пожалуй, большинства разработчиков изучение
исходников проекта будет капитальным "выносом мозга". Мое первое
знакомство с &lt;strong&gt;Lisp&lt;/strong&gt; &lt;em&gt;(Clojure - его диалект, работающий в
JVM)&lt;/em&gt;&amp;nbsp;надолго засело в памяти из-за обилия скобочек за каждым углом :)&lt;/li&gt;
&lt;li&gt;В любом случае из доступных &lt;a href="/tag/opensource/"&gt;opensource&lt;/a&gt; реализаций
систем для распределенных вычислений в реальном времени &lt;strong&gt;Storm&lt;/strong&gt;&amp;nbsp;на мой
взгляд является наиболее перспективным для применения в
интернет-проектах.&lt;/li&gt;
&lt;li&gt;Если Вашему проекту нужна лишь одна-две топологии и особо большого
кластера не планируется, то подобную схему достаточно не сложно
реализовать и просто посредством &lt;strong&gt;Zookeeper&lt;/strong&gt; + &lt;strong&gt;ZeroMQ&lt;/strong&gt; или
альтернативных технологий. Это избавит проект от возможных заморочек с
Clojure и другими "особенностями" Storm, ценой вероятно существенно
большей собственной кодовой базы, которую придется самостоятельно
тестировать и поддерживать. Какой путь ближе - команда каждого проекта
решает для себя сама.&lt;/li&gt;
&lt;li&gt;Помимо различных вариаций&amp;nbsp;&lt;strong&gt;веб-аналитики&lt;/strong&gt; заманчивыми применениями
подобной системы в Интернете может стать:&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;построение индекса для поисковых систем&lt;/strong&gt;, на сколько я знаю от
&lt;a href="/tag/mapreduce/"&gt;MapReduce&lt;/a&gt; здесь отказался только
&lt;a href="https://www.insight-it.ru/highload/2011/arkhitektura-google-2011/"&gt;Google&lt;/a&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;li&gt;&lt;em&gt;предлагаем свои варианты в комментариях&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Удачи в построении приложений для вычислений в реальном времени и &lt;a href="/feed/"&gt;до встречи на страницах &lt;strong&gt;Insight IT&lt;/strong&gt;&lt;/a&gt;!&lt;/p&gt;
&lt;h2 id="istochniki-informatsii"&gt;Источники информации&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/6f56bb97/" rel="nofollow" target="_blank" title="http://www.infoq.com/presentations/Storm"&gt;Видео презентации проекта&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/fbfa7e01/" rel="nofollow" target="_blank" title="http://www.slideshare.net/nathanmarz/storm-distributed-and-faulttolerant-realtime-computation"&gt;Слайды с презентации проекта&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/a027c9d7/" rel="nofollow" target="_blank" title="https://github.com/nathanmarz/storm"&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, 31 Mar 2012 00:08:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-03-31:highload/2012/twitter-storm/</guid><category>Clojure</category><category>JVM</category><category>opensource</category><category>real time</category><category>Storm</category><category>Thrift</category><category>Twitter</category><category>Twitter Storm</category><category>ZeroMQ</category><category>ZooKeeper</category></item><item><title>Кардинальный переворот в архитектуре поиска Twitter</title><link>https://www.insight-it.ru//highload/2011/kardinalnyjj-perevorot-v-arkhitekture-poiska-twitter/</link><description>&lt;p&gt;Не успел я опубликовать &lt;a href="https://www.insight-it.ru/highload/2011/arkhitektura-twitter-dva-goda-spustya/"&gt;обновление об архитектуре Twitter&lt;/a&gt;, как
они снова перекроили половину проекта =) На этот раз к паре
&lt;a href="/tag/ruby/"&gt;Ruby&lt;/a&gt;+&lt;a href="/tag/scala/"&gt;Scala&lt;/a&gt; активно вплелись технологии из
мира &lt;a href="/tag/java/"&gt;Java&lt;/a&gt;. Наибольшим изменениям подверглась подсистема
поиска твитов , о которой сегодня и пойдет речь.
&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="novaia-arkhitektura-poiska-tvitov"&gt;Новая архитектура поиска твитов&lt;/h2&gt;
&lt;h3 id="backend"&gt;Backend&lt;/h3&gt;
&lt;p&gt;Поиск осуществляется теперь не с помощью&amp;nbsp;&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;-кластера, а посредством версии &lt;a href="/tag/lucene/"&gt;Lucene&lt;/a&gt;, адаптированной для работы в реальном времени. Разработка этой подсистемы началась весной прошлого года, но полноценно использоваться она начала лишь недавно.&lt;/p&gt;
&lt;p&gt;Так как поиск в Twitter является одной из самых часто используемых поисковых систем в мире (более миллиарда поисковых запросов в день), то требования к новой
системе поиска были сопоставимо строгими:
-   Обработка более 12000 запросов в секунду
-   Индексация потока в 1000 новых твитов в секунду
-   Задержка между написанием твита и его появлением в индексе должна
    быть менее 10 секунд&lt;/p&gt;
&lt;p&gt;Lucene была взята за основу, так как на сегодняшний день это одно из
лучших решений для реализации поиска в мире opensource. Но в текущей ее
реализации она не была приспособлена к поиску в реальном времени.
Команде Twitter пришлось переписать существенную часть основных структур
в памяти, особенно списки записей. При этом внешний API Lucene остался
неизменным, что позволило использовать поисковые алгоритмы в практически
неизменном виде. Среди основных изменений в Lucene можно выделить:&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;эффективное раннее прекращение обработки запроса.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Все вышеперечисленные изменения находятся в процессе публикации обратно
в Lucene, какие-то прямо в основную ветку, какие-то в отдельную для
поиска в реальном времени.&lt;/p&gt;
&lt;p&gt;После внедрения этой системы поиск стал потреблять лишь 5% доступных ему
ресурсов, что оставило приличный запас для роста даже по меркам
невероятно быстро развивающегося Twitter. Новая подсистема индексации
способна обрабатывать в 50 раз больше твитов в секунду, чем они получали
на момент запуска, что также является очень позитивным показателем.
Помимо улучшения производительности, Lucene повысила и качество поиска,
а также открыла простор для новых улучшений в этом направлении.&lt;/p&gt;
&lt;h3 id="frontend"&gt;Frontend&lt;/h3&gt;
&lt;p&gt;Кардинальный переворот в этой части системы можно описать одной
фразой:&amp;nbsp;&lt;a href="/tag/ror/"&gt;Ruby on Rails&lt;/a&gt; заменен на Java-сервер, который они
назвали&amp;nbsp;&lt;a href="/tag/blender/"&gt;Blender&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;За неделю до развертывания Blender, количество поисков по твитам
существенно возросло из-за &lt;code&gt;#tsunami&lt;/code&gt; в Японии. Среднее время поиска
достигало 800-900мс.&lt;/p&gt;
&lt;p&gt;&lt;img alt="Blender и #tsunami" class="left" src="https://www.insight-it.ru/images/blender-tsunami.jpg" title="Blender и #tsunami"/&gt;&lt;/p&gt;
&lt;p&gt;После введения Blender в эксплуатацию среднее время отклика 95% запросов
упало втрое: до 250мс, при этом уровень использования вычислительных
ресурсов на frontend серверах упал вдвое. Тот же поток запросов стало
возможным обрабатывать меньшим количеством серверов.&lt;/p&gt;
&lt;p&gt;Чтобы понять, откуда взялся такой прирост производительности, необходимо
показать в чем были слабые стороны старого поиска на Ruby on Rails. На
каждом frontend сервере было запущено фиксированное количество
однопоточных Rails процессов, каждый из которых занимался следующим:&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;Они давно понимали, что синхронные запросы ведут к неэффективному
использованию вычислительных ресурсов. Со временем накопилось много
технически неудачных моментов, что делало все сложнее введение нового
функционала и поддержание надежности системы. Blender позволил
преодолеть эти функции следующим образом:&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;strong&gt;Элегантная работа с зависимостями сервисов.&lt;/strong&gt; Алгоритм обработки
    запросов автоматически обрабатывает зависимости между используемыми
    сервисами.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="chto-zhe-sobstvenno-predstavliaet-soboi-blender"&gt;Что же, собственно, представляет собой Blender?&lt;/h3&gt;
&lt;p&gt;Это HTTP и &lt;a href="/tag/thrift/"&gt;Thrift&lt;/a&gt; сервер, разработанный на основе
&lt;a href="/tag/netty/"&gt;Netty&lt;/a&gt;, масштабируемой неблокирующей клиент-серверной
библиотеки на Java, позволяющей легко и быстро разрабатывать клиенты и
серверы для различных протоколов. Выбор пал именно на неё, а не на
аналоги (например Jetty или Mina) из-за более чистого API, детальной
документации и, что более важно, так как некоторые другие сервисы в
Twitter уже используют её. Интеграции с Thrift у нее не было, но этот
вопрос решился написанием простого кодека, обрабатывающего сообщения на
низком уровне.&lt;/p&gt;
&lt;p&gt;Обработка поисковых запросов представляет собой цепочку запросов к
внутренним сервисами, обработку ответов и генерацию результата.
Внутренние сервисы имеют зависимости, которые можно представить в виде
ацикличного направленного графа. После топологической сортировки графа
Blender получает последовательность выполнения запросов, которые
назначаются к выполнению в поток Netty, что в совокупности с
обработчиками событий и образует workflow обработки поисковых запросов.&lt;/p&gt;
&lt;h2 id="zakliuchenie_1"&gt;Заключение&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Blender - схема работы" class="right" src="https://www.insight-it.ru/images/blender-workflow.jpg" title="Blender - схема работы"/&gt;
Эта диаграмма демонстрирует текущую архитектуру поиска с использованием
Blender и Lucene: все входящие поисковые запросы проходят через
аппаратный балансировщик нагрузки и попадают в Blender, где они
анализируются и перераспределяются между внутренними сервисами с
использованием workflow для обработки зависимостей и генерации
результатов.&lt;/p&gt;
&lt;p&gt;На моей памяти эти нововведения в Twitter - практически единственный
случай, когда крупный успешный проект настолько кардинально поменял
основную часть стека используемых технологий. Да, они получили
существенный выигрыш в производительности не в ущерб масштабируемости,
но не поменяли же они большую часть команды разработчиков с
Ruby-программистов на Java-программистов... Понятно, что это лишь
инструменты, но довольно приличная часть людей, особенно те, кто в
возрасте, не способны резко переключиться с привычных технологий на
что-то совершенно новое. Хотя, скорее всего, в команде Twitter особо не
было разработчиков "за 40", так что для них это не было особой
проблемой.&lt;/p&gt;
&lt;h2 id="istochnik-informatsii"&gt;Источник информации&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/ecede8b6/" rel="nofollow" target="_blank" title="https://blog.twitter.com/2011/twitter-search-now-3x-faster"&gt;Twitter Search 3x Faster&lt;/a&gt; (cпасибо Сергею Гуляеву за предоставленную ссылку)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/ddafc7f8/" rel="nofollow" target="_blank" title="https://blog.twitter.com/2010/twitters-new-search-architecture"&gt;Twitter's New Search Architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Fri, 15 Apr 2011 23:03:00 +0400</pubDate><guid>tag:www.insight-it.ru,2011-04-15:highload/2011/kardinalnyjj-perevorot-v-arkhitekture-poiska-twitter/</guid><category>Blender</category><category>Lucene</category><category>netty</category><category>Twitter</category></item><item><title>Архитектура Twitter. Два года спустя.</title><link>https://www.insight-it.ru//highload/2011/arkhitektura-twitter-dva-goda-spustya/</link><description>&lt;p&gt;В далеком 2008м я уже публиковал статью про &lt;a href="https://www.insight-it.ru/highload/2008/arkhitektura-twitter/"&gt;архитектуру Twitter&lt;/a&gt;, но время летит
стремительно и она уже абсолютно устарела. За это время аудитория
Twitter росла просто фантастическими темпами и многое поменялось и с
технической точки зрения. Интересно что новенького у одного из самых
популярных социальных интернет-проектов?&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;3 год, 2 месяца и 1 день потребовалось Twitter, чтобы набрать 1
    миллиард твитов&lt;/li&gt;
&lt;li&gt;На сегодняшний день, чтобы отправить миллиард твитов пользователям
    нужна всего одна неделя&lt;/li&gt;
&lt;li&gt;752% рост аудитории за 2008 год&lt;/li&gt;
&lt;li&gt;1358% рост аудитории за 2009 год&amp;nbsp;(без учета API, по данным comScore)&lt;/li&gt;
&lt;li&gt;175 миллионов зарегистрированных пользователей на сентябрь 2010 года&lt;/li&gt;
&lt;li&gt;460 тысяч регистраций пользователей в день&lt;/li&gt;
&lt;li&gt;9й сайт в мире по популярности (по данным Alexa, год назад был на 12
    месте)&lt;/li&gt;
&lt;li&gt;50 миллионов твитов в день год назад, 140 миллионов твитов в день
    месяц назад, 177 миллионов твитов в день на 11 марта 2011г.&lt;/li&gt;
&lt;li&gt;Рекорд по количеству твитов за секунду 6939, установлен через минуту
    после того, как Новый Год 2011 наступил в Японии&lt;/li&gt;
&lt;li&gt;600 миллионов поисков в день&lt;/li&gt;
&lt;li&gt;Лишь 25% трафика приходится на веб сайт, остальное идет через API&lt;/li&gt;
&lt;li&gt;Росто числа мобильных пользователей за последний год 182%&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;6 миллиардов&lt;/strong&gt; запросов к API в день, около 70 тысяч в секунду&lt;/li&gt;
&lt;li&gt;8, 29, 130, 350, 400 - это количество сотрудников Twitter на январь
    2008, январь 2009, январь 2010, январь и март 2011, соответственно&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Самая свежая &lt;a href="https://www.insight-it.ru/goto/682783c0/" rel="nofollow" target="_blank" title="http://blog.twitter.com/2011/03/numbers.html"&gt;статистика про Twitter&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="platforma"&gt;Платформа&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; + &lt;code&gt;mod_proxy&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/unicorn/"&gt;Unicorn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/ruby/"&gt;Ruby&lt;/a&gt; +&amp;nbsp;&lt;a href="/tag/ror/"&gt;Ruby on Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/scala/"&gt;Scala&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/flock/"&gt;Flock&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/kestrel/"&gt;Kestrel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/cassandra/"&gt;Cassandra&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/scribe/"&gt;Scribe&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt;, &lt;a href="/tag/hbase/"&gt;HBase&lt;/a&gt; и &lt;a href="/tag/pig/"&gt;Pig&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Сравните с аналогичным разделом предыдущей статьи о Twitter - увидите
много новых лиц, подробнее ниже.&lt;/p&gt;
&lt;h2 id="oborudovanie"&gt;Оборудование&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Сервера расположены в NTT America&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;h2 id="chto-takoe-tvit"&gt;Что такое твит?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Сообщение длиной до 140 символов + метаданные&lt;/li&gt;
&lt;li&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;/li&gt;
&lt;/ul&gt;
&lt;h2 id="arkhitektura"&gt;Архитектура&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Процесс обработки запроса в Twitter" class="responsive-img" src="https://www.insight-it.ru/images/twitter-request-flow.jpeg" title="Процесс обработки запроса в Twitter"/&gt;&lt;/p&gt;
&lt;h3 id="unicorn"&gt;Unicorn&lt;/h3&gt;
&lt;p&gt;Сервер приложений для Rails:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Развертывание новых версий кода &lt;strong&gt;без простоя&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;На 30% меньше расход вычислительных ресурсов и оперативной памяти,
    по сравнению с другими решениями&lt;/li&gt;
&lt;li&gt;Перешли с &lt;code&gt;mod_proxy_balancer&lt;/code&gt; на &lt;code&gt;mod_proxy_pass&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rails"&gt;Rails&lt;/h3&gt;
&lt;p&gt;Используется в основном для генерации страниц, работа за сценой
реализована на чистом Ruby или Scala.&lt;/p&gt;
&lt;p&gt;Столкнулись со следующими проблемами:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Проблемы с кэшированием, особенно по части инвалидации&lt;/li&gt;
&lt;li&gt;ActiveRecord генерирует не самые удачные SQL-запросы, что замедляло
    время отклика&lt;/li&gt;
&lt;li&gt;Высокие задержки в очереди и при репликации&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="memcached"&gt;memcached&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;memcached не идеален. Twitter начал сталкиваться с Segmentation
    Fault в нем очень рано.&lt;/li&gt;
&lt;li&gt;Большинство стратегий кэширования основываются на длинных TTL
    (более минуты).&lt;/li&gt;
&lt;li&gt;Вытеснение данных делает его непригодным для важных конфигурационных
    данных (например флагов "темного режима", о котором пойдет речь
    ниже).&lt;/li&gt;
&lt;li&gt;Разбивается на несколько пулов для улучшения производительности и
    снижения риска вытеснения.&lt;/li&gt;
&lt;li&gt;Оптимизированная библиотека для доступа к memcached из Ruby на
    основе libmemcached + FNV hash, вместо чистого Ruby и md5.&lt;/li&gt;
&lt;li&gt;Twitter является одним их наиболее активных проектов, участвующих в
    разработке libmemcached.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mysql"&gt;MySQL&lt;/h3&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;Репликация однопоточна и происходит недостаточно быстро.&lt;/li&gt;
&lt;li&gt;Данные социальных сетей плохо подходят для реляционных СУБД:&lt;ul&gt;
&lt;li&gt;NxN отношения, социальный граф и обход деревьев - не самые
    подходящие задачи для таких баз данных&lt;/li&gt;
&lt;li&gt;Проблемы с дисковой подсистемой (выбор файловой системы,
    noatime, алгоритм планирования)&lt;/li&gt;
&lt;li&gt;ACID практически не требуется&lt;/li&gt;
&lt;li&gt;Для очередей также практически непригодны&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Twitter сталкивался с большими проблемами касательно таблиц
    пользователей и их статусов&lt;/li&gt;
&lt;li&gt;Читать данные с мастера при Master/Slave репликации = медленная
    смерть&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="flockdb"&gt;FlockDB&lt;/h3&gt;
&lt;p&gt;Масштабируемое хранилище для данных социального графа:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Разбиение данных через Gizzard&lt;/li&gt;
&lt;li&gt;Множество серверов MySQL в качестве низлежащей системы хранения&lt;/li&gt;
&lt;li&gt;В Twitter содержит 13 миллиардов ребер графа и обеспечивает 20 тысяч
    операций записи и 100 тысяч операций чтения в секунду&lt;/li&gt;
&lt;li&gt;Грани хранятся и индексируются в обоих направлениях&lt;/li&gt;
&lt;li&gt;Поддерживает распределенный подсчет количества строк&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/4fe0530b/" rel="nofollow" target="_blank" title="https://github.com/twitter/flockdb"&gt;Open source!&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Среднее время на выполнение операций:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Подсчет количества строк: 1мс&lt;/li&gt;
&lt;li&gt;Временные запросы: 2мс&lt;/li&gt;
&lt;li&gt;Запись: 1мс для журнала, 16мс для надежной записи&lt;/li&gt;
&lt;li&gt;Обход дерева: 100 граней/мс&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Подробнее про эволюцию систем хранения данных в Twitter &lt;a href="https://www.insight-it.ru/goto/32077a90/" rel="nofollow" target="_blank" title="http://www.slideshare.net/nkallen/q-con-3770885"&gt;в презентации
Nick Kallen&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="cassandra"&gt;Cassandra&lt;/h3&gt;
&lt;p&gt;Распределенная система хранения данных, ориентированная на работу в
реальном времени:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Изначально разработана в &lt;a href="/tag/facebook/"&gt;Facebook&lt;/a&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;/li&gt;
&lt;li&gt;&lt;del&gt;Планируется полный переход на нее по
    следующему алгоритму:&lt;/del&gt;&lt;ul&gt;
&lt;li&gt;&lt;del&gt;Все твиты пишутся и в Cassandra
    и в MySQL&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;Динамически часть операций
    чтения переводится на Cassandra&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;Анализируется реакция системы,
    что сломалось&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;Полностью отключаем чтение из
    Cassandra, чиним неисправности&lt;/del&gt;&lt;/li&gt;
&lt;li&gt;&lt;del&gt;Начинаем сначала&lt;/del&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.insight-it.ru/goto/e83e4e8e/" rel="nofollow" target="_blank" title="http://engineering.twitter.com/2010/07/cassandra-at-twitter-today.html"&gt;Обновление:&lt;/a&gt;&lt;/strong&gt; стратегия по поводу использования Cassandra изменилась, попытки
    использовать её в роли основного хранилища для твитов прекратились,
    но она продолжает использоваться для аналитики и географической
    информации.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Подробнее почему Twitter пришел к решению использовать Cassandra можно
прочитать &lt;a href="https://www.insight-it.ru/goto/ffc31d1/" rel="nofollow" target="_blank" title="http://www.slideshare.net/ryansking/scaling-twitter-with-cassandra"&gt;в отдельной презентации&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Помимо всего прочего Cassandra&amp;nbsp;&lt;del&gt;планируется использовать&lt;/del&gt; используется для аналитики в реальном времени.&lt;/p&gt;
&lt;h3 id="scribe"&gt;Scribe&lt;/h3&gt;
&lt;p&gt;Пользователи Twitter генерируют огромное количество данных, около 15-25
Гб в минуту, более 12 Тб в день, и эта цифра удваивается несколько раз
в год.&lt;/p&gt;
&lt;p&gt;Изначально для сбора логов использовали &lt;code&gt;syslog-ng&lt;/code&gt;, но он очень быстро
перестал справляться с нагрузкой.&lt;/p&gt;
&lt;p&gt;Решение нашлось очень просто: &lt;a href="/tag/facebook/"&gt;Facebook&lt;/a&gt; столкнулся с
аналогичной проблемой и разработал проект Scribe, который был
опубликован в opensource.&lt;/p&gt;
&lt;p&gt;По сути это фреймворк для сбора и агрегации логов, основанный на
&lt;a href="/tag/thrift/"&gt;Thrift&lt;/a&gt;. Вы пишете текст для логов и указываете
категорию, остальное он берет на себя.&lt;/p&gt;
&lt;p&gt;Работает локально, надежен даже в случае потери сетевого соединения,
каждый узел знает только на какой сервер передавать логи, что позволяет
создавать масштабируемую иерархию для сбора логов.&lt;/p&gt;
&lt;p&gt;Поддерживаются различные системы для записи в данным, &amp;nbsp;в том числе
обычные файлы и HDFS (о ней ниже).&lt;/p&gt;
&lt;p&gt;Этот продукт полностью решил проблему Twitter со сбором логов,
используется около 30 различных категорий. В процессе использования была
создана и опубликована масса доработок. Активно сотрудничают с командой
Facebook в развитии проекта.&lt;/p&gt;
&lt;h3 id="hadoop"&gt;Hadoop&lt;/h3&gt;
&lt;p&gt;Как Вы обычно сохраняете 12Тб новых данных, поступающих каждый день?&lt;/p&gt;
&lt;p&gt;Если считать, что средняя скорость записи современного жесткого диска
составляет 80Мбайт в секунду, запись 12Тб данных заняла бы почти 48
часов.&lt;/p&gt;
&lt;p&gt;На одном даже очень большом сервере данную задачу не решить, логичным
решением задачи стало использование кластера для хранения и анализа
таких объемов данных.&lt;/p&gt;
&lt;p&gt;Использование кластерной файловой системы добавляет сложности, но
позволяет меньше заботиться о деталях.&lt;/p&gt;
&lt;p&gt;Hadoop Distributed File System (HDFS) предоставляет возможность
автоматической репликации и помогает справляться со сбоями оборудования.&lt;/p&gt;
&lt;p&gt;MapReduce framework позволяет обрабатывать огромные объемы данных,
анализируя пары ключ-значение.&lt;/p&gt;
&lt;p&gt;Типичные вычислительные задачи, которые решаются с помощью Hadoop в
Twitter:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Вычисление связей дружбы в социальном графе (&lt;code&gt;grep&lt;/code&gt; и &lt;code&gt;awk&lt;/code&gt; не
    справились бы, self join в MySQL на таблицах с миллиардами строк -
    тоже)&lt;/li&gt;
&lt;li&gt;Подсчет статистики (количество пользователей и твитов, например
    подсчет количества твитов занимает 5 минут при 12 миллиардах
    записей)&lt;/li&gt;
&lt;li&gt;Подсчет PageRank между пользователями для вычисления репутации.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;В твиттер используется бесплатный дистрибутив от Cloudera, версия Hadoop
0.20.1, данные храняться &lt;a href="https://www.insight-it.ru/goto/1ac5bba3/" rel="nofollow" target="_blank" title="https://github.com/kevinweil/hadoop-lzo"&gt;в сжатом по алгоритму LZO виде&lt;/a&gt;, библиотеки для работы с
данными опубликованы под названием
&lt;a href="https://www.insight-it.ru/goto/a1b5430e/" rel="nofollow" target="_blank" title="https://github.com/kevinweil/elephant-bird"&gt;elephant-bird&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="pig"&gt;Pig&lt;/h3&gt;
&lt;p&gt;Для того чтобы анализировать данные с помощью MapReduce обычно
необходимо разрабатывать код на Java, что далеко не все умеют делать, да
и трудоемко это.&lt;/p&gt;
&lt;p&gt;Pig представляет собой высокоуровневый язык, позволяющий
трансформировать огромные наборы данных шаг за шагом.&lt;/p&gt;
&lt;p&gt;Немного напоминает SQL, но намного проще. Это позволяет писать в 20 раз
меньше кода, чем при анализе данных с помощью обычных MapReduce работ.
Большая часть работы по анализу данных в Twitter осуществляется с
помощью Pig.&lt;/p&gt;
&lt;h3 id="dannye"&gt;Данные&lt;/h3&gt;
&lt;p&gt;Полу-структурированные данные:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;логи Apache, RoR, MySQL, A/B тестирования, процесса регистрации&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;/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;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;/li&gt;
&lt;li&gt;География&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Запутанные данные:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Социальный граф&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Что же они делают с этим всем?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Подсчет математического ожидания, минимума, максимума и дисперсии
    следующих показателей:&lt;ul&gt;
&lt;li&gt;Количество запросов за сутки&lt;/li&gt;
&lt;li&gt;Средняя задержка, 95% задержка&lt;/li&gt;
&lt;li&gt;Распределение кодов HTTP-ответов (по часам)&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;/li&gt;
&lt;li&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;Проблемы с сайтом (киты и роботы, подробнее ниже)&lt;/li&gt;
&lt;li&gt;Какие функциональные возможности цепляют пользователей?&lt;/li&gt;
&lt;li&gt;Какие функциональные возможности чаще используются популярными
    пользователями?&lt;/li&gt;
&lt;li&gt;Корректировка и предложение поисковых запросов&lt;/li&gt;
&lt;li&gt;A/B тестирование&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&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;Анализ эмоциональной окраски&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;li&gt;Обнаружения языка&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Подробнее про обработку данных &lt;a href="https://www.insight-it.ru/goto/3d4649ef/" rel="nofollow" target="_blank" title="http://www.slideshare.net/kevinweil/nosql-at-twitter-nosql-eu-2010"&gt;в презентации Kevin Weil&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="hbase"&gt;HBase&lt;/h3&gt;
&lt;p&gt;Twitter начинают строить настоящие сервисы на основе Hadoop, например
поиск людей:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HBase используется как изменяемая прослойка над HDFS&lt;/li&gt;
&lt;li&gt;Данные экспортируются из HBase c помощью периодической MapReduce
    работы:&lt;ul&gt;
&lt;li&gt;На этапе Map используются также данные из FlockDB и нескольких
    внутренних сервисов&lt;/li&gt;
&lt;li&gt;Собственная схема разбиения данных&lt;/li&gt;
&lt;li&gt;Данные подтягиваются через высокопроизводительный, горизонтально
    масштабируемый сервис на Scala (&lt;a href="https://www.insight-it.ru/goto/917f8c95/" rel="nofollow" target="_blank" title="http://www.slideshare.net/al3x/building-distributed-systems-in-scala"&gt;подробнее о построении распределенных сервисов на Scala&lt;/a&gt;)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;На основе HBase разрабатываются и другие продукты внутри Twitter.&lt;/p&gt;
&lt;p&gt;Основными её достоинствами являются гибкость и легкая интеграция с
Hadoop и Pig.&lt;/p&gt;
&lt;p&gt;По сравнению с Cassandra:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;"Их происхождение объясняет их сильные и слабые стороны"&lt;/li&gt;
&lt;li&gt;HBase построен на основе системы по пакетной обработке данных,
    высокие задержки, работает далеко не в реальном времени&lt;/li&gt;
&lt;li&gt;Cassandra построена с нуля для работы с низкими задержками&lt;/li&gt;
&lt;li&gt;HBase легко использовать при анализе данных как источник или место
    сохранения результатов, Cassandra для этого подходит меньше, но они
    работают над этим&lt;/li&gt;
&lt;li&gt;HBase на данный момент единственную точку отказа в виде мастер-узла&lt;/li&gt;
&lt;li&gt;В твиттере HBase используется для аналитики, анализа и создания
    наборов данных, а Cassandra - для онлайн систем&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="loony"&gt;Loony&lt;/h3&gt;
&lt;p&gt;Централизованная система управления оборудованием.&lt;/p&gt;
&lt;p&gt;Реализована с использованием:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/python/"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/django/"&gt;Django&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/8927633f/" rel="nofollow" target="_blank" title="http://www.lag.net/paramiko"&gt;Paraminko&lt;/a&gt; (реализация протокола SSH
    на Python, разработана и опубликована в opensource в Twitter)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Интегрирована с LDAP, анализирует входящую почту от датацентра и
автоматически вносит изменения в базу.&lt;/p&gt;
&lt;h3 id="murder"&gt;Murder&lt;/h3&gt;
&lt;p&gt;Система развертывания кода и ПО, основанная на протоколе BitTorrent.&lt;/p&gt;
&lt;p&gt;Благодаря своей P2P природе позволяет обновить более тысячи серверов за
30-60 секунд.&lt;/p&gt;
&lt;h3 id="kestrel"&gt;Kestrel&lt;/h3&gt;
&lt;p&gt;Распределенная очередь, работающая по протоколу memcache:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;set&lt;/code&gt; - поставить в очередь&lt;/li&gt;
&lt;li&gt;&lt;code&gt;get&lt;/code&gt; - взять из очереди&lt;/li&gt;
&lt;/ul&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;a href="/tag/scala/"&gt;Scala&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="daemony"&gt;Daemon'ы&lt;/h3&gt;
&lt;p&gt;Каждый твит обрабатывается с помощью daemon'ов.&lt;/p&gt;
&lt;p&gt;В unicorn обрабатываются только HTTP запросы, вся работа за сценой
реализована в виде отдельных daemon'ов.&lt;/p&gt;
&lt;p&gt;Раньше использовалось много разных демонов, по одному на каждую задачу
(Rails), но перешли к меньшему их количеству, способному решать
несколько задач одновременно.&lt;/p&gt;
&lt;h3 id="kak-oni-spravliaiutsia-s-takimi-tempami-rosta"&gt;Как они справляются с такими темпами роста?&lt;/h3&gt;
&lt;p&gt;Рецепт прост, но эффективен, подходит практически для любого
интернет-проекта:&lt;/p&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;p&gt;На словах звучит и правда примитивно, но на практике нужно предпринять
ряд мер, чтобы такой подход был бы реализуем:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Автоматический сбор метрик (причем в агрегированном виде)&lt;/li&gt;
&lt;li&gt;Построение графиков (RRD, Ganglia)&lt;/li&gt;
&lt;li&gt;Сбор и анализ&amp;nbsp;логов&lt;/li&gt;
&lt;li&gt;Все данные должны получаться с минимальной задержкой, как можно
    более близко к реальному времени&lt;/li&gt;
&lt;li&gt;Анализ:&lt;ul&gt;
&lt;li&gt;Из данных необходимо получать &lt;em&gt;информацию&lt;/em&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;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Примерами агрегированных метрик в Twitter являются "киты" и "роботы",
вернее их количество в единицу времени.&lt;/p&gt;
&lt;h5&gt;Что такое "робот"?&lt;/h5&gt;
&lt;p&gt;&lt;img alt="Twitter Робот" class="responsive-img" src="https://www.insight-it.ru/images/twitter-bot.jpg" title="Twitter Робот"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ошибка внутри Rails (HTTP 500)&lt;/li&gt;
&lt;li&gt;Непойманное исключение&lt;/li&gt;
&lt;li&gt;Проблема в коде или нулевой результат&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Что такое "кит"?&lt;/h5&gt;
&lt;p&gt;&lt;img alt="Twitter Кит" class="responsive-img" src="https://www.insight-it.ru/images/twitter-whale.jpg" title="Twitter Кит"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP ошибка 502 или 503&lt;/li&gt;
&lt;li&gt;В твиттер используется фиксированный таймаут в 5 секунд (лучше
    кому-то показать ошибку, чем захлебнуться в запросах)&lt;/li&gt;
&lt;li&gt;Убитый слишком длинный запрос к базе данных (mkill)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Значительное превышение нормального количества китов или роботов в
минуту является поводом для беспокойством.&lt;/p&gt;
&lt;p&gt;Реализован этот механизм простым bash-скриптом, который просматривает
агрегированные логи за последние 60 секунд, подсчитывает количество
китов/роботов и рассылает уведомления, если значение оказалось выше
порогового значения. Подробнее про работу команды оперативного
реагирования &lt;a href="https://www.insight-it.ru/goto/30562be/" rel="nofollow" target="_blank" title="http://www.slideshare.net/netik/billions-of-hits-scaling-twitter"&gt;в презентации John Adams&lt;/a&gt;.&lt;/p&gt;
&lt;h3 id="temnyi-rezhim"&gt;"Темный режим"&lt;/h3&gt;
&lt;p&gt;Для экстренных ситуаций в Twitter предусмотрен так называемый "темный
режим", который представляет собой набор механизмов для отключения
тяжелых по вычислительным ресурсам или вводу-выводу функциональных
частей сайта. Что-то вроде стоп-крана для сайта.&lt;/p&gt;
&lt;p&gt;Имеется около 60 выключателей, в том числе и полный режим "только для
чтения".&lt;/p&gt;
&lt;p&gt;Все изменения в настройках этого режима фиксируются в логах и сообщаются
руководству, чтобы никто не баловался.&lt;/p&gt;
&lt;h2 id="podvodim-itogi_1"&gt;Подводим итоги&lt;/h2&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;Все инженерные решения не вечны, ни одно из решений не идеально, но
    многие будут нормально работать в течение какого-то периода времени&lt;/li&gt;
&lt;li&gt;Заранее начинайте задумываться о плане масштабирования&lt;/li&gt;
&lt;li&gt;Не полагайтесь полностью на memcached и базу данных - они могут Вас
    подвести в самый неподходящий момент&lt;/li&gt;
&lt;li&gt;Все данные для запросов в реальном времени должны находиться в
    памяти, диски в основном для записи&lt;/li&gt;
&lt;li&gt;Убивайте медленные запросы (mkill) прежде, чем они убьют всю систему&lt;/li&gt;
&lt;li&gt;Некоторые задачи могут решаться путем предварительного подсчета и
    анализа, но далеко не все&lt;/li&gt;
&lt;li&gt;Приближайте вычисления к данным по возможности&lt;/li&gt;
&lt;li&gt;Используйте не mongrel, а unicorn для RoR&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Спасибо за внимание, &lt;a href="/feed/"&gt;жду Вас снова&lt;/a&gt;! Буду рад, если Вы
&lt;a href="https://www.insight-it.ru/goto/26b8fa1/" rel="nofollow" target="_blank" title="http://twitter.com/blinkov"&gt;подпишитесь на меня в Twitter&lt;/a&gt;, с
удовольствием пообщаюсь со всеми читателями :)&lt;/strong&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sat, 05 Mar 2011 20:47:00 +0300</pubDate><guid>tag:www.insight-it.ru,2011-03-05:highload/2011/arkhitektura-twitter-dva-goda-spustya/</guid><category>Apache</category><category>Cassandra</category><category>featured</category><category>Flock</category><category>FlockDB</category><category>Hadoop</category><category>HBase</category><category>Kestrel</category><category>Memcached</category><category>MySQL</category><category>Pig</category><category>Ruby</category><category>Ruby on Rails</category><category>Scala</category><category>Scribe</category><category>Twitter</category><category>Unicorn</category><category>архитектура Twitter</category><category>интернет-проекты</category><category>Масштабируемость</category><category>социальная сеть</category></item><item><title>Архитектура Twitter</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-twitter/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/c2919313/" rel="nofollow" target="_blank" title="https://www.twitter.com"&gt;Twitter&lt;/a&gt; стартовал как побочный подпроект, но
не смотря на это темпы его роста были впечатляющими: путь от 0 до
миллионов просмотров страниц занял всего несколько коротких месяцев.
Ранние решения о проектировании системы неплохо справлялись с небольшими
нагрузками, но они быстро таяли под напором огромного количества
пользователей, желающих разослать весточки всем своим друзьям с ответом
на простой вопрос: а чем ты занимаешься?&lt;/p&gt;
&lt;p&gt;Поначалу все винили &lt;a href="/tag/ror/"&gt;Ruby on Rails&lt;/a&gt; во всех проблемах с
масштабированием, но Blaine Cook, главный архитектор Twitter, встал на
его защиту:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Основной для нас на самом деле является проблема горизонтального
масштабирования, с этой точки зрения &lt;a href="/tag/ror/"&gt;Ruby on Rails&lt;/a&gt; ничем
не хуже других языков программирования или framework'ов: переход на
"более быстрый" язык программирования дал бы нам 10-20% прирост
производительности, в то время архитектурные преобразования, легко
реализованные средствами &lt;a href="/tag/ror/"&gt;Ruby on Rails&lt;/a&gt;, сделали Twitter
быстрее на 10000%.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Даже если &lt;a href="/tag/ror/"&gt;Ruby on Rails&lt;/a&gt; оказался невиновен, как же тогда
Twitter научился с его помощью рости до все больших и больших высот?
&lt;!--more--&gt;&lt;/p&gt;
&lt;h3 id="istochniki-informatsii"&gt;Источники информации&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Этот текст является продолжением &lt;a href="https://www.insight-it.ru/highload/"&gt;серии переводов&lt;/a&gt;, автор
&lt;a href="https://www.insight-it.ru/goto/9736f7f8/" rel="nofollow" target="_blank" title="http://highscalability.com/scaling-twitter-making-twitter-10000-percent-faster"&gt;оригинала&lt;/a&gt; -
Todd Hoff. На этот раз написать что-либо своими силами у меня не
сложилось, все мысли ушли на другой пост, который я скоро опубликую, а
перевод этот получился несколько менее строгим, чем обычно, но я думаю
ничего страшного.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/1a76cc37/" rel="nofollow" target="_blank" title="http://video.google.com/videoplay?docid=-7846959339830379167"&gt;Scaling Twitter Video&lt;/a&gt;
    от Blaine Cook.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/a004222e/" rel="nofollow" target="_blank" title="http://www.slideshare.net/Blaine/scaling-twitter"&gt;Scaling Twitter Slides&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/7541c4c6/" rel="nofollow" target="_blank" title="http://talklikeaduck.denhaven2.com/articles/2007/06/22/good-news"&gt;Good News&lt;/a&gt;
    блог пост от Rick Denatale&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/96735c2c/" rel="nofollow" target="_blank" title="http://pragmati.st/2007/5/20/scaling-twitter"&gt;Scaling Twitter&lt;/a&gt; блог
    пост от Patrick Joyce&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/7267856d/" rel="nofollow" target="_blank" title="http://readwritetalk.com/2007/09/05/biz-stone-co-founder-twitter/"&gt;Twitter API Traffic is 10x Twitter&amp;rsquo;s Site&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/5eb63819/" rel="nofollow" target="_blank" title="http://www.slideshare.net/britt/a-small-talk-on-getting-big-113066"&gt;A Small Talk on Getting Big. Scaling a Rails App &amp;amp; all that Jazz&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="platforma"&gt;Платформа&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/ruby-on-rails/"&gt;Ruby on Rails&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/erlang/"&gt;Erlang&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/mongrel/"&gt;Mongrel&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/munin/"&gt;Munin&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/nagios/"&gt;Nagios&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/google-analytics/"&gt;Google Analytics&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/awstats/"&gt;AWStats&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/memcached/"&gt;Memcached&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="statistika"&gt;Статистика&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Более 350000 пользователей. Точная цифра, как обычно, держится в
    секрете.&lt;/li&gt;
&lt;li&gt;Около 600 запросов в секунду.&lt;/li&gt;
&lt;li&gt;В среднем система поддерживает 200-300 соединений в секунду.
    Максимум обычно достигается при значении 800.&lt;/li&gt;
&lt;li&gt;MySQL обрабатывает примерно 2400 запросов в секунду.&lt;/li&gt;
&lt;li&gt;180 экземпляров приложений на Rails, использующих Mongrel как
    веб-сервер.&lt;/li&gt;
&lt;li&gt;1 MySQL сервер (одна большая машина с 8 ядрами) и 1 slave,
    используемый лишь для статистики и отчетов.&lt;/li&gt;
&lt;li&gt;30+ процессов для выполнения произвольных работ.&lt;/li&gt;
&lt;li&gt;8 Sun X4100&lt;/li&gt;
&lt;li&gt;Обработка запроса обычно занимает у Rails 200 миллисекунд.&lt;/li&gt;
&lt;li&gt;В среднем ответ на запрос к базе данных занимает 50-100 миллисекунд.&lt;/li&gt;
&lt;li&gt;Более 16 GB выделено под &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="arkhitektura"&gt;Архитектура&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Проект столкнулся с массой проблем, связанных с масштабируемостью.
    Маленькая птичка частенько давала сбои.&lt;/li&gt;
&lt;li&gt;Изначально не было реализовано никаких форм мониторинга, графиков
    или статистики, это очень затрудняло обнаружение м решение
    возникающих проблем. Впоследствии были внедрены &lt;a href="/tag/munin/"&gt;Munin&lt;/a&gt;
    и &lt;a href="/tag/nagios/"&gt;Nagios&lt;/a&gt;. Разработчики столкнулись с некоторыми
    трудностями при использовании этих продуктов в
    &lt;a href="/tag/solaris/"&gt;Solaris&lt;/a&gt;. Помимо этого был использован сервис Google
    Analytics, но от него обычно мало толку, особенно когда страницы
    даже не загружаются.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Активное использование кэширования средствами &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Например, если подсчет количества чего-либо выполняется медленно,
намного эффективнее один раз запомнить результат в
&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;, чем каждый раз считать его заново.&lt;/li&gt;
&lt;li&gt;Получение информации о статусе своих друзей - непростая задача.
Вместо использования запросов информация о статусе друзей
обновляется в кэше. База данных совсем не используется. Такой подход
позволяет получить предсказуемое время отклика (ограниченное сверху примерно 20 миллисекундами).&lt;/li&gt;
&lt;li&gt;Объекты ActiveRecord настолько велики, что кэширование их
нецелесообразно. Критичные атрибуты хранятся в хэше, а остальная их часть подвергается "ленивой загрузке" в момент запроса на доступ.&lt;/li&gt;
&lt;li&gt;90% запросов являются запросами к API. Таким образом кэширование
страниц или их фрагментов становится бессмысленным, зато никто не мешает им кэшировать сами API запросы.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Внутренняя организация работы с сообщениями:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Сообщения очень активно используются: производители генерируют
сообщения, они образуются в очереди, а затем распространяются по
потребителем.&lt;/li&gt;
&lt;li&gt;Основная функция Twitter заключается в реализации
своеобразного моста между различными форматами электронных сообщений
(SMS, электронная почта, сервисы мгновенного обмена сообщениями и так далее).&lt;/li&gt;
&lt;li&gt;Чтобы инвалидировать в кэше информацию можно просто отправить внутреннее сообщение, зачем выполнять все действия синхронно?&lt;/li&gt;
&lt;li&gt;Изначально этот механизм основывался на DRb (distributed Ruby) -
библиотека, позволяющая отправлять и принимать сообщения сообщения
между удаленными Ruby-объектами по TCP/IP. Но она была несколько
странноватой, да и являлось потенциально слабым местом с точки зрения стабильности.&lt;/li&gt;
&lt;li&gt;Со временем сервис перевели на Rinda, представляющую собой набор
общих для всей системы очередей. Но и у нее были недостатки: все очереди были постоянными, а данные терялись при сбоях.&lt;/li&gt;
&lt;li&gt;Следующей попыткой был Erlang. Но однажды возникла проблема: каким
образом сломавшийся сервер может продолжать работать, но при этом в
очереди откуда-то возникли целых 20000 ожидающих пользователей? Разработчики не знали. На лицо явный недостаток документации...&lt;/li&gt;
&lt;li&gt;В конце концов решение было разработано своими силами: Twitter
выпустил &lt;a href="/tag/starling/"&gt;Starling&lt;/a&gt;, распределенный легковесный
сервер очередей, написанный на Ruby и поддерживающий протокол memcache. Сейчас серверная часть Twitter управляется именно им.&lt;/li&gt;
&lt;li&gt;Распределенные очереди позволяют переживать сбои путем записи их
на диск в критических ситуациях. Другие крупные интернет-проекты также часто пользуются таким подходом.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Работа с SMS осуществляется с помощью сторонних сервисов и
    предоставляемых ими шлюзов. Достаточно дорогое удовольствие.&lt;/li&gt;
&lt;li&gt;Развертывание:&lt;ul&gt;
&lt;li&gt;Просто запускаются дополнительные сервера с mongrel, более элегантного решения пока нет.&lt;/li&gt;
&lt;li&gt;Все внутренние ошибки выдаются пользователям, если обслуживающий
их mongrel сервер на данный момент заменяется.&lt;/li&gt;
&lt;li&gt;Все сервера останавливаются одновременно. Отключение их по одному
по определенным причинам не используется.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Неправильное использование сервиса:&lt;ul&gt;
&lt;li&gt;Много времени сервис был не доступен, так как люди проходились
специальными программами по сайту с целью добавить всех кто
попадался под руку в друзья. 9000 друзей за 24 часа. Это
просто-напросто останавливало работу сайта.&lt;/li&gt;
&lt;li&gt;Были разработаны средства для своевременного обнаружения таких
ситуаций.&lt;/li&gt;
&lt;li&gt;Будте беспощадными, таких пользователей нужно просто удалять.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Сегментирование:&lt;ul&gt;
&lt;li&gt;Пока оно только в планах, сейчас оно не используется.&lt;/li&gt;
&lt;li&gt;В будущем оно будет основываться на времени, а не на
пользователях, так как запросы обычно очень локальны по времени.&lt;/li&gt;
&lt;li&gt;Сегментирование будет не так просто реализовать благодаря
автоматическому запоминанию результатов выполнения функций для
последующего повторного их использования. Никто не даст гарантии,
что операции "только для чтения" на самом деле будут таковыми
являться. Запись в slave, работающий в режиме read-only, - не самая
лучшая идея.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;API Twitter генерирует в 10 раз больше трафика, чем сам сайт.&lt;ul&gt;
&lt;li&gt;Их API - самая важная вещь из всех, что они разработали.&lt;/li&gt;
&lt;li&gt;Простота сервиса позволила разработчикам строить свои приложения
поверх инфраструктуры Twitter, привнося все новые и новые идеи.
Например, Twitterrific - красивый способ использовать Twitter в
небольшой команде.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Мониторинг используется для остановки слишком больших процессов.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="podvodim-itogi"&gt;Подводим итоги&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Общайтесь со своим сообществом. Не прячьтесь и не пытайтесь решить
    абсолютно все проблемы самостоятельно. Много отличных людей будут
    готовы помочь, достаточно лишь попросить.&lt;/li&gt;
&lt;li&gt;Рассматривайте вашу стратегию масштабирования как бизнес-план.
    Соберите советы помощников для того чтобы облегчить для себя
    принятие решений.&lt;/li&gt;
&lt;li&gt;Стройте свой проект сами. Twitter потратил много времени, пытаясь
    приспособить готовые решения других людей, которые казалось бы
    должны работать, но это оказалось не совсем так. Лучше построить
    какие-то вещи самостоятельно, чтобы иметь высокую степень контроля
    над ситуацией и иметь возможность привносить новые возможности как
    только они понадобились.&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;li&gt;Оптимизируйте базу данных:&lt;ul&gt;
&lt;li&gt;Индексируйте все таблицы, Rails не будет делать это за Вас.&lt;/li&gt;
&lt;li&gt;Используйте "explain" для анализа выполнения запросов. Результаты
могут не совпадать с Вашими ожиданиями.&lt;/li&gt;
&lt;li&gt;Денормализуйте данные. Один только этот совет порой может спасти
ситуацию. Для примера, в Twitter хранят все ID друзей каждого
пользователя вместе, это позволило избежать многих ресурсоемких
запросов.&lt;/li&gt;
&lt;li&gt;Избегайте комплексного объединения данных из нескольких таблиц.&lt;/li&gt;
&lt;li&gt;Избегайте сканирования больших наборов данных.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Кэшируйте все, что только можно.&lt;/li&gt;
&lt;li&gt;Тестируйте все максимально тщательно:&lt;ul&gt;
&lt;li&gt;Когда Вы развертываете приложение, Вы должно быть уверены, что оно
будет работать корректно.&lt;/li&gt;
&lt;li&gt;Они используют полный набор средств для тестирования. Таким
образом, когда произошла неполадка в кэшировании, они узнали о ней
еще до того как она на самом деле произошла.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Длительно функционирующие процессы стоит оформить в виде daemon'ов.&lt;/li&gt;
&lt;li&gt;Используйте уведомления об исключительных ситуациях в совокупности с
    ведением логов, это необходимо для своевременного реагирования на
    них.&lt;/li&gt;
&lt;li&gt;Не делайте глупостей!&lt;ul&gt;
&lt;li&gt;Масштаб проект несколько меняет понятие "глупость".&lt;/li&gt;
&lt;li&gt;Пытаться загрузить 3000 друзей в память одновременно может
заставить сервер временно перестать функционировать, хотя когда
друзей было всего 4 - этот механизм прекрасно работал.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Большая часть производительности зависит не от использованного языка
    программирования, а от продуманной структуры приложения.&lt;/li&gt;
&lt;li&gt;Превратите свой сайт в открытый сервис с помощью создания API. Их
    API является ключом к успеху Twitter. Он позволяет пользователям
    создавать постоянно расширяющуюся экосистему вокруг Twitter,
    соревноваться с которой не так-то просто. Вы никогда не сможете
    сделать столько же работы, сколько смогут Ваши пользователи для Вас,
    Вам просто не хватит креативных идей. Так что не стесняйтесь,
    откройте свое приложение и сделайте интеграцию Вашего приложения с
    другими максимально простой и удобной!&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sat, 10 May 2008 12:36:00 +0400</pubDate><guid>tag:www.insight-it.ru,2008-05-10:highload/2008/arkhitektura-twitter/</guid><category>AWStats</category><category>Erlang</category><category>Google Analytics</category><category>Memcached</category><category>mongrel</category><category>Munin</category><category>MySQL</category><category>Nagios</category><category>Ruby on Rails</category><category>Solaris</category><category>Starling</category><category>Twitter</category><category>архитектура</category><category>архитектура Twitter</category></item></channel></rss>