<?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/redis/feed/index.xml" rel="self"></atom:link><lastBuildDate>Wed, 15 Aug 2012 22:26:00 +0400</lastBuildDate><item><title>Архитектура Pinterest</title><link>https://www.insight-it.ru//highload/2012/arkhitektura-pinterest/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/975fdd8/" rel="nofollow" target="_blank" title="https://www.pinterest.com/"&gt;Pinterest&lt;/a&gt; - по непонятным для меня причинам
популярная в определенных кругах социальная сеть, построенная вокруг
произвольных картинок чаще всего не собственного производства. Как и
&lt;a href="https://www.insight-it.ru/highload/2012/arkhitektura-instagram/"&gt;Instagram&lt;/a&gt;
проект довольно молодой, с очень похожей историей и стеком технологий.
Тем не менее, Pinterest определенно заслуживает внимания как один из
самых быстрорастущих по посещаемости вебсайтов за всю историю.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="platforma"&gt;Платформа&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/amazon/"&gt;Amazon&lt;/a&gt; &lt;a href="/tag/aws/"&gt;AWS&lt;/a&gt;&amp;nbsp;- хостинг и вспомогательные
    сервисы&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/nginx/"&gt;nginx&lt;/a&gt;&amp;nbsp;- вторичная балансировка нагрузки, отдача
    статики&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/python/"&gt;Python&lt;/a&gt;&amp;nbsp;- язык программирования&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/django/"&gt;Django&lt;/a&gt;&amp;nbsp;- фреймворк&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;&amp;nbsp;- основная СУБД&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;&amp;nbsp;- кэширование объектов&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/redis/"&gt;Redis&lt;/a&gt;&amp;nbsp;- кэширование коллекций объектов&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/solr/"&gt;Solr&lt;/a&gt;&amp;nbsp;- поиск&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt;&amp;nbsp;- анализ данных&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;3 миллиона уникальных посетителей в день&lt;/li&gt;
&lt;li&gt;18 миллионов уникальных посетителей в месяц&lt;/li&gt;
&lt;li&gt;4-я по популярности социальная сеть в США после
    &lt;a href="/tag/facebook/"&gt;Facebook&lt;/a&gt;,&amp;nbsp;&lt;a href="/tag/twitter/"&gt;Twitter&lt;/a&gt;&amp;nbsp;и
    &lt;a href="/tag/linkedin/"&gt;LinkedIn&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Порядка 500 виртуальных машин в EC2&lt;/li&gt;
&lt;li&gt;80 миллионов объектов в S3&lt;/li&gt;
&lt;li&gt;410Тб пользовательских данных&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="razvitie"&gt;Развитие&lt;/h2&gt;
&lt;h4&gt;Март 2010&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;1 маленький виртуальный веб-сервер&lt;/li&gt;
&lt;li&gt;1 маленький виртуальный сервер MySQL&lt;/li&gt;
&lt;li&gt;Все это в Rackspace, 1 разработчик&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Январь 2011&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;1 сервер nginx для балансировки нагрузки, 4 веб-сервера&lt;/li&gt;
&lt;li&gt;2 сервера MySQL с master/slave репликацией&lt;/li&gt;
&lt;li&gt;3 сервера для отложенного выполнения задач&lt;/li&gt;
&lt;li&gt;1 сервер MongoDB&lt;/li&gt;
&lt;li&gt;Переехали на Amazon &lt;a href="/tag/ec2/"&gt;EC2&lt;/a&gt; + &lt;a href="/tag/s3/"&gt;S3&lt;/a&gt; +
    &lt;a href="/tag/cloudfront/"&gt;CloudFront&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Осень 2011&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;2 сервера nginx, 16 веб-серверов, 2 сервера для API&lt;/li&gt;
&lt;li&gt;5 функционально разделенных серверов MySQL с 9 read slave&lt;/li&gt;
&lt;li&gt;Кластер из 4 узлов Cassandra&lt;/li&gt;
&lt;li&gt;15 серверов Membase в 3 отдельных кластерах&lt;/li&gt;
&lt;li&gt;8 серверов memcached&lt;/li&gt;
&lt;li&gt;10 серверов Redis&lt;/li&gt;
&lt;li&gt;7 серверов для отложенной обработки задач&lt;/li&gt;
&lt;li&gt;4 сервера Elastic Search&lt;/li&gt;
&lt;li&gt;3 кластера MongoDB&lt;/li&gt;
&lt;li&gt;3 разработчика&lt;/li&gt;
&lt;li&gt;Если кто-то может объяснить зачем им сдался такой зоопарк, кроме как
    потестировать разные варианты, можете взять с полки пирожок.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Зима 2011-2012&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Заменили CloudFront на &lt;a href="/tag/akamai/"&gt;Akamai&lt;/a&gt; - вполне объяснимо,
    так как у Akamai намного лучше покрытие по миру, а
    качественный&amp;nbsp;&lt;a href="/tag/cdn/"&gt;CDN&lt;/a&gt; для сайта с большим количеством
    изображений - чуть ли не залог успеха.&lt;/li&gt;
&lt;li&gt;90 веб серверов и 50 серверов для API&lt;/li&gt;
&lt;li&gt;66 + 66 MySQL серверов на m1.xlarge инстансах EC2&lt;/li&gt;
&lt;li&gt;59 серверов Redis&lt;/li&gt;
&lt;li&gt;51 серверов memcached&lt;/li&gt;
&lt;li&gt;25+1 сервер для отложенной обработки задач на основе Redis&lt;/li&gt;
&lt;li&gt;Кластеризованный Solr&lt;/li&gt;
&lt;li&gt;6 разработчиков&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Весна-лето 2012&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Снова сменили CDN, на этот раз в пользу ранее неизвестного мне &lt;a href="/tag/edge-cast/"&gt;Edge
    Cast&lt;/a&gt;. Покрытие по всему миру довольно скромное,
    так что единственное логичное объяснение, которое мне приходит в
    голову - не потянули Akamai по деньгам.&lt;/li&gt;
&lt;li&gt;135 веб серверов и 75 серверов для API&lt;/li&gt;
&lt;li&gt;80 + 80 серверов MySQL&lt;/li&gt;
&lt;li&gt;110 серверов Redis&lt;/li&gt;
&lt;li&gt;60 серверов memcached&lt;/li&gt;
&lt;li&gt;60 + 2&amp;nbsp;сервера&amp;nbsp;для отложенной обработки задач на основе Redis&lt;/li&gt;
&lt;li&gt;25 разработчиков&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vybor"&gt;Выбор&lt;/h2&gt;
&lt;h4&gt;Почему Amazon Ec2/S3?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Очень хорошая надежность, отчетность и поддержка&lt;/li&gt;
&lt;li&gt;Хорошие дополнительные сервисы: кэш, базы данных, балансировка
    нагрузки, &lt;a href="/tag/mapreduce/"&gt;MapReduce&lt;/a&gt; и т.п.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Новые виртуальные машины готовы за считанные секунды&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Почему MySQL?&lt;/h4&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;Хорошая поддержка сторонним ПО (XtraBackup, Innotop, Maatkit)&lt;/li&gt;
&lt;li&gt;Надежное активное сообщество&lt;/li&gt;
&lt;li&gt;Отличная поддержка от Percona&lt;/li&gt;
&lt;li&gt;Бесплатна&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Почему memcached?&lt;/h4&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;h4&gt;Почему Redis?&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Много удобных &lt;strong&gt;структур данных&lt;/strong&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;h2 id="arkhitektura"&gt;Архитектура&lt;/h2&gt;
&lt;h4&gt;Сlustering vs Sharding&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Большую часть презентации, на основе которой написана данная статья
    (&lt;a href="https://www.insight-it.ru/goto/10005efe/" rel="nofollow" target="_blank" title="http://www.slideshare.net/eonarts/mysql-meetup-july2012scalingpinterest"&gt;ссылка&lt;/a&gt;,
    если не охота листать до секции источников информации), занимает
    раздел под названием "Clustering vs Sharding". В связи с путаницей в
    терминологии пришлось несколько раз перечитывать, чтобы понять к
    чему они клонят, сейчас попробую объяснить.&lt;/li&gt;
&lt;li&gt;Вообще есть два фундаментальных способа распределить данные между
    несколькими серверами:&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Вертикально:&lt;/strong&gt;&amp;nbsp;разные таблицы (или просто логически разные
    типы данных) разносятся на разные сервера.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Горизонтально:&lt;/strong&gt; каждая таблица разбивается на некоторое
    количество частей и эти части разносятся на разные сервера по
    определенному алгоритму.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;С первого взгляда казалось, что они пытаются вертикальное разбиение
    назвать &lt;em&gt;sharding&lt;/em&gt;, а горизонтальное - &lt;em&gt;clustering&lt;/em&gt;. Хотя вообще они
    почти синонимы и на русский я их обычно примерно одинаково перевожу.&lt;/li&gt;
&lt;li&gt;По факту же оказалось, что под словом clustering они понимают все
    программные продукты для хранения данных, которые имеют встроенную
    поддержку работы в кластере. В частности они имеют ввиду
    &lt;a href="/tag/cassandra/"&gt;Cassandra&lt;/a&gt;, &lt;a href="/tag/membase/"&gt;Membase&lt;/a&gt;,
    &lt;a href="/tag/hbase/"&gt;HBase&lt;/a&gt; и &lt;a href="/tag/riak/"&gt;Riak&lt;/a&gt;, которые прозрачно для
    пользователя горизонтально распределяют данные по кластеру.&lt;/li&gt;
&lt;li&gt;За словом &lt;em&gt;sharding&lt;/em&gt; в их терминологии стоит аналогичная схема
    собственной разработки, использующая огромное количество логических
    БД в MySQL, распределенных между меньшим количеством &lt;del&gt;физических серверов&lt;/del&gt; виртуальных машин. Именно по этому пути и пошли в
    Pinterest, плюс очень похожий подход используется в
    &lt;a href="https://www.insight-it.ru/highload/2010/arkhitektura-facebook/"&gt;Facebook&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;От себя добавлю, что хоть при наличии должных ресурсов разработка
    собственной системы распределения данных и может быть
    целесообразной, в большинстве случаев на начальном этапе проще
    основываться на готовых решениях вроде перечисленных выше. К слову в
    opensource доступны и основанные на MySQL подобные решения:&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/vitess/"&gt;Vitess&lt;/a&gt; от &lt;a href="/tag/google/"&gt;Google&lt;/a&gt; /
    &lt;a href="/tag/youtube/"&gt;YouTube&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/flockdb/"&gt;FlockDB&lt;/a&gt; от &lt;a href="/tag/twitter/"&gt;Twitter&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;В их проекте данная подсистема развивалась следующим образом:&lt;ul&gt;
&lt;li&gt;1 БД + внешние ключи + join'ы&amp;nbsp;&amp;rarr;&lt;/li&gt;
&lt;li&gt;1 БД + денормализация + кэш&amp;nbsp;&amp;rarr;&lt;/li&gt;
&lt;li&gt;1 БД + master/slave + кэш&amp;nbsp;&amp;rarr;&lt;/li&gt;
&lt;li&gt;несколько функциональных разделенных БД + master/slave + кэш&amp;nbsp;&amp;rarr;&lt;/li&gt;
&lt;li&gt;вертикально и горизонтально разделенные БД (по
    идентификаторам) + по резервные БД (пассивный slave) + кэш&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;При использовании аналогичного решения остерегайтесь:&lt;ul&gt;
&lt;li&gt;Невозможности выполнять большинство запросов с join&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;h4&gt;Остальные моменты&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Кэширование многоуровневое:&lt;ul&gt;
&lt;li&gt;Коллекции объектов хранятся в списках Redis&lt;/li&gt;
&lt;li&gt;Сами объекты - в memcached&lt;/li&gt;
&lt;li&gt;На уровне SQL запросы в основном примитивны и написаны вручную,
    так что часты попадания в кэш MySQL&lt;/li&gt;
&lt;li&gt;Кэш файловой системы - само собой&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Еще пара фактов про кэширование в Pinterest:&lt;ul&gt;
&lt;li&gt;Кэш разбит также на несколько частей (шардов), для упрощения
    обслуживания и масштабирования&lt;/li&gt;
&lt;li&gt;В коде для кэширования используются Python'овские декораторы, на
    вид собственной разработки, хотя точно не уверен&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Балансировка нагрузки осуществляется в первую очередь за счет Amazon
    ELB, что позволяет легко подключать/отключать новые сервера
    посредством API.&lt;/li&gt;
&lt;li&gt;Так как большинство пользователей живут в США по ночам нагрузка
    сильно падает, что позволяет им по ночам отключать до 40%
    виртуальных машин. В пиковые часы EC2 обходится порядка 52$ в час,
    а по ночам - всего 15$.&lt;/li&gt;
&lt;li&gt;Elastic Map Reduce, основанный на Hadoop, используется для анализа
    данных и стоит всего несколько сотен долларов в месяц&lt;/li&gt;
&lt;li&gt;Текущие проблемы:&lt;ul&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;li&gt;Изоляция доступа (безопасность)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="uroki-ot-komandy-pinterest"&gt;Уроки от команды Pinterest&lt;/h2&gt;
&lt;ol&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;/ol&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/10005efe/" rel="nofollow" target="_blank" title="http://www.slideshare.net/eonarts/mysql-meetup-july2012scalingpinterest"&gt;Scaling Pinterest @ MySQL Meetup&lt;/a&gt;&lt;ul&gt;
&lt;li&gt;В презентации можно посмотреть примеры кода и SQL-запросов&lt;/li&gt;
&lt;li&gt;Если кто-то знает где можно посмотреть/послушать запись этого
    мероприятия - поделитесь ссылкой, пожалуйста&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/ac4a03d6/" rel="nofollow" target="_blank" title="http://highscalability.com/blog/2012/5/21/pinterest-architecture-update-18-million-visitors-10x-growth.html"&gt;Pinterest Architecture Update&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Вакансии в Pinterest&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Wed, 15 Aug 2012 22:26:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-08-15:highload/2012/arkhitektura-pinterest/</guid><category>Akamai</category><category>Amazon</category><category>Apache Hadoop</category><category>AWS</category><category>CDN</category><category>CloudFront</category><category>django</category><category>EC2</category><category>Edge Cast</category><category>Hadoop</category><category>Memcached</category><category>MySQL</category><category>nginx</category><category>Pinterest</category><category>Python</category><category>Redis</category><category>S3</category><category>Solr</category><category>Архитектура Pinterest</category><category>архиткутера</category><category>Масштабируемость</category></item><item><title>Серверная часть интерактивного сайта и потоки сообщений</title><link>https://www.insight-it.ru//interactive/2012/servernaya-chast-interaktivnogo-sajjta-i-potoki-soobshhenijj/</link><description>&lt;p&gt;Вернемся к теме &lt;a href="https://www.insight-it.ru/interactive/"&gt;интерактивных сайтов&lt;/a&gt; с обратной стороны, серверной. В ней есть огромный простор для творчества, так как
в отличии от клиентской части отсутствуют ограничения, накладываемыми
браузерами. С "простором" же приходит и неоднозначность/неопределенность, вариантов как реализовать одно и то же множество, так что возможно приводимые мной примеры Вам окажутся не по душе &amp;nbsp;- и это нормально, правильный путь не единственный, их много :)&lt;/p&gt;
&lt;p&gt;Приступим!&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="vnutrennie-servisy"&gt;Внутренние сервисы&lt;/h2&gt;
&lt;p&gt;Напомню, что обычно на внутренние сервисы ложится реализация всей или
большей части бизнес-логики приложения. Они получают пользовательские
запросы в стандартизированном виде через прослойки в виде внешних
интерфейсов и, при необходимости взаимодействуя друг с другом и
остальными компонентами системы, определяют какой ответ необходимо
отправить и какие другие действия предпринять.&lt;/p&gt;
&lt;p&gt;Я не буду здесь особо вдаваться в возможные детали реализации самой
бизнес-логики - она практически всегда уникальна, скорее заслуживает
внимания её "обертка" - сам процесс, принимающий и создающий внутренние
запросы.&lt;/p&gt;
&lt;p&gt;Вообще создание внутренних сервисов очень хорошо ложится на так
называемую &lt;a href="https://www.insight-it.ru/goto/7e699ecd/" rel="nofollow" target="_blank" title="http://ru.wikipedia.org/wiki/%D0%9C%D0%BE%D0%B4%D0%B5%D0%BB%D1%8C_%D0%B0%D0%BA%D1%82%D0%BE%D1%80%D0%BE%D0%B2"&gt;модель "акторов"&lt;/a&gt;,
система разбивается на некие логические примитивы, общающиеся между
собой исключительно передачей сообщений. По сути процессы с
определенными разработчиками наборами входящих и исходящих сообщений и
алгоритмом преобразования одних в другие. При таком подходе группа
одинаково функционирующих акторов (вероятно распределенная по нескольким
серверам для отказоустойчивости и возможности масштабирования) и
образует внутренний сервис.&lt;/p&gt;
&lt;p&gt;На практике есть масса способов воплотить эту модель в жизнь,
перечислю&amp;nbsp;с пояснениями наиболее заслуживающие внимания&amp;nbsp;на мой взгляд:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Функциональные языки программирования,&lt;/strong&gt;&amp;nbsp;в &lt;a href="/tag/erlang/"&gt;Erlang&lt;/a&gt;
    и &lt;a href="/tag/scala/"&gt;Scala&lt;/a&gt; модель акторов является практически "сердцем"
    всего языка и связанной платформы; у обоих есть библиотеки для
    реализации надежных, высокопроизводительных и масштабируемых акторов
    (&lt;strong&gt;OTP&lt;/strong&gt; и &lt;strong&gt;Akka&lt;/strong&gt;, соответственно). Если не боитесь кардинально
    отличающейся от нынче модного ООП парадигмы разработки, этот вариант
    наиболее жизнеспособный, &lt;em&gt;рекомендую&lt;/em&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Асинхронный HTTP-сервер&lt;/strong&gt;, в частности &lt;a href="/tag/tornado/"&gt;Tornado&lt;/a&gt; и
    &lt;a href="/tag/node-js/"&gt;node.js&lt;/a&gt;&amp;nbsp;- они основаны на &lt;a href="https://www.insight-it.ru/linux/2012/kak-rabotaet-epoll/"&gt;epoll&lt;/a&gt; и помимо эффективной обработки HTTP-запросов умеют и эффективно их отправлять посредством идущего в комплекте асинхронного же клиента.
    При таком подходе по сути получается несколько "уровней"
    HTTP-серверов, первый из которых публично доступен для общения с
    внешним миром и в ответ на каждый входящий запрос обращается сразу к
    нескольким внутренним HTTP-сервисам (вероятно параллельно) и на их
    основе составляет ответ пользователю. Этот подход одно время активно
    пропагандировали на конференциях ребята из одного крупного
    отечественного сайта с вакансиями. Особенным бонусом этого варианта
    является возможность использовать в роли внутреннего сервиса
    какую-то старую, доставшуюся по наследству &lt;em&gt;(legacy)&lt;/em&gt;, систему,
    которая с одной стороны по-прежнему нужна, а с другой - человек,
    который в ней&amp;nbsp;разбирался уже давно уволился.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/c/"&gt;С++&lt;/a&gt; и &lt;a href="/tag/thrift/"&gt;Thrift&lt;/a&gt;&lt;/strong&gt; - хоть одного из
    участников этой пары можно легко заменить на альтернативу, вместе
    они смотрятся наиболее органично: потенциально
    высокопроизводительная реализация бизнес-логики на С++ плюс
    проверенная в деле многими крупными и очень крупными проектами
    обертка для создания серверов и клиентов, легко общающихся из разных
    языков программирования (речь о Thrift, если не очевидно). Если в
    команде проекта есть гуру C++ - этот вариант Ваш, в противном случае
    не рекомендую, т.к. &lt;em&gt;очень&lt;/em&gt; легко накосячить.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Иногда внутренние сервисы возможно сделать совсем изолированными, то
есть без взаимодействия с другими компонентами системы. Но в большинстве
случаев это не так, зачастую для принятия решения им необходимы внешние
данные.&lt;/p&gt;
&lt;h2 id="baza-dannykh-i-keshirovanie"&gt;База данных и кэширование&lt;/h2&gt;
&lt;p&gt;По большому счету интерактивные сайты не особо сильно отличаются от
статичных с точки зрения организации хранения данных.&lt;/p&gt;
&lt;p&gt;Из особенностей хочу отметить более-менее четкое разграничение
&lt;strong&gt;стабильной&lt;/strong&gt; информации и &lt;strong&gt;свежей&lt;/strong&gt;, актуальной лишь короткое время.
Для социальной сети это могут быть, например, профили пользователей
(стабильная) и сообщения (свежая).&lt;/p&gt;
&lt;p&gt;В соответствии с этим стоит выбирать хранилище данных и политику
кэширования:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Стабильная информация, которая редко обновляется и в тысячи раз чаще
    читается, прекрасно поддается кэшированию и возможно даже прекрасно
    будет себя чувствовать в реляционной СУБД.&lt;/li&gt;
&lt;li&gt;Свежую информацию вероятно вообще важнее доставить в кратчайшие
    сроки получателю, а сохранять в персистентном виде можно вообще
    постфактум для архива, на маловероятный случай когда она повторно
    понадобится. Про кэширование лучше вообще забыть. Для этого самого
    "архива" часто используют нереляционные распределенные базы данных
    вроде &lt;a href="/tag/hbase/"&gt;HBase&lt;/a&gt;, &lt;a href="/tag/cassandra/"&gt;Cassandra&lt;/a&gt; или
    &lt;a href="/tag/riak/"&gt;Riak&lt;/a&gt;. А про оперативную доставку получателю поговорим
    в следующем разделе.&lt;/li&gt;
&lt;li&gt;Хранилища данных в памяти вроде &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt; или
    &lt;a href="/tag/redis/"&gt;Redis&lt;/a&gt; с отключенной персистентностью можно
    использовать независимо для временного хранения каких-то побочных
    данных (восстановимых производных данных или просто чего-то не особо
    важного, вроде счетчиков пользователей онлайн).&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="potoki-soobshchenii"&gt;Потоки сообщений&lt;/h2&gt;
&lt;p&gt;Одной из ключевых задач интерактивного сайта является доставка сообщений
пользователем в реальном времени, причем их источник может быть как
внешний, так и внутренний, зачастую это просто другие пользователи.&lt;/p&gt;
&lt;p&gt;Часть системы, отвечающую за маршрутизацию таких сообщений, обычно
назвают &lt;strong&gt;брокером сообщений&lt;/strong&gt;&amp;ensp;&lt;em&gt;(message broker)&lt;/em&gt;. Для доставки
сообщений в браузер чаще всего используют &lt;strong&gt;интерфейс сериализованных
данных&lt;/strong&gt;, подробно обсуждавшийся в &lt;a href="https://www.insight-it.ru/interactive/2012/postoyannoe-soedinenie-mezhdu-brauzerom-i-serverom/"&gt;одной из предыдущих статей серии&lt;/a&gt;. Когда пользователь устанавливает соединение с этим интерфейсом, он, в
свою очередь, напрямую или через внутренний сервис регистрируется в
брокере сообщений для оперативного получения сообщений, предназначенных
соответствующему пользователю.&lt;/p&gt;
&lt;p&gt;Предлагаю рассмотреть типичные сценарии маршрутизации сообщений, они
довольно просты:&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;, актуально для проектов, где пользователи
    взаимодействуют не на глобальном пространстве, а разбиты на части по
    какому-то признаку. Скажем это может быть какой-то B2B сервис и
    сообщения ходят только между сотрудниками одной компании-клиента.
    Обычно используется такие же метки, как и при конкретном получателе,
    только с одной из сторон (обычно принимающей) вместо конкретного
    идентификатора указывается какой-то паттерн, вроде &lt;code&gt;CompanyA.*&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Публичные сообщения&lt;/strong&gt; - получают все пользователи, метки не
    используются. Обычно это уведомления о глобальных для сайта событиях
    или публикации каких-то материалов.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Реализаций брокеров сообщений есть много разных, общий принцип работы у
всех примерно одинаковый и соответствует трем изложенным выше пунктам.
Для интернет-проектов очень рекомендую &lt;a href="/tag/rabbitmq/"&gt;RabbitMQ&lt;/a&gt;, в нем
эти стратегии маршрутизации называются &lt;em&gt;direct&lt;/em&gt;, &lt;em&gt;topic&lt;/em&gt; и &lt;em&gt;fanout&lt;/em&gt;
exchange, соответственно.&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;h2 id="zakliuchenie"&gt;Заключение&lt;/h2&gt;
&lt;p&gt;Таким образом наша цепь замыкается - между браузерами любых
пользователей можно в "мягком" реальном времени пересылать любые
сообщения, пропуская их через бизнес-логику для регулирования данного
процесса, и, при необходимости, использовать постоянные и временные
хранилища данных.&lt;/p&gt;
&lt;p&gt;Как я уже упоминал&amp;nbsp;&lt;a href="https://www.insight-it.ru/interactive/2012/arkhitektura-interaktivnykh-sajjtov/"&gt;в первой статье серии&lt;/a&gt;, серверная часть у интерактивного сайта не так уж и кардинально отличается от любого другого - примерно те же компоненты, примерно так же работают и взаимодействуют. Разница в деталях.&lt;/p&gt;
&lt;p&gt;В следующей, заключительной, статье серии мы по второму кругу пройдемся
по ключевым моментам и попробуем рассмотреть наиболее перспективные
моменты для улучшений и оптимизации, хотя, как говорится, заранее
оптимизировать - плохая примета :)&lt;/p&gt;
&lt;div class="card green"&gt;
&lt;p&gt;&lt;div class="card-content white-text"&gt;
Эта статья - пятая в &lt;a class="green-text text-lighten-4" href="https://www.insight-it.ru/interactive/"&gt;серии про Интерактивные сайты&lt;/a&gt;, автор - &lt;a class="green-text text-lighten-4" href="https://www.insight-it.ru/goto/b03d9116/" rel="nofollow" target="_blank" title="http://blinkov.ru"&gt;Иван&amp;nbsp;Блинков&lt;/a&gt;, основано на личном опыте.
До встречи &lt;a class="green-text text-lighten-4" href="/feed/"&gt;на страницах Insight IT&lt;/a&gt;!
&lt;/div&gt;&lt;/p&gt;
&lt;/div&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Mon, 04 Jun 2012 05:38:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-06-04:interactive/2012/servernaya-chast-interaktivnogo-sajjta-i-potoki-soobshhenijj/</guid><category>Akka</category><category>C++</category><category>Cassandra</category><category>Erlang</category><category>HBase</category><category>Memcached</category><category>OTP</category><category>RabbitMQ</category><category>Redis</category><category>Riak</category><category>Scala</category><category>Thrift</category></item><item><title>Архитектура Instagram</title><link>https://www.insight-it.ru//highload/2012/arkhitektura-instagram/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/a8e562b3/" rel="nofollow" target="_blank" title="https://instagram.com/"&gt;Instagram&lt;/a&gt; - всего лишь &lt;a href="/tag/ios/"&gt;iOS&lt;/a&gt;, а теперь
и &lt;a href="/tag/android/"&gt;Android&lt;/a&gt;, приложение для обмена фотографиями с
друзьями. Последнее время находится на слуху благодаря новости о покупке
проекта &lt;a href="/tag/facebook/"&gt;Facebook&lt;/a&gt;'ом за кругленькую сумму. Недавно один
из основателей проекта, Mike Krieger, выступил на конференции с докладом
о техническом аспекте проекта, который я и хотел бы вкратце пересказать.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Начало:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;1 сервер слабее Macbook Pro&lt;/li&gt;
&lt;li&gt;25к регистраций в первый день&lt;/li&gt;
&lt;li&gt;2 разработчика&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Сегодня:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;40+ миллионов пользователей&lt;/li&gt;
&lt;li&gt;100+ виртуальных серверов в EC2, в том числе:&lt;/li&gt;
&lt;li&gt;Проект куплен Facebook за &lt;em&gt;1 млрд. долл&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;1 миллион регистраций за 12 часов после запуска Android-версии&lt;/li&gt;
&lt;li&gt;5 разработчиков&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tekhnologii"&gt;Технологии&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/ubuntu/"&gt;Ubuntu&lt;/a&gt; &lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; 11.04&lt;/strong&gt; - основная
операционная система&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/python/"&gt;Python&lt;/a&gt;&lt;/strong&gt; - основной язык программирования серверной части&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/django/"&gt;Django&lt;/a&gt;&lt;/strong&gt; - фреймворк&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/amazon/"&gt;&lt;strong&gt;Amazon&lt;/strong&gt;&lt;/a&gt;:&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/ec2/"&gt;EC2&lt;/a&gt;&lt;/strong&gt;&amp;nbsp;- хостинг&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/elb/"&gt;ELB&lt;/a&gt;&lt;/strong&gt;&amp;nbsp;- балансировка входящих HTTP-запросов&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/route53/"&gt;Route53&lt;/a&gt;&lt;/strong&gt; - DNS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/s3/"&gt;S3&lt;/a&gt;&lt;/strong&gt; - хранение фотографий&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/cloudfront/"&gt;CloudFront&lt;/a&gt;&lt;/strong&gt; - &lt;a href="/tag/cdn/"&gt;CDN&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/nginx/"&gt;nginx&lt;/a&gt;&lt;/strong&gt; - второй уровень балансировки входящихHTTP-запросов&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/gunicorn/"&gt;gunicorn&lt;/a&gt;&lt;/strong&gt; - WSGI-сервер&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/haproxy/"&gt;&lt;strong&gt;HAProxy&lt;/strong&gt;&lt;/a&gt;&amp;nbsp;- балансировка нагрузки внутри системы&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/postgresql/"&gt;&lt;strong&gt;PostgreSQL&lt;/strong&gt;&lt;/a&gt; - основное хранилище данных&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/postgis/"&gt;&lt;strong&gt;postgis&lt;/strong&gt;&lt;/a&gt; - поддержка гео-запросов&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/pgfouine/"&gt;&lt;strong&gt;pgfouine&lt;/strong&gt;&lt;/a&gt; - отчеты на основе логов&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/pgbouncer/"&gt;pgbouncer&lt;/a&gt;&lt;/strong&gt; - создание пула соединений&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/redis/"&gt;&lt;strong&gt;Redis&lt;/strong&gt;&lt;/a&gt; - дополнительное хранилище данных&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/memcached/"&gt;&lt;strong&gt;Memcached&lt;/strong&gt;&lt;/a&gt; - кэширование&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/gearman/"&gt;&lt;strong&gt;Gearman&lt;/strong&gt;&lt;/a&gt; - очередь задач&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/solr/"&gt;&lt;strong&gt;Solr&lt;/strong&gt;&lt;/a&gt; - гео-поиск&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="/tag/munin/"&gt;munin&lt;/a&gt;&lt;/strong&gt;, &lt;a href="/tag/statsd/"&gt;&lt;strong&gt;statsd&lt;/strong&gt;&lt;/a&gt;, &lt;a href="/tag/pingdom/"&gt;&lt;strong&gt;pingdom&lt;/strong&gt;&lt;/a&gt; - мониторинг&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/fabric/"&gt;&lt;strong&gt;Fabric&lt;/strong&gt;&lt;/a&gt; - управление кластером&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/xfs/"&gt;&lt;strong&gt;xfs&lt;/strong&gt;&lt;/a&gt; - файловая система&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="filosofiia"&gt;Философия&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Простота&lt;/li&gt;
&lt;li&gt;Минимизация операционных издержек&lt;/li&gt;
&lt;li&gt;Использование подходящих инструментов&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="istoriia"&gt;История&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Забыли сделать &lt;strong&gt;favicon.ico&lt;/strong&gt; до запуска - в первый же день логи
пестрили ошибками 404&lt;/li&gt;
&lt;li&gt;Для хранения данных использовали просто &lt;strong&gt;Django &lt;a href="/tag/orm/"&gt;ORM&lt;/a&gt;&lt;/strong&gt; и
&lt;strong&gt;PostgreSQL&lt;/strong&gt; (из-за postgis)&lt;/li&gt;
&lt;li&gt;Начали с одного слабого сервера, после успешного запуска решили
переехать на &lt;strong&gt;EC2&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;Довольно быстро пришлось вынести &lt;a href="/tag/subd/"&gt;СУБД&lt;/a&gt; на отдельный сервер
(виртуальный, естественно)&lt;/li&gt;
&lt;li&gt;Количество фотографий продолжало расти и расти, даже самый большой
инстанс &lt;strong&gt;EC2&lt;/strong&gt; не справлялся&lt;/li&gt;
&lt;li&gt;Решили вертикально разделить данные на несколько баз, с использованием
механизма &lt;strong&gt;routers&lt;/strong&gt; из ORM, параллельно избавившись от внешних ключей&lt;/li&gt;
&lt;li&gt;Через несколько месяцев суммарный размер базы данных перевалил за 60Гб и
перестало справляться и это решение&lt;/li&gt;
&lt;li&gt;Следующим шагом стало горизонтальное разбиение данных &lt;em&gt;(sharding)&lt;/em&gt;:&lt;/li&gt;
&lt;li&gt;Создали несколько тысяч логических баз данных.&lt;/li&gt;
&lt;li&gt;Распределили их по существенно меньшему количеству физических серверов (читай: виртуальных машин).&lt;/li&gt;
&lt;li&gt;Написали свой механизм определения где искать какую базу данных, с поддержкой миграции (вероятно тоже на основе routers).&lt;/li&gt;
&lt;li&gt;По последним данным под &lt;strong&gt;PostgreSQL&lt;/strong&gt; используется 12+12 виртуальных
машин с максимальной оперативной памятью (68.4Гб), а также сетевые диски
EBS, объединенные в программный RAID посредством mdadm. Это необходимо,
чтобы весь массив данных помещался в памяти, EBS не в состоянии
обеспечить достаточную производительность.&lt;/li&gt;
&lt;li&gt;С некоторыми задачами лучше справляется &lt;strong&gt;Redis&lt;/strong&gt;:&lt;/li&gt;
&lt;li&gt;Для каждого пользователя в Redis есть список идентификаторов новых
фотографий от других пользователей, на которых он подписан.&lt;/li&gt;
&lt;li&gt;При отображении потока новых для пользователя фотографий делается
выборка части такого списка, после чего посредством multiget достается
подробная о них информация из memcached.&lt;/li&gt;
&lt;li&gt;Пробовали возложить на него задачу хранения списков подписчиков, но в
итоге вернулись к решению на &lt;strong&gt;PostgreSQL&lt;/strong&gt; с небольшим кэшированием.&lt;/li&gt;
&lt;li&gt;В Redis также хранится информация о сессиях.&lt;/li&gt;
&lt;li&gt;Несколько фактов о Redis:&lt;ul&gt;
&lt;li&gt;Так как все находится в памяти - очень быстрые операции записи и работы с множествами.&lt;/li&gt;
&lt;li&gt;Является не заменой, а дополнением к основному хранилищу данных.&lt;/li&gt;
&lt;li&gt;Redis хорош для структур данных, которые относительно ограничены.&lt;/li&gt;
&lt;li&gt;Отлично подходит для кэширования комплексных структур данных, где нужно большее, чем просто получить значение по ключу (например - счетчики, подмножества, проверка вхождения в множества).&lt;/li&gt;
&lt;li&gt;Механизм репликации (посредством slaveof) позволяет легко
масштабировать операции чтения.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Пользователи синхронно загружают фотографии на медиа-сервер с
(опциональными) заголовком и месте на карте, все остальное происходит
асинхронно посредством очередей, например:&lt;ul&gt;
&lt;li&gt;Сохраняются гео-метки, обновляется &lt;strong&gt;Solr&lt;/strong&gt; (который впоследствии заменил postgis).&lt;/li&gt;
&lt;li&gt;Идентификатор нового фото добавляется в обсуждавшиеся выше списки для всех подписчиков автора.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Поначалу использовали &lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; + &lt;code&gt;mod_wsgi&lt;/code&gt; для запуска
&lt;strong&gt;Django&lt;/strong&gt;, впоследствии перешли к gunicorn из-за меньшего потребления
ресурсов и простоты настройки.&lt;/li&gt;
&lt;li&gt;С недавних пор начали использовать&amp;nbsp;&lt;strong&gt;Amazon ELB&lt;/strong&gt;&amp;nbsp;вместо &lt;strong&gt;DNS
round-robin&lt;/strong&gt; для первичной балансировки входяших HTTP-запросов, что
позволило:&lt;/li&gt;
&lt;li&gt;избежать необходимости дешифровки &lt;a href="/tag/ssl/"&gt;&lt;strong&gt;SSL&lt;/strong&gt;&lt;/a&gt; посредством nginx;&lt;/li&gt;
&lt;li&gt;ускорить исключение из балансировки проблемных серверов.&lt;/li&gt;
&lt;li&gt;Благодаря использованию &lt;strong&gt;xfs&lt;/strong&gt; есть возможность "замораживать" и
"размораживать" дисковые массивы при резервном копировании.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="podvodim-itogi"&gt;Подводим итоги&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Многие проблемы с масштабируемостью - результат банальных
    человеческих ошибок.&lt;/li&gt;
&lt;li&gt;Масштабирование = замена всех деталей в машине на скорости 150 км/ч.&lt;/li&gt;
&lt;li&gt;Заранее сложно узнать как в основном будут обращаться к данным, без
    реального использования.&lt;/li&gt;
&lt;li&gt;В первую очередь попытайтесь адаптировать известные Вам технологии и
    инструменты для создания простого и понятного решения, прежде чем
    бросаться на поиски чего-то нетривиального.&lt;/li&gt;
&lt;li&gt;Дополните свое основное хранилище более гибким компонентом, вроде
    Redis.&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;DRY: не делайте одну и ту же работу несколько раз.&lt;/li&gt;
&lt;li&gt;Слабая связанность посредством уведомлений или сигналов позволяет
    легко менять структуру проекта.&lt;/li&gt;
&lt;li&gt;Дисковый ввод-вывод часто оказывается узким местом, особенно на EC2.&lt;/li&gt;
&lt;li&gt;Спускаться до C нужно только при необходимости, большую часть работы
    лучше делать в Python.&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;a href="https://www.insight-it.ru/consulting/"&gt;консультантами&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Культура открытости вокруг разработки.&lt;/li&gt;
&lt;li&gt;Делитесь с &lt;a href="/tag/opensource/"&gt;opensource&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;/li&gt;
&lt;/ul&gt;
&lt;h2 id="istochnik-informatsii"&gt;Источник информации&lt;/h2&gt;
&lt;p&gt;Упоминавшаяся во вступлении неприлично длинная презентация из 185
слайдов:&lt;/p&gt;
&lt;iframe data-aspect-ratio="" data-auto-height="true" frameborder="0" height="600" id="doc_73113" scrolling="no" src="//www.scribd.com/embeds/89025069/content?start_page=1&amp;amp;view_mode=scroll" width="100%"&gt;&lt;/iframe&gt;
&lt;p&gt;На видео, к сожалению, это выступление не записывалось.&lt;/p&gt;
&lt;p&gt;Часть информации взята из &lt;a href="https://www.insight-it.ru/goto/ce2d4e38/" rel="nofollow" target="_blank" title="http://instagram-engineering.tumblr.com/"&gt;технического блога Instagram&lt;/a&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Fri, 13 Apr 2012 20:11:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-04-13:highload/2012/arkhitektura-instagram/</guid><category>Amazon</category><category>Android</category><category>CloudFront</category><category>django</category><category>EC2</category><category>ELB</category><category>Fabric</category><category>Facebook</category><category>gearman</category><category>gunicorn</category><category>HAProxy</category><category>Intagram</category><category>iOS</category><category>Linux</category><category>Memcached</category><category>Munin</category><category>nginx</category><category>ORM</category><category>pgbouncer</category><category>pgFouine</category><category>Pingdom</category><category>postgis</category><category>PostgreSQL</category><category>Python</category><category>Redis</category><category>Route53</category><category>S3</category><category>Solr</category><category>statsd</category><category>Ubuntu</category><category>WSGI</category><category>xfs</category><category>Архитектура Instagram</category></item><item><title>Архитектура Tumblr</title><link>https://www.insight-it.ru//highload/2012/arkhitektura-tumblr/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/e90ae6ea/" rel="nofollow" target="_blank" title="http://www.tumblr.com"&gt;&lt;strong&gt;Tumblr&lt;/strong&gt;&lt;/a&gt; - одна из самых популярных в мире
платформ для блоггинга, которая делает ставку на привлекательный внешний
вид, юзабилити и дружелюбное сообщество. Хоть проект и не особо на слуху
в России, цифры говорят сами за себя: 24й по посещаемости сайт в США
с&amp;nbsp;15 миллиардами просмотров страниц в месяц. Хотите познакомиться с
историей этого проекта, выросшего из простого стартапа?
&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="vvedenie"&gt;Введение&lt;/h2&gt;
&lt;p&gt;Как и всем успешным стартапам, Tumblr удалось преодолеть опасную пропать
между начинающим проектом и широко известной компанией. Поиск правильных
людей, эволюция инфраструктуры, поддержка старых решений, паника по
поводу значительного роста посещаемости от месяца к месяцу, при этом в
команде только 4 технических специалиста - все это заставляло
руководство Tumblr принимать тяжелые решения о том над чем стоит
работать, а над чем - нет. Сейчас же технический персонал расширился до
20 человек и у них достаточно энергии для преодоления всех текущих
проблем и разработки новых интересных технических решений.&lt;/p&gt;
&lt;p&gt;Поначалу Tumblr был вполне типичным большим &lt;a href="/tag/lamp/"&gt;LAMP&lt;/a&gt;
приложением. Сейчас же они двигаются в направлении модели распределенных
сервисов, построенных вокруг существенно менее распространенных
технологий. Основные усилия сейчас вкладываются в постепенный уход от
&lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; в пользу более "правильных" и "современных" решений,
оформленных в виде сервисов. Параллельно с переходом к новым технологиям
идут изменения и в команде проекта: от небольшой группы энтузиастов к
полноценной команде разработчиков, имеющей четкую структуру и сферы
ответственности, но тем не менее жаждущей реализовывать новый функционал
и обустраивать совершенно новую инфраструктуру проекта.&lt;/p&gt;
&lt;h2 id="platforma"&gt;Платформа&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/centos/"&gt;CentOS&lt;/a&gt; на серверах, &lt;a href="/tag/mac-os-x/"&gt;Mac OS X&lt;/a&gt; для
    разработки&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; - основной веб-сервер&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/php/"&gt;PHP&lt;/a&gt;, &lt;a href="/tag/scala/"&gt;Scala&lt;/a&gt;, &lt;a href="/tag/ruby/"&gt;Ruby&lt;/a&gt; - языки
    программирования&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/finagle/"&gt;Finagle&lt;/a&gt;&amp;nbsp;- асинхронный RPC сервер и клиент&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;, &lt;a href="/tag/hbase/"&gt;HBase&lt;/a&gt;&amp;nbsp;- СУБД&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;,&amp;nbsp;&lt;a href="/tag/redis/"&gt;Redis&lt;/a&gt;&amp;nbsp;- кэширование&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/varnish/"&gt;Varnish&lt;/a&gt;, &lt;a href="/tag/nginx/"&gt;nginx&lt;/a&gt; - отдача статики&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/haproxy/"&gt;HAProxy&lt;/a&gt; - балансировка нагрузки&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/kestrel/"&gt;kestrel&lt;/a&gt;, &lt;a href="/tag/gearman/"&gt;gearman&lt;/a&gt; - очередь задач&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/thrift/"&gt;Thrift&lt;/a&gt; - сериализация&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/kafka/"&gt;Kafka&lt;/a&gt; - распределенная шина сообщений&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt; - обработка статистики&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/zookeeper/"&gt;ZooKeeper&lt;/a&gt; - хранение конфигурации и состояний
    системы&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/git/"&gt;git&lt;/a&gt; - система контроля версий&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/jenkins/"&gt;Jenkins&lt;/a&gt; - непрерывное тестирование&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Около 500 миллионов просмотров страниц в день&lt;/li&gt;
&lt;li&gt;Более 15 миллиардов просмотров страниц в месяц&lt;/li&gt;
&lt;li&gt;Посещаемость растет примерно на 30% в месяц&lt;/li&gt;
&lt;li&gt;Пиковые нагрузки порядка 40 тысяч запросов в секунду&lt;/li&gt;
&lt;li&gt;Около 20 технических специалистов в команде&lt;/li&gt;
&lt;li&gt;Каждый день создается около 50Гб новых постов и 2.7Тб обновлений списков
последователей&lt;/li&gt;
&lt;li&gt;Более 1Тб статистики обрабатывается в &lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt; ежедневно&lt;/li&gt;
&lt;li&gt;Используется порядка 1000 серверов:&lt;ul&gt;
&lt;li&gt;500 веб-серверов c Apache и PHP-приложением&lt;/li&gt;
&lt;li&gt;200 серверов баз данных (существенная их часть - резервные)&lt;ul&gt;
&lt;li&gt;47 пулов&lt;/li&gt;
&lt;li&gt;30 партиций (шардов)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;30 серверов &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;25 серверов Redis&lt;/li&gt;
&lt;li&gt;15 серверов Varnish&lt;/li&gt;
&lt;li&gt;25 серверов HAProxy&lt;/li&gt;
&lt;li&gt;8 серверов nginx&lt;/li&gt;
&lt;li&gt;14 серверов для очередей задач&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tipichnoe-ispolzovanie"&gt;Типичное использование&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;Tumblr&lt;/strong&gt; используется несколько по-другому, чем другие социальные
сети:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;При более чем 50 миллионах постов в день, каждый из них попадает в
среднем к нескольким сотням читателей. Это и не несколько
пользователей с миллионами читателей (например, популярные личности
в Twitter) и не миллиарды личных сообщений.&lt;/li&gt;
&lt;li&gt;Ориентированность на длинные публичные сообщения, полные интересной
информацией и картинками/видео, заставляет пользователей проводить
долгие часы каждый день за чтением Tumblr.&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;p&gt;Публичные блоги называют Tumblelog'ами, они не так динамичны и легко
кэшируются.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;Сложнее всего масштабировать Dashboard, страницу, где пользователи в
реальном времени читают что нового у блоггеров, на которых они
подписаны:&lt;ul&gt;
&lt;li&gt;Кэширование практически бесполезно, так как для активных
пользователей запросы редко повторяются.&lt;/li&gt;
&lt;li&gt;Информация должна отображаться в реальном времени, быть целостной и
не "задерживаться".&lt;/li&gt;
&lt;li&gt;Около 70% просмотров страниц приходится именно на Dashboard, почти
все пользователи им пользуются.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="staraia-arkhitektura"&gt;Старая архитектура&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Когда проект только начинался, Tumblr размещался в Rackspace и последние выдавали каждому блогу с собственным доменом A-запись. Когда они переросли Rackspace, они не смогли полноценно мигрировать в новый
датацентр, в том числе из-за количества пользователей. Это было в 2007
году, но у них по-прежнему часть доменов ведут на Rackspace и
перенаправляются в новый датацентр с помощью HAProxy и Varnish. Подобных
"унаследованных" проблем у проекта очень много.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;С технической точки зрения проект прошел по пути типичной эволюции
&lt;strong&gt;LAMP&lt;/strong&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Исторически разработан на &lt;strong&gt;PHP&lt;/strong&gt;, все началось с веб-сервера,
сервера баз данных и начало потихоньку развиваться.&lt;/li&gt;
&lt;li&gt;Чтобы справляться с нагрузкой они начали использовать memcache,
затем добавили кэширование целых страниц и статических файлов, потом
поставили HAProxy перед кэшами, после чего сделали партиционирование
на уровне &lt;strong&gt;MySQL&lt;/strong&gt;, что сильно облегчило им жизнь.&lt;/li&gt;
&lt;li&gt;Они делали все, чтобы выжать максимум из каждого сервера.&lt;/li&gt;
&lt;li&gt;Было разработано два сервиса на C: генератор уникальных
идентификаторов на основе HTTP и libevent, а также
&lt;a href="https://www.insight-it.ru/goto/533d5aae/" rel="nofollow" target="_blank" title="http://engineering.tumblr.com/post/7819252942/staircar-redis-powered-notifications"&gt;Staircar&lt;/a&gt;,
использующий Redis для обеспечения уведомлений в реальном времени на
Dashboard.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Dashboard использует подход
&lt;a href="https://www.insight-it.ru/goto/f4d9020c/" rel="nofollow" target="_blank" title="http://www2.parc.com/istl/projects/ia/papers/sg-sigir92/sigir92.html"&gt;"разбрасывать-собирать"&lt;/a&gt;,
так как из-за отсортировонности данных по времени традиционные схемы
партиционирования работали не очень хорошо. По их прогнозам текущая
реализация позволит им рости еще в течении полугода.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="novaia-arkhitektura"&gt;Новая архитектура&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Приоритетным направлением стали технологии, основанные на JVM, по
причине более быстрой разработки и доступности квалифицированных
кадров. Мотивация несколько спорная, особенно если учесть, что речь
идет в первую очередь о &lt;a href="/tag/scala/"&gt;Scala&lt;/a&gt;, а не
о&amp;nbsp;&lt;a href="/tag/scala/"&gt;Java&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Основная цель - вынести все из PHP приложения в отдельные сервисы, что
сделает его лишь тонким клиентом к внутреннему API.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Почему выбор пал именно на &lt;strong&gt;Scala&lt;/strong&gt; и &lt;strong&gt;Finagle&lt;/strong&gt;?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Многие разработчики имели опыт с Ruby и PHP, так что Scala был
привлекательным (цитата, логики мало)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/d7e3c54e/" rel="nofollow" target="_blank" title="https://github.com/twitter/finagle"&gt;Finagle&lt;/a&gt; был одним из основных
факторов в пользу JVM: это библиотека, разработанная в Twitter,
которая решает большинство распределенных задач вроде маршрутизации
запросов и обнаружение/регистрацию сервисов - не пришлось
реализовывать это все с нуля.&lt;/li&gt;
&lt;li&gt;В Scala не принято использовать общие состояния, что избавляет
разработчиков от забот с потоками выполнения и блокировками.&lt;/li&gt;
&lt;li&gt;Им очень нравится Thrift в роли программного интерфейса из-за его
высокой производительности (он кроссплатформенный и к JVM никак не
относится)&lt;/li&gt;
&lt;li&gt;Нравится &lt;a href="/tag/netty/"&gt;Netty&lt;/a&gt;, но не хочется связываться с Java, еще
один аргумент в пользу Scala.&lt;/li&gt;
&lt;li&gt;Рассматривали &lt;a href="/tag/node-js/"&gt;Node.js&lt;/a&gt;, но отказались так как под
JVM проще найти разработчиков, а также из-за отсутствия стандартов,
"лучших практик" и большого количества качественно протестированного
кода.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Старые внутренние сервисы также переписываются с C + libevent на Scala + Fingle.&lt;/p&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Используется 6 внутренних сервисов, над которыми работает отдельная
команд. На запуск сервиса с нуля уходит около 2-3 недель.&lt;/li&gt;
&lt;li&gt;Новые, нереляционные СУБД, такие как HBase и Redis, вводятся в
эксплуатацию, но основным хранилищем по-прежнему остается сильно
партиционированный MySQL.&lt;/li&gt;
&lt;li&gt;HBase используется для сервиса сокращенных ссылок для постов, а также
всех исторических данных и аналитики. HBase хорошо справляется с
ситуациями, где необходимы миллионы операций записи в секунду, но он не
достаточно стабилен, чтобы полностью заменить проверенное временем
решение на MySQL в критичных для бизнеса задачах.&lt;/li&gt;
&lt;li&gt;Партиционированный MySQL плохо справляется с отсортированными по времени данными, так как один из серверов всегда оказывается существенно более "горячим", чем остальными. Также сталкивались с значительными задержками в репликации из-за большого количества параллельных операций добавления данных.&lt;/li&gt;
&lt;li&gt;Используется 25 серверов Redis с 8-32 процессами на каждом, что означает
порядка 300-400 экземпляров Redis в сумме.&lt;ul&gt;
&lt;li&gt;Используется для уведомлений в реальном времени на Dashboard (о
событиях вроде "кому-то понравился Ваш пост").&lt;/li&gt;
&lt;li&gt;Высокое соотношений операций записи к операциям чтения сделало MySQL
не очень подходящим кандидатом.&lt;/li&gt;
&lt;li&gt;Уведомления не так критичны, их потеря допустима, что позволило
отключить персистентность Redis.&lt;/li&gt;
&lt;li&gt;Был создан интерфейс между Redis и отложенными задачами в Finagle.&lt;/li&gt;
&lt;li&gt;Сервис коротких ссылок также использует Redis как кэш, а HBase для
постоянного хранения.&lt;/li&gt;
&lt;li&gt;Вторичный индекс Dashboard также построен вокруг Redis.&lt;/li&gt;
&lt;li&gt;Redis также используется для хранения задач Gearman, для чего был
написан memcache proxy на основе Finale.&lt;/li&gt;
&lt;li&gt;Постепенно отказываются от memcached в пользу Redis в роли основного
кэша. Производительность у них сопоставима.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Внутренним сервисам необходим доступ к потоку всех событий в системе
(создание, редактирование и удаление постов, нравится или не нравится и
т.п.), для чего была созданна внутренняя шина сообщений &lt;em&gt;(англ.
firehose, пожарный шланг)&lt;/em&gt;:&lt;ul&gt;
&lt;li&gt;Пробовали использовать в этой роли Scribe, но так как оно по сути
свелось к пропусканию логов через grep в реальном времени - нагрузки
оно не выдержало.&lt;/li&gt;
&lt;li&gt;Текущая реализация основана на Kafka, решению аналогичной задачи от
LinkedIn на Scala.&lt;/li&gt;
&lt;li&gt;MySQL также не рассматривался из-за большой доли операций записи.&lt;/li&gt;
&lt;li&gt;Внутри сервисы используют HTTP потоки для чтения данных, хотя Thrift
интерфейс также используется.&lt;/li&gt;
&lt;li&gt;Поток сообщений хранит события за последнюю неделю с возможностью
указать момент времени с которого считывать данные при открытии
соединения.&lt;/li&gt;
&lt;li&gt;Поддерживается абстракция "группы потребителей", которая позволяет
группе клиентов вместе обрабатывать один поток данных вместе и
независимо, то есть одно и то же сообщение не попадет дважды к
клиентам из одной группы.&lt;/li&gt;
&lt;li&gt;ZooKeeper используется для периодического сохранения текущей позиции
каждого клиента в потоке.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Новая архитектура Dashboard основана на принципе ячеек или ящиков
входящих сообщений:&lt;ul&gt;
&lt;li&gt;Каждая "ячейка" отвечает за группу пользователей и читает новые события
с шины сообщений, если один из её пользователей-подопечных подписан на
автора только что опубликованного поста, то пост добавляется в "почтовый
ящик" подписанного пользователя.&lt;/li&gt;
&lt;li&gt;Когда пользователь заходит в Dashboard его запрос попадает в его ячейку,
которая возвращает ему нужную часть непрочитанных постов.&lt;/li&gt;
&lt;li&gt;Каждая ячейка состоит из трех групп серверов:&lt;ul&gt;
&lt;li&gt;HBase для постоянного хранения копий постов и почтовых ящиков;&lt;/li&gt;
&lt;li&gt;Redis для кэширование свежих данных;&lt;/li&gt;
&lt;li&gt;Сервис, читающий данные из шины и предоставляющий доступ к ящикам
посредством Thrift.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;В HBase используется две таблицы:&lt;ul&gt;
&lt;li&gt;Отсортированный &lt;strong&gt;список идентификаторов постов&lt;/strong&gt; для каждого
пользователя в ячейке, именно в том виде, как они будут отображены в
итоге.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Копии всех постов&lt;/strong&gt; по идентификаторам, что позволяет выдать все
данные для отрисовки Dashboard без обращений к серверам вне одной
ячейки.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ячейки представляют собой независимые единицы, что позволяет легко
масштабировать систему при росте числа пользователей.&lt;/li&gt;
&lt;li&gt;Платой за относительно безболезненность масштабирования является
чрезвычайная избыточность данных: при том что ежедневно создается лишь
50Гб постов, суммарный объем данных в ячейках растет на 2.7Тб в день.&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;li&gt;Tumblr географически по-прежнему находится в одном датацентре (если не
считать незначительное присутствие в Rackspace), распределение по
нескольким лишь в планах.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="razvertyvanie"&gt;Развертывание&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Начиналось как несколько rsync-скриптов для распространения
    PHP-приложения. Как только машин стало больше 200 такой подход стал
    занимать слишком много времени.&lt;/li&gt;
&lt;li&gt;Следующий вариант был основан на &lt;a href="/tag/capistrano/"&gt;Capistrano&lt;/a&gt;:
    были созданы три стадии процесса развертывания (разработка,
    тестирование, боевой). Неплохо справлялся с десятками серверов, но
    на сотнях также был слишком медленным, так как основывался на SSH.&lt;/li&gt;
&lt;li&gt;Итоговый вариант основан на &lt;strong&gt;Func&lt;/strong&gt;, решении от
    &lt;a href="/tag/redhat/"&gt;RedHat&lt;/a&gt;, позволившим заменить &lt;a href="/tag/ssh/"&gt;SSH&lt;/a&gt; на
    более легковесный протокол.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="razrabotka"&gt;Разработка&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Поначалу философия была такова, что каждый мог использовать любые
технологии, которые считал уместным. Но довольно скоро пришлось
стандартизировать стек технологий, чтобы было легче нанимать и вводить в
работу новых сотрудников, а также для более оперативного решения
технических проблем.&lt;/li&gt;
&lt;li&gt;Каждый разработчик имеет одинаковую заранее настроенную рабочую станцию,
которая обновляется посредством &lt;a href="/tag/puppet/"&gt;Puppet&lt;/a&gt;:&lt;ul&gt;
&lt;li&gt;Настроена публикация изменений, тестирование и развертывание новых
версий.&lt;/li&gt;
&lt;li&gt;Разработчики используют vim и Textmate.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Новый PHP код систематически инспектируется другими разработчиками.&lt;/li&gt;
&lt;li&gt;Внутренние сервисы подвергаются непрерывному тестированию посредством
Jenkins.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="struktura-komand"&gt;Структура команд&lt;/h2&gt;
&lt;p&gt;Проект разбит на 6 команд:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Инфраструктура:&lt;/strong&gt;&amp;nbsp;все, что ниже 5 уровня по модели OSI -
    маршрутизация, TCP/IP, DNS, оборудование и.т.п.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Платформа:&lt;/strong&gt;&amp;nbsp;разработка основного приложения, партиционирование
    SQL, взаимодействие сервисов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Надежность (SRE):&lt;/strong&gt;&amp;nbsp;сфокусирована на текущие потребности с точки
    зрения надежности и масштабируемости.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Сервисы:&lt;/strong&gt;&amp;nbsp;занимается более стратегической разработкой того, что
    понадобится через один-два месяца.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Эксплуатация:&lt;/strong&gt;&amp;nbsp;отвечает за обнаружение и реагирование на
    проблемы, плюс тонкая настройка.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="naim"&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;/ul&gt;
&lt;h2 id="podvodim-itogi"&gt;Подводим итоги&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Автоматизация - ключ к успеху крупного проекта.&lt;/li&gt;
&lt;li&gt;При партиционировании MySQL может масштабироваться, но лишь при
    преобладании операций чтения.&lt;/li&gt;
&lt;li&gt;Redis с отключенной персистентностью легко может заменить memcached.&lt;/li&gt;
&lt;li&gt;Scala достойно себя проявляет в роли языка программирования для
    внутренних сервисов, во многом благодаря обширной Java-экосистеме.&lt;/li&gt;
&lt;li&gt;Внедряйте новые технологии постепенно, поначалу работать с HBase и
    Redis было очень болезненно, они были включены в основной стек
    технологий только после испытаний в некритичных сервисах и
    подпроектах, где цена ошибки не так велика.&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;a href="https://www.insight-it.ru/highload/2010/arkhitektura-facebook/"&gt;Facebook&lt;/a&gt;,
    &lt;a href="https://www.insight-it.ru/highload/2011/arkhitektura-twitter-dva-goda-spustya/"&gt;Twitter&lt;/a&gt;,
    &lt;a href="https://www.insight-it.ru/highload/2011/arkhitektura-google-2011/"&gt;Google&lt;/a&gt;
    или
    &lt;a href="https://www.insight-it.ru/highload/2008/arkhitektura-linkedin/"&gt;LinkedIn&lt;/a&gt; -
    если нет прямого доступа, всегда можно получить нужную информацию
    через одно-два "рукопожатия".&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Статья написана на основе &lt;a href="https://www.insight-it.ru/goto/1444dc9b/" rel="nofollow" target="_blank" title="http://highscalability.com/blog/2012/2/13/tumblr-architecture-15-billion-page-views-a-month-and-harder.html"&gt;интервью&lt;/a&gt;&amp;ensp;&lt;a href="https://www.insight-it.ru/goto/f1d04e95/" rel="nofollow" target="_blank" title="https://www.linkedin.com/in/bmatheny"&gt;Blake Matheny&lt;/a&gt;, директора по разработке платформы Tumblr.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Tue, 21 Feb 2012 16:29:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-02-21:highload/2012/arkhitektura-tumblr/</guid><category>Apache</category><category>Capistrano</category><category>CentOS</category><category>Finagle</category><category>Func</category><category>gearman</category><category>Git</category><category>Hadoop</category><category>HAProxy</category><category>HBase</category><category>jenkins</category><category>kafka</category><category>Kestrel</category><category>LAMP</category><category>Mac OS X</category><category>Memcached</category><category>MySQL</category><category>nginx</category><category>PHP</category><category>puppet</category><category>Redis</category><category>Ruby</category><category>Scala</category><category>Thrift</category><category>Tumblr</category><category>Varnish</category><category>ZooKeeper</category></item><item><title>Архитектура Stack Exchange Network</title><link>https://www.insight-it.ru//highload/2011/arkhitektura-stack-exchange-network/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/8d9e30a4/" rel="nofollow" target="_blank" title="http://stackexchange.com/"&gt;Stack Exchange Network&lt;/a&gt; представляет собой
сеть из 46 сайтов вопросов-ответов на совершенно разные темы от
программирования до кулинарии. Проект вырос из известной в узких кругах
тусовки программистов &lt;a href="https://www.insight-it.ru/goto/dd7cd9bb/" rel="nofollow" target="_blank" title="http://stackoverflow.com/"&gt;Stack Overflow&lt;/a&gt;, об
архитектуре которой &lt;a href="https://www.insight-it.ru/highload/2010/arkhitektura-stack-overflow/"&gt;я уже рассказывал&lt;/a&gt; чуть больше года назад. Проект активно развивается и уже появилось приличное количество новой информации, которой я и спешу с Вами поделиться.
&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;95 миллионов просмотров страниц в месяц&lt;/li&gt;
&lt;li&gt;800 HTTP запросов в секунду&lt;/li&gt;
&lt;li&gt;180 DNS запросов в секунду&lt;/li&gt;
&lt;li&gt;Загруженность интернет-канала в 55 Мбит/с&lt;/li&gt;
&lt;li&gt;16 миллионов уникальных пользователей в месяц&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tekhnologii"&gt;Технологии&lt;/h2&gt;
&lt;h3 id="razrabotka"&gt;Разработка&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/c/"&gt;C#&lt;/a&gt; - основной язык программирования&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/visual-studio/"&gt;Visual Studio 2010 Team Suite&lt;/a&gt; -&amp;nbsp;IDE&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/asp-net/"&gt;Microsoft ASP.NET 4.0&lt;/a&gt; - framework&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/asp-net-mvc/"&gt;ASP.NET MVC 3&lt;/a&gt; -&amp;nbsp;web Framework&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/razor/"&gt;Razor&lt;/a&gt; - генератор шаблонов&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/jquery/"&gt;jQuery 1.4.2&lt;/a&gt; - JavaScript framework&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/linq-to-sql/"&gt;LINQ to SQL&lt;/a&gt; и немного чистого SQL - доступ к
    данным&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/mercurial/"&gt;Mercurial&lt;/a&gt; и &lt;a href="/tag/kiln/"&gt;Kiln&lt;/a&gt; - контроль версий
    исходного кода&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/beyond-compare/"&gt;Beyond Compare 3&lt;/a&gt; - инструмент для сравнения&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="programmnoe-obespechenie"&gt;Программное обеспечение&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/886b3540/" rel="nofollow" target="_blank" title="http://stackoverflow.com/questions/177901/what-does-wisc-stack-mean"&gt;WISC&lt;/a&gt;
    стек получен условно-бесплатно с
    помощью&amp;nbsp;&lt;a href="https://www.insight-it.ru/goto/b478b941/" rel="nofollow" target="_blank" title="http://blog.stackoverflow.com/2009/03/stack-overflow-and-bizspark/"&gt;BizSpark&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/windows-server/"&gt;Windows Server&lt;/a&gt;&lt;a href="/tag/windows-server-2008/"&gt;2008 R2
    x64&lt;/a&gt; - основная операционная система&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/ms-sql-server-2008/"&gt;MS SQL Server 2008 R2&lt;/a&gt; на&amp;nbsp;&lt;a href="/tag/windows-server-2008/"&gt;Windows Server
    2008 Enterprise Edition x64&lt;/a&gt; - база
    данных&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/ubuntu-server/"&gt;Ubuntu Server&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/centos/"&gt;CentOS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/iis/"&gt;IIS 7.0&lt;/a&gt; - веб-сервер&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/haproxy/"&gt;HAProxy&lt;/a&gt; - балансировка нагрузки&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/redis/"&gt;Redis&lt;/a&gt; - используется как распределенная система
    кэширования&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/cruisecontrol-net/"&gt;CruiseControl.NET&lt;/a&gt; - сборки и
    автоматическая система развертывания кода&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/lucene/"&gt;Lucene.NET&lt;/a&gt; - полнотекстовый поиск&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/bacula/"&gt;Bacula&lt;/a&gt; - резервное копирование&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/nagios/"&gt;Nagios&lt;/a&gt; (с плагинами&amp;nbsp;&lt;code&gt;n2rrd&lt;/code&gt; и &lt;code&gt;drraw&lt;/code&gt;) для мониторинга&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/splunk/"&gt;Splunk&lt;/a&gt; - сбор и агрегация логов&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/sql-monitor/"&gt;SQL Monitor&lt;/a&gt; от&amp;nbsp;Red Gate - мониторинг SQL Server&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/bind/"&gt;Bind&lt;/a&gt; -&amp;nbsp;DNS&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/dotnetopenid/"&gt;DotNetOpenId&lt;/a&gt; - реализация OpenID на .NET&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/wmd/"&gt;WMD&lt;/a&gt; - текстовый редактор&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/prettify/"&gt;Prettify&lt;/a&gt; - подсветка синтаксиса&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/markdownsharp/"&gt;MarkdownSharp&lt;/a&gt; - обработчик разметки Markdown
    на C#&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/flot/"&gt;Flot&lt;/a&gt; - построение графиков на JavaScript&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="vneshnie-servisy"&gt;Внешние сервисы&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/recaptcha/"&gt;reCAPTCHA&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/kiln/"&gt;Kiln&lt;/a&gt; - Mercurial хостинг&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/pingdom/"&gt;Pingdom&lt;/a&gt; - внешний мониторинг и уведомления&lt;/li&gt;
&lt;li&gt;CDN не используется, его роль выполняет&amp;nbsp;&lt;a href="https://www.insight-it.ru/goto/a5057c7b/" rel="nofollow" target="_blank" title="http://sstatic.net/"&gt;sstatic.net&lt;/a&gt;, отдельный домен для статичных файлов SEN без cookie&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="oborudovanie_1"&gt;Оборудование&lt;/h2&gt;
&lt;h3 id="datatsentry"&gt;Датацентры&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;1 стойка в Peak Internet, штат Орегон (чат и обнаружение данных)&lt;/li&gt;
&lt;li&gt;2 стойки в Peer 1, Нью-Йорк (остальная часть SEN)&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="servery"&gt;Серверы&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;10 веб-серверов:&lt;ul&gt;
&lt;li&gt;Dell R610&lt;/li&gt;
&lt;li&gt;1x Intel Xeon Processor E5640 @ 2.66 GHz&lt;/li&gt;
&lt;li&gt;16 GB RAM&lt;/li&gt;
&lt;li&gt;Windows Server 2008 R2&lt;/li&gt;
&lt;li&gt;IIS&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2 сервера баз данных:&lt;ul&gt;
&lt;li&gt;Dell R710&lt;/li&gt;
&lt;li&gt;2x Intel Xeon Processor X5680 @ 3.33 GHz&lt;/li&gt;
&lt;li&gt;64 GB RAM&lt;/li&gt;
&lt;li&gt;8 жестких дисков&lt;/li&gt;
&lt;li&gt;MS SQL Server 2008 R2&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2 виртуальных сервера для балансировки нагрузки:&lt;ul&gt;
&lt;li&gt;1x Intel Xeon Processor E5640 @ 2.66 GHz&lt;/li&gt;
&lt;li&gt;4 GB RAM&lt;/li&gt;
&lt;li&gt;Ubuntu Server&lt;/li&gt;
&lt;li&gt;HAProxy&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2 сервера для кэша:&lt;ul&gt;
&lt;li&gt;Dell R610&lt;/li&gt;
&lt;li&gt;2x Intel Xeon Processor E5640 @ 2.66 GHz&lt;/li&gt;
&lt;li&gt;16 GB RAM&lt;/li&gt;
&lt;li&gt;CentOS&lt;/li&gt;
&lt;li&gt;Redis&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1 сервер для резервного копирования:&lt;ul&gt;
&lt;li&gt;Dell R610&lt;/li&gt;
&lt;li&gt;1x Intel Xeon Processor E5640 @ 2.66 GHz&lt;/li&gt;
&lt;li&gt;32 GB RAM&lt;/li&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;li&gt;Bacula&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;1 сервер для мониторинга, управления и сбора логов:&lt;ul&gt;
&lt;li&gt;Dell R610&lt;/li&gt;
&lt;li&gt;1x Intel Xeon Processor E5640 @ 2.66 GHz&lt;/li&gt;
&lt;li&gt;32 GB RAM&lt;/li&gt;
&lt;li&gt;Linux&lt;/li&gt;
&lt;li&gt;Nagios&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;2 сервера для виртуализации:&lt;ul&gt;
&lt;li&gt;Dell R610&lt;/li&gt;
&lt;li&gt;1x Intel Xeon Processor E5640 @ 2.66 GHz&lt;/li&gt;
&lt;li&gt;16 GB RAM&lt;/li&gt;
&lt;li&gt;VMWare ESXi&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="setevoe-oborudovanie"&gt;Сетевое оборудование&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;2 маршрутизатора на Linux&lt;/li&gt;
&lt;li&gt;5 свитчей &amp;nbsp;Dell PowerConnect&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="prochee"&gt;Прочее&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/aa5532bf/" rel="nofollow" target="_blank" title="http://www.wowwee.com/en/products/tech/telepresence/rovio/rovio"&gt;Rovio&lt;/a&gt; -
    маленький робот, позволяющий удаленным разработчиком посетить офис
    "виртуально"&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="komanda_1"&gt;Команда&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;14 разработчиков&lt;/li&gt;
&lt;li&gt;2 системных администратора&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="chto-novogo"&gt;Что нового?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;HAProxy стал использоваться вместо Windows NLB так как HAProxy
    является быстрым, нересурсоемким, бесплатным решением, которое
    работает. Полностью прозрачен для серверов, легче обслуживать по
    сравнению со старым решением, располагается на виртуальных машинах.&lt;/li&gt;
&lt;li&gt;CDN не используется, так как даже "недорогие" решения обходятся в
    очень приличную сумму по сравнению с тем трафиком, который входит в
    тарифный план хостинг-провайдера. Самое дешевой решение CDN от
    Amazon обошлось бы как минимум на тысячу долларов в месяц дороже при
    текущем уровне использования трафика.&lt;/li&gt;
&lt;li&gt;Резервное копирование на диски для быстрого восстановления и на
    кассеты для "истории".&lt;/li&gt;
&lt;li&gt;Полнотекстный поиск в SQL Server плохо интегрируется, нестабилен и
    обладает низким качеством результатов, так что они перешли на
    Lucene.&lt;/li&gt;
&lt;li&gt;Все сайты в SEN теперь работают на общей платформе: используется
    общее оборудование и программное обеспечение.&lt;/li&gt;
&lt;li&gt;Проект разделен на разные сайты для разных ниш, чтобы полностью
    изолировать группы аудитории, специализирующиеся в каждой конкретной
    области.&lt;/li&gt;
&lt;li&gt;Используется агрессивное кэширование, большинство страниц кэшируются
    в виде HTML для анонимных пользователей средствами IIS.&lt;/li&gt;
&lt;li&gt;Используется три уровня кэширования: локальный, относящийся к
    каждому сайту и глобальный.&lt;/li&gt;
&lt;li&gt;Локальный кэш доступен только для каждой пары сайт/сервер:&lt;ul&gt;
&lt;li&gt;Используется для уменьшения сетевых задержек, по сути просто
    через&amp;nbsp;HttpRuntime.Cache.&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;Располагается в Redis.&lt;/li&gt;
&lt;li&gt;Redis настолько быстр, что большую часть времени доступа к кэшу
    занимает передача данных по сети.&lt;/li&gt;
&lt;li&gt;Данные сжимаются перед отправкой в Redis, так как большинство
    данных являются строками и у них есть масса свободных
    вычислительных ресурсов.&lt;/li&gt;
&lt;li&gt;Использование процессорных ресурсов на серверах с Redis
    стремится к нулю.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Глобальный кэш является общим для всех серверов и сайтов:&lt;ul&gt;
&lt;li&gt;Личные сообщения, квоты по API и несколько других по-настоящему
    глобальных вещей располагаются здесь.&lt;/li&gt;
&lt;li&gt;Также используется Redis.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Большинство данных в кэше удаляются через заданный период времени
    (обычно в районе нескольких минут) и практически никогда явно не
    удаляются.&lt;/li&gt;
&lt;li&gt;Когда требуется инвалидация кэша на уровне готовых страниц,
    используется система подписки внутри Redis для отправки сообщений в
    соответствующую часть системы кэширования.&lt;/li&gt;
&lt;li&gt;Для системы ввода-вывода они выбрали Intel X25 SSD в RAID10. RAID
    решил многие вопросы с надежностью, а SSD показывают отличную
    производительностью по сравнению с&amp;nbsp;FusionIO при существенно более
    низкой цене.&lt;/li&gt;
&lt;li&gt;Стоимость лицензий используемых продуктов Microsoft составила бы 242
    тысячи долларов. Но так как они используют программу BizSpark, им не
    пришлось платить большую часть этой суммы.&lt;/li&gt;
&lt;li&gt;Сетевые карты от Broadcom заменяются на сетевые карты от Intel на
    основных production серверах. Это решило большинство проблем с
    потерями соединений, пакетов и таблицами ARP.&lt;/li&gt;
&lt;/ul&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/8a78f426/" rel="nofollow" target="_blank" title="http://highscalability.com/blog/2011/3/3/stack-overflow-architecture-update-now-at-95-million-page-vi.html"&gt;Stack Overflow Architecture Update - Now At 95 Million Page Views
    A&amp;nbsp;Month&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/ac2efccd/" rel="nofollow" target="_blank" title="http://blog.stackoverflow.com/"&gt;Stack Overflow Blog&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/a1b71243/" rel="nofollow" target="_blank" title="http://blog.serverfault.com/2010/10/29/1432571770/"&gt;Stack Overflow&amp;rsquo;s New York Data
    Center&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/f1ab22d7/" rel="nofollow" target="_blank" title="http://blog.serverfault.com/2010/09/10/1097492931/"&gt;Designing For Scalability of Management and Fault
    Tolerance&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/955af379/" rel="nofollow" target="_blank" title="http://blog.stackoverflow.com/2011/01/stack-overflow-search-now-81-less-crappy/"&gt;Stack Overflow Search &amp;mdash; Now 81% Less
    Crappy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/7ab0ab00/" rel="nofollow" target="_blank" title="http://blog.stackoverflow.com/2011/01/state-of-the-stack-2010-a-message-from-your-ceo/"&gt;State of the Stack 2010 (a message from your
    CEO)&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/f4755d56/" rel="nofollow" target="_blank" title="http://blog.stackoverflow.com/2010/01/stack-overflow-network-configuration/"&gt;Stack Overflow Network
    Configuration&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/d29680fc/" rel="nofollow" target="_blank" title="http://meta.stackoverflow.com/questions/69164/does-stackoverflow-use-caching-and-if-so-how"&gt;Does StackOverflow use caching and if so,
    how?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/a1f157a/" rel="nofollow" target="_blank" title="http://meta.stackoverflow.com/questions/6435/how-does-stackoverflow-handle-cache-invalidation"&gt;How does StackOverflow handle cache
    invalidation?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/4812040a/" rel="nofollow" target="_blank" title="http://meta.stackoverflow.com/questions/10369/which-tools-and-technologies-build-the-stack-exchange-network"&gt;Which tools and technologies build the Stack Exchange
    Network?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/d1cfeccf/" rel="nofollow" target="_blank" title="http://meta.stackoverflow.com/questions/2765/how-does-stack-overflow-handle-spam"&gt;How does Stack Overflow handle
    spam?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/58e28ee2/" rel="nofollow" target="_blank" title="http://blog.serverfault.com/post/our-storage-decision/"&gt;Our Storage
    Decision&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/6a63689c/" rel="nofollow" target="_blank" title="http://meta.stackoverflow.com/questions/4766/how-are-hot-questions-selected"&gt;How are &amp;ldquo;Hot&amp;rdquo; Questions
    Selected?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/90fef20/" rel="nofollow" target="_blank" title="http://blog.stackoverflow.com/2010/04/stack-overflow-and-dvcs/"&gt;Stack Overflow and
    DVCS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/fe105178/" rel="nofollow" target="_blank" title="http://chat.stackexchange.com/rooms/127/the-comms-room"&gt;Server Fault Chat
    Room&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Спасибо за внимание! Для оперативного получения свежей информации о
&lt;a href="https://www.insight-it.ru/highload/"&gt;высоконагруженных интернет-проектах&lt;/a&gt; рекомендую &lt;a href="/feed/"&gt;подписаться на RSS&lt;/a&gt;.&lt;/strong&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Thu, 31 Mar 2011 16:05:00 +0400</pubDate><guid>tag:www.insight-it.ru,2011-03-31:highload/2011/arkhitektura-stack-exchange-network/</guid><category>ASP .NET</category><category>ASP .NET MVC</category><category>Bacula</category><category>Beyond Compare 3</category><category>Bind</category><category>C++</category><category>CentOS</category><category>CruiseControl.NET</category><category>DotNetOpenId</category><category>Flot</category><category>Google Analytics</category><category>HAProxy</category><category>IIS</category><category>JQuery</category><category>Kiln</category><category>LINQ to SQL</category><category>Lucene</category><category>MarkdownSharp</category><category>Mercurial</category><category>MS SQL Server 2008</category><category>Nagios</category><category>Pingdom</category><category>Prettify</category><category>Razor</category><category>reCAPTCHA</category><category>Redis</category><category>Splunk</category><category>SQL Monitor</category><category>Ubuntu Server</category><category>Visual Studio</category><category>Windows Server</category><category>Windows Server 2008</category><category>WMD</category></item></channel></rss>