<?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/mysql/feed/index.xml" rel="self"></atom:link><lastBuildDate>Thu, 20 Sep 2012 20:16:00 +0400</lastBuildDate><item><title>Вакансии: PHP и Python разработчики в Киеве</title><link>https://www.insight-it.ru//vacancy/2012/vakansii-php-i-python-razrabotchiki-v-kieve/</link><description>&lt;div class="card orange darken-3"&gt;
&lt;p&gt;&lt;div class="card-content white-text center"&gt;
&lt;strong&gt;Вакансии более не актуальны&lt;/strong&gt;
&lt;/div&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Киевская команда разработчиков игр для социальных и мобильных платформ
Level UP ищет опытных специалистов по
веб-разработке на Python и PHP.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="senior-python-developer"&gt;Senior Python Developer&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Задачи:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Разработка высоконагруженных веб-приложений;&lt;/li&gt;
&lt;li&gt;Разработка внутренних и публичных API;&lt;/li&gt;
&lt;li&gt;Разработка архитектуры комплексных сервисов;&lt;/li&gt;
&lt;li&gt;Конвертирование бизнес-задач в технические решения (R&amp;amp;D).&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;strong&gt;Python&lt;/strong&gt; более 3х лет;&lt;/li&gt;
&lt;li&gt;Сильные навыки применения реляционных и нереляционных баз данных;&lt;/li&gt;
&lt;li&gt;Опыт в разработке высоконагруженных веб-приложений;&lt;/li&gt;
&lt;li&gt;Дружба с &lt;strong&gt;Linux&lt;/strong&gt; и &lt;strong&gt;Git&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;Хорошее знание клиентских технологий (HTML, CSS, Javascript);&lt;/li&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;strong&gt;PHP&lt;/strong&gt; или серверном
    &lt;strong&gt;Javascript&lt;/strong&gt; &lt;em&gt;(node.js)&lt;/em&gt;;&lt;/li&gt;
&lt;li&gt;Опыт разработки инструментов для верстки, автоматизации верстки,
    шаблонизаторов и пр.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="senior-php-developer"&gt;Senior PHP Developer&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Задачи:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Разработка высоконагруженных социальных веб-приложений;&lt;/li&gt;
&lt;li&gt;Работа в небольшой дружной команде до 15 человек;&lt;/li&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;strong&gt;PHP&lt;/strong&gt; более 3х лет;&lt;/li&gt;
&lt;li&gt;Опыт работы с &lt;strong&gt;MySQL&lt;/strong&gt; и &lt;strong&gt;MongoDB&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;Опыт в разработке высоконагруженных веб-приложений;&lt;/li&gt;
&lt;li&gt;Дружба с &lt;strong&gt;Linux&lt;/strong&gt; и &lt;strong&gt;Git&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;Хорошее знание клиентских технологий (HTML, CSS, Javascript);&lt;/li&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;strong&gt;Python&lt;/strong&gt; или серверном &lt;strong&gt;Javascript&lt;/strong&gt;
&lt;em&gt;(nodejs)&lt;/em&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="usloviia-dlia-oboikh-vakansii"&gt;Условия для обоих вакансий&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Зарплата в диапазоне &lt;strong&gt;\$2500-4000&lt;/strong&gt; в месяц по результатам
    собеседования;&lt;/li&gt;
&lt;li&gt;Полный рабочий день в &lt;strong&gt;Киевском офисе&lt;/strong&gt;, иногородним помощь с
    переездом;&lt;/li&gt;
&lt;li&gt;За успешную рекомендацию специалиста по данным вакансиям компания
    выплачивает&amp;nbsp;&lt;strong&gt;бонус в размере $1000&lt;/strong&gt; так что сообщите своим
    знакомым, кому-то это может быть интересно.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="zainteresovalo"&gt;Заинтересовало?&lt;/h2&gt;
&lt;div class="card orange darken-3"&gt;
&lt;p&gt;&lt;div class="card-content white-text center"&gt;
&lt;strong&gt;Вакансии более не актуальны&lt;/strong&gt;
&lt;/div&gt;&lt;/p&gt;
&lt;/div&gt;
&lt;p&gt;Не лишним будет, если кроме резюме Вы напишите - почему Вам нравится
серверная разработка на Python или PHP и почему Вам интересна данная
вакансия. Плюс упомяните, пожалуйста, что Вы узнали о данной вакансии
через &lt;strong&gt;Insight IT&lt;/strong&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Thu, 20 Sep 2012 20:16:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-09-20:vacancy/2012/vakansii-php-i-python-razrabotchiki-v-kieve/</guid><category>css</category><category>Git</category><category>html</category><category>JavaScript</category><category>Level UP</category><category>Linux</category><category>MongoDB</category><category>MySQL</category><category>node.js</category><category>PHP</category><category>Python</category><category>вакансии</category><category>Киев</category></item><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>Архитектура YouTube 2012</title><link>https://www.insight-it.ru//highload/2012/arkhitektura-youtube-2012/</link><description>&lt;blockquote&gt;
&lt;p&gt;Выбирайте самое простое решение с наиболее общими гарантиями, которые
практически полезны.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;- Дао YouTube&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&lt;strong&gt;YouTube&lt;/strong&gt; практически на протяжении всех 7 лет своего существования
является мировым лидером в сфере интернет-видео. С точки зрения
технической реализации проект оказался достаточно консервативным -
команда придерживается того же курса и стека технологий, с которых все
начиналось еще до приобретения проекта &lt;strong&gt;Google&lt;/strong&gt;. Но с 2008 года, когда
я написал первый обзор&amp;nbsp;&lt;a href="https://www.insight-it.ru/highload/2008/arkhitektura-youtube/"&gt;архитектуры YouTube&lt;/a&gt;, все же произошли интересные изменения, о которых я и хотел бы сегодня вкратце рассказать.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;4 млрд. просмотров страниц в день&lt;/li&gt;
&lt;li&gt;60 часов видео загружается каждую минуту&lt;/li&gt;
&lt;li&gt;350 миллионов устройств подключено к YouTube&lt;/li&gt;
&lt;li&gt;На февраль 2012 года в США по данным comScore:&lt;ul&gt;
&lt;li&gt;147,4 млн. уникальных зрителей&lt;/li&gt;
&lt;li&gt;16,7 млрд. просмотров видео (в октябре 2011 было больше 20 млрд.)&lt;/li&gt;
&lt;li&gt;Каждый зритель посмотрел в среднем 7 часов видео за месяц&lt;/li&gt;
&lt;li&gt;1.1 млрд. просмотров видео рекламы, суммарной длительностью в 10.8
млн. часов&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="tekhnologii"&gt;Технологии&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; - операционная система&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; - основной HTTP-сервер&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/lighttpd/"&gt;lighttpd&lt;/a&gt; - отдача видео из YouTube CDN&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/zookeeper/"&gt;Zookeeper&lt;/a&gt; - распределенные блокировки, хранение
конфигураций&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="/tag/python/"&gt;Python&lt;/a&gt;:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/wiseguy/"&gt;wiseguy&lt;/a&gt; - FastCGI-прослойка между Apache и Python&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/pycurl/"&gt;pycurl&lt;/a&gt; - лучшая доступная реализация HTTP-клиента,
но в итоге все равно заменили на самописное низкоуровневое решение,
выиграв 8% в потреблении вычислительных ресурсов.&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/spitfire/"&gt;spitfire&lt;/a&gt; - высокопроизводительный шаблонизатор на
основе абстрактного синтаксического дерева с регулируемым уровнем
оптимизации (как в gcc)&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/bson/"&gt;bson&lt;/a&gt; в качестве формата сериализации&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;a href="/tag/bigtable/"&gt;BigTable&lt;/a&gt; - хранение изображений&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt; - используется просто как хранилище данных, версия
5.1.52 с InnoDB&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/vitess/"&gt;Vitess&lt;/a&gt; - система для масштабирования MySQL-кластера&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="vitess"&gt;Vitess&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Основная цель проекта - предоставление всех необходимых инструментов и
серверов для горизонтального масштабирования баз данных на основе MySQL,
с учетом потребностей современных интернет-проектов.&lt;/li&gt;
&lt;li&gt;Реализован на &lt;a href="/tag/go/"&gt;Go&lt;/a&gt; - все еще экзотическом языке
программирования, также родившемся в стенах &lt;a href="/tag/google/"&gt;Google&lt;/a&gt;.
Сравним по производительности с &lt;a href="/tag/c/"&gt;C++&lt;/a&gt; и &lt;a href="/tag/java/"&gt;Java&lt;/a&gt;, но
несколько более "выразителен".&lt;/li&gt;
&lt;li&gt;Опубликован в opensource 24 февраля 2012 года, совсем недавно, так что
&lt;a href="/tag/youtube/"&gt;YouTube&lt;/a&gt; - по-прежнему единственный пример его
использования на практике в крупном проекте.&lt;/li&gt;
&lt;li&gt;Готовые клиентские библиотеки пока только для&amp;nbsp;&lt;strong&gt;Python&lt;/strong&gt;&amp;nbsp;и&amp;nbsp;&lt;strong&gt;Go&lt;/strong&gt;, что
не удивительно, но есть и универсальные интерфейсы на основе HTTP и
просто TCP-сокетов.&lt;/li&gt;
&lt;li&gt;Основной формат данных - &lt;strong&gt;bson&lt;/strong&gt;, как и в &lt;a href="/tag/mongodb/"&gt;MongoDB&lt;/a&gt;, но
по словам разработчиков &lt;em&gt;Vitess&lt;/em&gt;&amp;ensp;&lt;a href="https://www.insight-it.ru/goto/b807d615/" rel="nofollow" target="_blank" title="http://code.google.com/p/vitess/source/browse/#hg%2Fgo%2Fbson"&gt;их
реализация&lt;/a&gt;
выполняет (де)сериализацию в 10-15 раз быстрее.&lt;/li&gt;
&lt;li&gt;Ядром проекта выступает &lt;strong&gt;Vtocc&lt;/strong&gt;, &amp;nbsp;SQL-прокси с RPC интерфейсом,
позволяющий перераспределять запросы от большого количества (более 10
тыс.) одновременно подключенных клиентов в сравнительно небольшое
количество соединений с базами данных. Пропускная способность порядка 10
тыс. запросов в секунду.&lt;/li&gt;
&lt;li&gt;Встроенные возможности &lt;strong&gt;Vtocc&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;парсер и анализатор SQL-запросов для оптимизации их выполнения;&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;поддержка DML.&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;/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;
&lt;li&gt;Поддержка работы в нескольких датацентрах с концентрацией
мастер-серверов в одном датацентре и использования остальных в
режиме только для чтения.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="podvodim-itogi"&gt;Подводим итоги&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;YouTube&lt;/strong&gt; - еще один проект мирового масштаба, который с самого начала
использовал MySQL и оказался не в силах от него отказаться, не смотря на
трудности с горизонтальным масштабированием.&lt;/li&gt;
&lt;li&gt;По аналогичному пути пошли и другие проекты, схожие с &lt;strong&gt;Vitess&lt;/strong&gt;
надстройки над MySQL используются в &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;ul&gt;
&lt;li&gt;В &lt;a href="/tag/facebook/"&gt;Facebook&lt;/a&gt; она дополнена сильной интеграцией с
&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;&amp;nbsp;и сильно ограниченным интерфейсом, не
имеющим практически ничего общего с SQL.&amp;nbsp;Планы о публикации в
opensource, кажется, были, но я не слышал чтобы они воплотились в
жизнь. &lt;em&gt;// Уже почти дописав статью случайно заметил в коде, а потом
и мелким шрифтом в документации, что в Vitess тоже используется
memcached для кэширования из-за проблем со сборщиком мусора Go.&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/twitter/"&gt;Twitter&lt;/a&gt;&amp;nbsp;по-прежнему использует свою связку
&lt;a href="https://www.insight-it.ru/goto/4fe0530b/" rel="nofollow" target="_blank" title="https://github.com/twitter/flockdb"&gt;FlockDB&lt;/a&gt; +
&lt;a href="https://www.insight-it.ru/goto/c4275cdf/" rel="nofollow" target="_blank" title="https://github.com/twitter/gizzard"&gt;Gizzard&lt;/a&gt;&amp;nbsp;на
&lt;a href="/tag/scala/"&gt;Scala&lt;/a&gt;, которые уже пару лет публично доступны. В
отличии от Vitess она заточена на хранение информации о социальных
графах, по-этому сфера её применения как в Twitter, так и за его
пределами ограничена.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Vitess - пожалуй первая относительно успешная попытка построить
распределенную горизонтально масштабируемую СУБД на основе реляционной
базы данных, сохранив при этом SQL-интерфейс, пускай и с некоторыми
ограничениями.&lt;/li&gt;
&lt;li&gt;Выбирайте подходящее хранилище для каждого типа данных в системе - если
Vitess стал подходящим решением для структурированных данных вроде
информации о пользователях, метаданных видео и комментариев, это не
значит, что он хорошо (или плохо) справится, например, с медиа-файлами
вроде изображений и видео (для них в
&lt;a href="/tag/youtube/"&gt;YouTube&lt;/a&gt;&amp;nbsp;по-прежнему используют стек технологий
&lt;a href="/tag/google/"&gt;Google&lt;/a&gt;, подробности не публикуются).&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/python/"&gt;Python&lt;/a&gt; - вполне пригодный инструмент для реализации
бизнес-логики интернет-проектов, свет клином на &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; не
сошелся. Python предлагает широкий ассортимент инструментов для решения
любых типичных для интернет-проектов задач, хотя субъективно выбор
некоторых из них разработчиками YouTube мне кажется странным.&lt;/li&gt;
&lt;/ul&gt;
&lt;div class="card light-blue lighten-5"&gt;
&lt;div class="card-content"&gt;
        В комментариях предлагаю обсудить слабые и сильные стороны использования
        надстроек над реляционными базами данных, скажем по сравнению с
        использованием изначально-распределенных СУБД, таких как Riak, Cassandra
        и многих других. Может быть кто-то уже успел прикрутить к своему проекту
        Vitess или хотя бы FlockDB и готов поделиться впечатлениями?
    &lt;/div&gt;
&lt;/div&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/fb446b63/" rel="nofollow" target="_blank" title="https://www.youtube.com/watch?v=G-lGCC4KKok"&gt;Mike Solomon на PyCon'12&lt;/a&gt; (один из первых
    разработчиков проекта)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/29524853/" rel="nofollow" target="_blank" title="http://code.google.com/p/vitess"&gt;О проекте Vitess&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/652a935e/" rel="nofollow" target="_blank" title="http://www.comscore.com/Press_Events/Press_Releases/2012/3/comScore_Releases_February_2012_U.S._Online_Video_Rankings"&gt;Статистика comScore на февраль '12&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, 24 Mar 2012 16:50:00 +0400</pubDate><guid>tag:www.insight-it.ru,2012-03-24:highload/2012/arkhitektura-youtube-2012/</guid><category>bson</category><category>Go</category><category>Google</category><category>lighttpd</category><category>Linux</category><category>MySQL</category><category>pycurl</category><category>Python</category><category>spitfire</category><category>Vitess</category><category>wiseguy</category><category>YouTube</category><category>ZooKeeper</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>Архитектура Dropbox</title><link>https://www.insight-it.ru//highload/2011/arkhitektura-dropbox/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/4f16cf21/" rel="nofollow" target="_blank" title="http://db.tt/4TDAr1L"&gt;Dropbox&lt;/a&gt; - это самый простой способ...
&lt;img alt="Dropbox" class="right" src="https://www.insight-it.ru/images/dropbox_logo.png" title="Dropbox Logo"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Хранить файлы в безопасном месте&lt;/li&gt;
&lt;li&gt;Делиться файлами с другими людьми&lt;/li&gt;
&lt;li&gt;Постоянно иметь к ним доступ вне зависимости от своего месторасположения&lt;/li&gt;
&lt;/ul&gt;
&lt;!--more--&gt;
&lt;h2 id="vzryvnoi-rost"&gt;Взрывной рост&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;1 миллион файлов сохраняются в Dropbox каждые 15 минут (по
    презентации это больше, чем твитов в Twitter за тот же период
    времени, но это &lt;a href="https://www.insight-it.ru/highload/2011/arkhitektura-twitter-dva-goda-spustya/"&gt;несколько преувеличено&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;Одно из самых скачиваемых приложений, уступает лишь Skype&lt;/li&gt;
&lt;li&gt;Важная часть жизни многих пользователей: "не могу жить без этого"&lt;/li&gt;
&lt;li&gt;Рост обеспечен "сарафанным радио", практически без рекламы&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;img alt="Dropbox" class="responsive-img" src="https://www.insight-it.ru/images/dropbox.jpeg" title="Dropbox"/&gt;&lt;/p&gt;
&lt;h2 id="komanda-v-nachale-proekta"&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;a href="/tag/python/"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="rannie-dostizheniia"&gt;Ранние достижения&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Reverse engineering приложения Finder для Mac OSX 10.4/5 для
    отображения иконок статуса синхронизации ("в процессе", "все
    готово")&lt;/li&gt;
&lt;li&gt;Сложная инфраструктура HTTP нотификаций для избежания регулярного
    опроса серверов на каждом клиенте, основанная на
    &lt;a href="/tag/twisted/"&gt;Twisted&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Общая кодовая база, работающая на всех основных операционных
    системах: Windows, Mac OS, Linux (на основе PyObjC, wxPython,
    ctypes, py2exe, py2app, PyWin32)&lt;/li&gt;
&lt;li&gt;Горизонтально масштабируемое хранилище для информации о файлах на
    основе &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Собственная инфраструктура для аналитики в реальном времени&lt;/li&gt;
&lt;li&gt;Собственный механизм выделения памяти для Python, позволивший
    сократить её потребление на 90%&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="sfery-primeneniia-python"&gt;Сферы применения Python&lt;/h2&gt;
&lt;p&gt;По сути он используется во всех частях проекта:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;логика backend синхронизации;&lt;/li&gt;
&lt;li&gt;клиенты для основных ОС (Windows, Mac, Linux);&lt;/li&gt;
&lt;li&gt;контроллер основного сайта;&lt;/li&gt;
&lt;li&gt;обработка API запросов;&lt;/li&gt;
&lt;li&gt;аналитика.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Исключения из-за ограничений по доступной оперативной памяти:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Android (мог бы быть Jython)&lt;/li&gt;
&lt;li&gt;iPhone (мог бы быть Cpython)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="pochemu-imenno-python"&gt;Почему именно Python?&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Легок в изучении и понимании:&lt;/strong&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;strong&gt;Легок в написании:&lt;/strong&gt; важно для быстрой реализации функционала и
    выпуска новых версий.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Легок в изменении:&lt;/strong&gt;&lt;ul&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;li&gt;уменьшение прямых зависимостей модулей;&lt;/li&gt;
&lt;li&gt;динамические инструменты.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Позволяет обеспечивать качество&lt;/strong&gt; путем создания более-менее
    работающей версии продукта и доведения её до качественного уровня
    путем быстрых итераций.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="ne-bez-trudnostei"&gt;Не без трудностей&lt;/h2&gt;
&lt;blockquote&gt;
&lt;p&gt;Аргх!!! Python потребляет слишком много оперативной памяти и о-о-очень
медленный!&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;На серверной стороне можно вообще не заморачиваться и купить больше
оборудования - всегда помогает. Но для клиентской части такой подход не
прокатит, если только Вы не собираетесь купить новые компьютеры и
телефоны всем своим клиентам.&lt;/p&gt;
&lt;p&gt;Как с этим бороться?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Убедитесь, что все длинные внутренние циклы выполняются в C (может
    сэкономить до 44% процессорного времени)&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;ul&gt;
&lt;li&gt;нет готовых решений для профайлинга память (одновременно в
    Python и C);&lt;/li&gt;
&lt;li&gt;много потенциальных причин для повышенного потребления памяти:&lt;ul&gt;
&lt;li&gt;утечки в Python и C;&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;Большинство объектов расположены в heap памяти (большой
    последовательный кусок, выделенный приложению);&lt;/li&gt;
&lt;li&gt;Много маленьких объектов вперемешку с большими;&lt;/li&gt;
&lt;li&gt;Много временных объектов вперемешку с постоянными;&lt;/li&gt;
&lt;li&gt;В CPython нет сборщика мусора, позволяющего собрать объекты
    компактно в одной части heap'а.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Решением проблемы с фрагментацией стал собственный аллокатор
    памяти (механизм её выделения под определенные типы объектов):&lt;ul&gt;
&lt;li&gt;В Dropbox обнаружили, что большая часть heap-памяти
    захламляется контейнерами с метаданными файлов, которые
    синхронизируется;&lt;/li&gt;
&lt;li&gt;Было решено вынести их куда-нибудь еще;&lt;/li&gt;
&lt;li&gt;CPython позволяет управлять процессом выделения памяти для
    типов данных расширений;&lt;/li&gt;
&lt;li&gt;Делается это с помощью простых структур на C;&lt;/li&gt;
&lt;li&gt;"Not Rocket Science, just C code";&lt;/li&gt;
&lt;li&gt;Выделяются области памяти по 4Мб, состоящие из заголовка и
    буферов фиксированной длины.&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;в результате Dropbox редко использует более 100Мб памяти
    для больших синхронизаций (раньше эта цифра могла
    достигать 1.5Гб)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Но писать C расширение для каждой структуры данных, которую
    может понадобиться вынести в отдельный аллокатор - дело
    неблагодарное:&amp;nbsp;в результате эта история закончилась
    изменением &lt;code&gt;type_new()&lt;/code&gt; в &lt;code&gt;Objects/typeobject.c&lt;/code&gt; для того,
    чтобы можно было указывать &lt;code&gt;__use_region_allocator__&lt;/code&gt;
    = True** для тех классов, которым требуется такой механизм
    выделения памяти.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="podvodim-itogi"&gt;Подводим итоги&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Python стал ключом к технической реализации обоих сторон Dropbox:
    серверной и клиентской.&lt;/li&gt;
&lt;li&gt;Залогом успеха является максимальная простота с пользовательской
    точки зрения: "положил файл в папку и он становится доступен
    отовсюду"&lt;/li&gt;
&lt;li&gt;Dropbox не брали на себя реализацию стороннего функционала, вроде
    собственно создания хранилища файлов - используется &lt;a href="https://www.insight-it.ru/goto/d0869408/" rel="nofollow" target="_blank" title="http://aws.amazon.com/s3/"&gt;Amazon S3&lt;/a&gt;, что позволило им запуститься очень
    быстро и стремительно.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Лучше решать одну задачу, но качественно, чем много, но так себе!&lt;/em&gt;&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/afbbb2b7/" rel="nofollow" target="_blank" title="http://pycon.blip.tv/file/4878722/"&gt;Видео&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/f70a4522/" rel="nofollow" target="_blank" title="https://www.dropbox.com/s/mwxsyxtu9qieboo/pycon%20talk%20minus%20video.pptx"&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>Fri, 18 Mar 2011 18:57:00 +0300</pubDate><guid>tag:www.insight-it.ru,2011-03-18:highload/2011/arkhitektura-dropbox/</guid><category>ctypes</category><category>Dropbox</category><category>MySQL</category><category>py2app</category><category>py2exe</category><category>PyObjC</category><category>PyWin32</category><category>Twisted</category><category>wxPython</category><category>Архитектура Dropbox</category><category>Масштабируемость</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>Архитектура Mollom</title><link>https://www.insight-it.ru//highload/2011/arkhitektura-mollom/</link><description>&lt;p&gt;&lt;img alt="Mollom" class="right" src="https://www.insight-it.ru/images/mollom-logo.jpg" title="Mollom"/&gt;
&lt;a href="https://www.insight-it.ru/goto/aa3c2fd2/" rel="nofollow" target="_blank" title="http://mollom.com/"&gt;Mollom&lt;/a&gt; - это прибыльный SaaS сервис по фильтрации различных форм спама из
контента, сгенерированного пользователями: комментариев, постов на
форумах и блогах, опросов, контактных и регистрационных форм.
Определение спама основано не только на контенте, но и репутации и
прошлой активности разместившего его пользователя. Алгоритм машинного
обучения Mollom выполняет роль цифрового модератора 24х7 для более 40
тысяч сайтов, в том числе и очень крупных компаний.&lt;/p&gt;
&lt;p&gt;С того момента, как Mollom запустили систему анализа цифрового контента,
они выявили более 373 миллионов спам сообщений, обнаружив в процессе что
впечатляющие 90% всех прошедших через них сообщений оказались спамом.
Весь этот поток спама в 100 сообщений в секунду обрабатывается всего
двумя географически распределенными серверами. На каждом из них работает
сервер Java-приложений и Cassandra. Так мало ресурсов требуется лишь
из-за того, что они создали очень эффективную систему машинного
обучения. Разве не круто? Так как же они это делают?&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Обслуживаются 40000 активных веб-сайтов, многие их которых
    принадлежат крупным клиентам, таким как Adobe, Sony BMG, Warner
    Brothers, Fox News и The Economist. Много крупных брендов, с
    крупными сайтами, масса комментариев.&lt;/li&gt;
&lt;li&gt;Обнаруживают пол-миллиона спам-сообщений ежедневно.&lt;/li&gt;
&lt;li&gt;Обрабатывается около 100 запросов к API в секунду.&lt;/li&gt;
&lt;li&gt;Проверка сообщения на спам занимает очень мало времени, обычно около
    30-50 миллисекунд, 95% запросов укладывается в 250 миллисекунд,
    когда самые медленные обрабатываются пол секунды.&lt;/li&gt;
&lt;li&gt;Эффективность определения спама составляет 99.95%. Это означает, что
    из 10000 спам-сообщений Mollom пропустит только 5.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/82e0a09b/" rel="nofollow" target="_blank" title="http://mollom.com/blog/netlog-using-mollom"&gt;Netlog&lt;/a&gt;, европейская
    социальная сеть, имеет отдельный Mollom-сервер в своем датацентре.
    Netlog проверяют на спам около 4 миллионов сообщений каждый день на
    классификаторах, специально натренированных на их данных.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="platforma"&gt;Платформа&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/java/"&gt;Java&lt;/a&gt; - исторически сложилось, что Mollom был с самого
    начала был разработан на Java.&lt;/li&gt;
&lt;li&gt;Два сервера обслуживают основную часть клиентов:&lt;ul&gt;
&lt;li&gt;Один сервер на восточном побережье США, другой - на западном&lt;/li&gt;
&lt;li&gt;В случае сбоя один сервер может полностью подменить другой&lt;/li&gt;
&lt;li&gt;Конфигурация обоих: Intel Xeon Quad core, 2.8GHz, 16GB RAM, 4
    диска по 300 GB, RAID 10.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/ad66f2bf/" rel="nofollow" target="_blank" title="http://www.softlayer.com/"&gt;SoftLayer&lt;/a&gt; - хостинг-провайдер.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/baf11ec8/" rel="nofollow" target="_blank" title="http://cassandra.apache.org/"&gt;Cassandra&lt;/a&gt; - NoSQL база данных,
    выбранная из-за высокой производительности на запись и способности
    работать на серверах, располагающихся в разных датацентрах (была
    разработана в&amp;nbsp;&lt;a href="https://www.insight-it.ru/highload/2010/arkhitektura-facebook/"&gt;Facebook&lt;/a&gt;,
    но там практически не используется).&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/dce103e6/" rel="nofollow" target="_blank" title="http://www.mysql.com/"&gt;MySQL&lt;/a&gt; - Java Persistence API используется
    для обычных наборов данных, когда Cassandra используется для больших
    объемов данных.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/2b056aff/" rel="nofollow" target="_blank" title="http://en.wikipedia.org/wiki/GlassFish"&gt;Glassfish&lt;/a&gt; - open source
    сервер приложений для платформы Java EE. Они выбрали именно
    Glassfish за его возможности корпоративного уровня, такие как
    репликация и обработка сбоев.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/cc84f430/" rel="nofollow" target="_blank" title="http://hudson-ci.org/"&gt;Hudson&lt;/a&gt; - предоставляет непрерывное
    тестирование и развертывание кода серверной части на всех
    используемых машинах.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/f94e85c8/" rel="nofollow" target="_blank" title="http://munin-monitoring.org/"&gt;Munin&lt;/a&gt; - измерение и построение
    графиков, касающихся здоровья серверов.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/cfd5a6c7/" rel="nofollow" target="_blank" title="http://www.pingdom.com/"&gt;Pingdom&lt;/a&gt; - внешний мониторинг.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/acf8f59d/" rel="nofollow" target="_blank" title="http://www.zendesk.com/"&gt;Zendesk&lt;/a&gt; - используется для оказания
    поддержки клиентам.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/17f204ac/" rel="nofollow" target="_blank" title="http://drupal.org/"&gt;Drupal&lt;/a&gt; - используется для основного сайта со
    специализированным модулем интернет-магазина.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/a81d9bb9/" rel="nofollow" target="_blank" title="http://unfuddle.com/"&gt;Unfuddle&lt;/a&gt; - хостинг Subversion для
    взаимодействия удаленной команды разработчиков.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kak-eto-rabotaet"&gt;Как это работает?&lt;/h2&gt;
&lt;p&gt;Процесс выглядит следующим образом:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Когда пользователь отправляет комментарий на сайт, происходит запрос
    к API Mollom.&lt;/li&gt;
&lt;li&gt;Контент анализируется, если он оказывается спамом, то сайту
    сообщается, что необходимо его заблокировать, если же алгоритм не
    уверен на 100% - сайту советуют показать CAPTCHA, которую сервис
    также предоставляет.&lt;/li&gt;
&lt;li&gt;После того, как CAPTCHA будет успешно заполнена, контент
    принимается. В большинстве случаев пользователи не будут ее видеть и
    контент будет приниматься сразу же.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Обнаружение спама является сложным балансом между отказом нормальному
контенту и принятию спама.&lt;/p&gt;
&lt;h2 id="biznes-model"&gt;Бизнес-модель&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Основным залогом популярности Mollom является бесплатная возможность
    попробовать сервис, ограничение составляет 100 нормальных (не спам)
    сообщений в день. Небольшие сайты могут никогда и не достичь этого
    ограничения.&lt;/li&gt;
&lt;li&gt;Далее есть два тарифа: 1 евро в день и 3600 евро с возможностями
    вполне соответствующими этим суммам&lt;/li&gt;
&lt;li&gt;Сайты, использующие бесплатный тариф, вовсе не зря тратят ресурсы
    системы, как кажется на первый взгляд, а являются жизненно-важным
    источником данных для тренировки системы. Без этих данных алгоритмы
    были бы существенно менее точны.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="arkhitektura"&gt;Архитектура&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Разработчики Mollom уделяют максимум внимания времени отклика,
    эффективности кода и использования серверных ресурсов.&lt;/li&gt;
&lt;li&gt;Физически каждый сервер может справиться со всеми запросами, два
    сервера нужны для избежания перерывов в работе системы. Когда оба
    сервера в строю - работа распределяется между ними, когда один
    падает - второй перехватывает его запросы.&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mollom прошел через несколько этапов развития:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Изначально маленькая команда из двух человек работала вечерами
    над основными алгоритмами, классификаторами и реальными
    бизнес-задачами, которые они пытались решить. Для построения
    инфраструктуры серверной части они использовали свои реализации
    базовых механизмов по управлению ресурсами, соединениями и
    потоками. В итоге они обнаружили, что тратят слишком много
    времени на эти вещи. После этого они переключились на Glassfish,
    что позволило им намного меньше беспокоится об управлении
    памятью, REST-запросах, парсинге XML и поддержании пула
    соединений с базой данных.&lt;/li&gt;
&lt;li&gt;В прошлом основной проблемой была пропускная способность
    дисковой подсистемы. Они должны хранить информацию о репутации
    всех IP-адресов и URL по всему Интернету, что привело к
    массивному набору данных с большим количеством случайных
    обращений.&lt;/li&gt;
&lt;li&gt;Поначалу они использовали MySQL на недорогой виртуальной машине,
    что в итоге не смогло масштабироваться.&lt;/li&gt;
&lt;li&gt;Они перенесли данные на твердотельные жесткие диски (SSD) и
    стали все хранить в файлах. Этот шаг решил проблемы с записью,
    но возникли новые проблемы:&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;/li&gt;
&lt;li&gt;В итоге они отказались от твердотельных накопителей и стали
    использовать Cassandra.&lt;/li&gt;
&lt;/ol&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Cassandra сейчас используется для обработки интенсивного потока
    запросов на запись и в роли кэша:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Работает на RAID10, что хорошо подходит для высоких смешанных
    нагрузок на запись/чтение.&lt;/li&gt;
&lt;li&gt;Cassandra оптимизирована для записи, а в Mollom запись как раз
    происходит намного чаще, чем чтение.&lt;/li&gt;
&lt;li&gt;Разработана для распределенной работы как внутри датацентра, так
    и между датацентрами.&lt;/li&gt;
&lt;li&gt;Обратной стороной медали является отсутствие стандартного NoSQL
    интерфейса, что усложняет реализацию приложений.&lt;/li&gt;
&lt;li&gt;Механизм кэширования строк в Cassandra позволяет им не
    использовать отдельную систему для кэширования, что существенно
    упростило код приложения.&lt;/li&gt;
&lt;li&gt;Cassandra имеет функцию удаления устаревшей информации после
    определенного периода времени. В Европе существуют строгие
    законы о приватности личных данных, согласно которым они должны
    храниться не более определенного срока (штаб-квартира Mollom
    находится в Бельгии). В этом плане эта функция очень удобна.
    Эта функция опять же избавляет от необходимости реализовывать
    данный функционал вручную.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Типичный путь одного комментария внутри системы:&lt;ul&gt;
&lt;li&gt;Балансировка нагрузки между серверами лежит на клиентской
    библиотеке, в роли типичного клиента может выступать сайт на
    Drupal, осуществляющий запрос к API через XML-RPC или REST.&lt;/li&gt;
&lt;li&gt;Запросы обрабатываются сервером приложений Glassfish и проходят
    стандартный процесс обработки с помощью сервлетов и специфичных
    классов.&lt;/li&gt;
&lt;li&gt;Платящие клиенты обслуживаются в первую очередь, что приводит к
    тому, что клиенты на бесплатном тарифе могут ожидать результата
    несколько дольше.&lt;/li&gt;
&lt;li&gt;Запрос анализируется и оценка вероятности спама возвращается
    пользователю. Помимо этого отдельная часть кода Mollom отвечает
    за генерацию, выдачу и проверку CAPTCHA.&lt;/li&gt;
&lt;li&gt;Классификаторы полностью располагаются в оперативной памяти.
    Небольшой кусок контента разбивается на тысячи и тысячи
    крошечных частей, которые могут быть идентифицированы как спам.
    Такие классификаторы хранят в памяти до нескольких миллионов
    признаков, характерных для спама. Анализ должен выполняться
    очень быстро, так что никаких других вариантов кроме
    расположения всех требуемых данных в оперативной памяти просто
    не было.&lt;/li&gt;
&lt;li&gt;В Cassandra хранятся очки репутации, частоты, URL и IP-адреса.&lt;/li&gt;
&lt;li&gt;Струтуры данных в памяти не реплицируются напрямую. Они
    записываются в Cassandra, которая и передает их на второй
    сервер. Промежуток времени, когда данные не консистентны, очень
    невелик, так что это не сказывается негативно на алгоритмах.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Балансировка нагрузки с помощью клиента:&lt;ul&gt;
&lt;li&gt;Mollom использует такой подход к балансировке, так как стартап
    не может себе позволить дорогой железный балансировщик нагрузки.
    Если учесть, что им нужна балансировка между датацентрами,
    решение от любого из вендоров было бы комплексным и дорогим.&lt;/li&gt;
&lt;li&gt;У каждого клиента есть индивидуальный список серверов, которыми
    он может воспользоваться. Этот список изменяется через API.&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;Mollom - это набор самообучающихся систем. Отдельные
    CAPTCHA-решения, не учитывают ни пользовательское поведение, ни
    источник контента, заставляя каждого пользователя вводить
    проверочный код при каждом сообщении. В случае с Mollom это
    происходит только когда система анализа контента не уверена в
    конкретном решении.&lt;/li&gt;
&lt;li&gt;Средняя длина сообщения - 500 символов, обычно оно разбивается
    на 3000 характеристик. Принадлежность контента к спаму
    определяется путем оценки репутации IP адреса или Open ID,
    пользовательского идентификатора, эмоциональной окраски, языка,
    профанации, проверки на наличие специфичных слов и фраз, также
    учитывается качество написания текста и многие другие факторы.
    Все эти данные основываются на классификаторах. Некоторые из них
    статистические по природе, так что обучение происходит
    автоматически. Другие же основываются на правилах для того,
    чтобы быть уверенными, что они никогда не могут быть настроены
    неверно. Комбинация результатов всех тестов после нормализации и
    образует финальный рейтинг принадлежности к спаму каждого
    конкретного сообщения.&lt;/li&gt;
&lt;li&gt;Классификаторы и внутренние метрики обучаются с каждым новым
    сообщением и обновляются в реальном времени.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Glassfish берет на себя планировку нагрузки, учитывая многоядерность
    системы:&lt;ul&gt;
&lt;li&gt;Ключ к дизайну системы в многопроцессорном окружении заключается
    в максимальном параллелизации работы при минимальном простое
    из-за блокировок.&lt;/li&gt;
&lt;li&gt;Они используют 16 thread'ов на сервер.&lt;/li&gt;
&lt;li&gt;Большинство запросов обрабатываются сессионными объектами (Java
    Bean), не имеющими состояний. Они хорошо подходят для управления
    параллельными запросами.&lt;/li&gt;
&lt;li&gt;Они держат пул из нескольких сессионных объектов, но определение
    их количества делегируется Glassfish. В пиковую нагрузку это
    число увеличивается для более эффективной обработки запросов,
    порой оно достигает 32.&lt;/li&gt;
&lt;li&gt;Все классификаторы реализованы как раз как такие объекты,
    повторно использующиеся различными thread'ами.&lt;/li&gt;
&lt;li&gt;У каждого объекта есть свое клиентское соединение с Cassandra,
    чтобы гарантировать отсутствие блокировок.&lt;/li&gt;
&lt;li&gt;Когда пользователь не отвечает на CAPTCHA сессия очищается и
    Mollom узнает что это скорее всего был спам.&lt;/li&gt;
&lt;li&gt;На каждом сервере запущено по одной копии каждого
    классификатора.&lt;/li&gt;
&lt;li&gt;В момент очистки сессии происходит небольшая блокировка, когда
    происходит обновление классификаторов.&lt;/li&gt;
&lt;li&gt;Обновленные классификаторы записываются в Cassandra каждые пол
    часа.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Интеграция приложений:&lt;ul&gt;
&lt;li&gt;Mollom использует открытый API, который может быть интегрирован
    в любую систему.&lt;/li&gt;
&lt;li&gt;Библиотеки: Java, PHP, Ruby и другие.&lt;/li&gt;
&lt;li&gt;Готовые модули: Drupal, Joomla, Wordpress и прочие системы
    управления контентом.&lt;/li&gt;
&lt;li&gt;Решения от сторонних разработчиков, основанные на примерах кода
    от &amp;nbsp;Mollom.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Для мониторинга здоровья серверов они используют Munin:&lt;ul&gt;
&lt;li&gt;Каков размер heap памяти после сбора мусора?&lt;/li&gt;
&lt;li&gt;Каково количество доступных соединений?&lt;/li&gt;
&lt;li&gt;Каково количество thread'ов в пуле?&lt;/li&gt;
&lt;li&gt;Оценка времени блокировок в каждом thread'е.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Если взглянуть в целом на архитектуру Mollom, можно увидеть, что они
    стараются построить систему, способную прозрачно работать в
    нескольких датацентрах, чтобы позволить горизонтально расширить
    систему, когда они перерастут текущую двухсерверную конфигурацию:&lt;ul&gt;
&lt;li&gt;Балансировка нагрузки на клиенте позволяет выбирать оптимальный
    сервер и справляться со сбоями одного из них.&lt;/li&gt;
&lt;li&gt;Кластеризация Glassfish облегчает добавление/удаление новых
    машин и позволяет перехватывать запросы, когда один из серверов
    выходит из строя.&lt;/li&gt;
&lt;li&gt;Cassandra используется для управления данными между серверами в
    нескольких датацентрах.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Инсталляция Mollom в Netlog обладает некоторыми интересными
    характеристиками. Она обрабатывает больше сообщений, чем основные
    сервера Mollom, но распределение спама в ней совершенно другое, так
    как люди в ней общаются в рамках социальной сети. Внутри Netlog лишь
    10% сообщений является спамом, когда в суровом мире информационных
    порталов распределение обратно. Интересным следствием является тот
    факт, что обработка нормальных сообщений требует меньше
    вычислительных ресурсов, так что на аналогичном оборудовании удается
    обрабатывать больший поток сообщений.&lt;/li&gt;
&lt;li&gt;Изначально они думали о виртуализированных серверах, в частности об
    Amazon EC2, но в итоге обнаружилось, что наиболее узким местом
    являются операции ввода-вывода - низкая производительность дисковой
    подсистемы в виртуальных машинах создавали реальные проблемы, так
    что они решили воспользоваться вертикальным масштабированием и
    переехали на более дорогие физические машины с большим объемом
    дискового пространства:&lt;ul&gt;
&lt;li&gt;На удивление они не упираются в вычислительные ресурсы: лишь два
    ядра из 8 занимаются вычислениями, когда остальные же работают
    над операциями ввода-вывода.&lt;/li&gt;
&lt;li&gt;Трафик Mollom практически постоянен, так что физические сервера
    более эффективны с финансовой точки зрения. Они рассматривают
    Amazon лишь как запасной вариант для обработки непредвиденных
    пиков нагрузки.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Процесс разработки:&lt;ul&gt;
&lt;li&gt;Команда распределена: трое в Бельгии, остальные в Техасе,
    Бостоне и Германии.&lt;/li&gt;
&lt;li&gt;Scrum используется в процессе разработки и они довольны этой
    методологией. Scrum-собрание проходит через Skype в два часа дня
    по Бельгии.&lt;/li&gt;
&lt;li&gt;Разработчики работают локально и отправляют код на Unfuddle.&lt;/li&gt;
&lt;li&gt;Hudson используется для непрерывного интеграционного
    тестирования.&amp;nbsp;Hudson позволил облегчить миграцию, так как перед
    развертыванием все тесты должны быть пройдены. Они не теряли
    лишнего времени на проблемах, обнаруженных уже в развернутом
    приложении.&lt;/li&gt;
&lt;li&gt;Они активно используют автоматическое тестирование: юнит-тесты,
    системные тесты, тесты Drupal.&lt;/li&gt;
&lt;li&gt;Развертывание по-прежнему делается вручную для минимизации риска
    простоя (что правда спорный момент).&lt;/li&gt;
&lt;li&gt;Для обнаружения утечек памяти они используют анализ дампов
    оперативной памяти. Анализ дампа сервера с 16Гб памяти - дело
    непростое, практически невозможное на обычном компьютере, так
    что они арендуют большую виртуальную машину на Amazon для
    проведения анализа. Весь процесс занимает всего около 2 часов.
    Они сравнивают два дампа: через 10 и 20 часов после запуска
    сервера. Если обнаруживаются значительные отличия, то скорее
    всего дело в утечке памяти.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="puti-razvitiia"&gt;Пути развития&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Mollom API основано на XML-RPC, REST-интерфейс находится на стадии
    тестирования для облегчения интеграции других сервисов.&lt;/li&gt;
&lt;li&gt;Они мигрировали на Cassandra, чтобы облегчить процесс
    горизонтального масштабирования, когда нагрузка достигнет
    соответствующего уровня.&lt;/li&gt;
&lt;li&gt;Скоро будут выпущены корпоративные возможности, которые позволят
    работать с сотнями сайтов как с единым целым. Появится возможность
    легко модерировать несколько сайтов одновременно по эмоциональной
    окраске сообщений, рейтингу спама или удалить все сообщения с
    определенного IP-адреса.&lt;/li&gt;
&lt;li&gt;Они думали над участием в бизнесе потоковых данных вроде Twitter, но
    они сильно ограничены европейскими более строгими требованиями по
    приватности.&lt;/li&gt;
&lt;li&gt;Планируются эксперименты по использованию Glassfish для балансировки
    нагрузки в рамках каждого датацентра.&lt;/li&gt;
&lt;li&gt;Если нагрузка увеличится десятикратно им придется добавить больше
    серверов в Cassandra. Дисковый ввод-вывод является узким местом.
    Дополнительные сервера приложения понадобятся только если нагрузка
    вырастет более, чем на порядок.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="podvodim-itogi"&gt;Подводим итоги&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Mollom очень серьезно относится к
    разработке&amp;nbsp;высокопроизводительной системы.&lt;/strong&gt; Они гордятся тем, что
    Mollom очень эффективно использует вычислительные и финансовые
    ресурсы. Множество запросов может обрабатываться одним сервером с
    низкой задержкой, что очень радует как клиентов, так и владельцев
    проекта, так как издержки очень низки. Этот вопрос был выбран
    приоритетным с самого начала и они выбрали подходящие технологии для
    реализации своих целей. Это позволило им вкладывать средства в
    маркетинг, построить базу клиентов и создавать новые продукты на
    основе Mollom.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Машинное обучение требует много исходных данных&amp;nbsp;для успешного
    обнаружение спама.&lt;/strong&gt; Для сбора этих данных предлагает бесплатные
    услуги. Крупные клиенты обеспечивают доход и получают выгоду от
    данных, полученных от более мелких клиентов. Эта модель очень хорошо
    себя проявила в машинном обучении, за которым как известно будущее.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Старайтесь избавиться от проблем, не связанных напрямую с
    продуктом.&lt;/strong&gt; Большие системы требуют серьезных усилий на разработку
    инфраструктуры. Можно убить все время на построение&amp;nbsp;инфраструктуры,
    вместо создания по-настоящему ценного продукта (классификаторов,
    системы репутации, клиентских библиотек). Mollom постоянно пытались
    максимально избавляться от лишних проблем, именно по-этому они
    выбрали Cassandra и Glassfish.&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;strong&gt;Уменьшайте объем кода, позволяя используемым сторонним продуктам
    брать на себя грязную работу&lt;/strong&gt;.&amp;nbsp;Поначалу код Mollom был существенно
    большим по объему, чем сейчас. Использование Cassandra и Glassfish
    позволило убрать массу кода, связанного с кэшированием,
    кластеризацией, репликацией и обработкой сбоев. Упрощайте систему со
    временем.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Минимизируйте блокировки.&lt;/strong&gt; Mollom потратили много времени на
    устранение блокировок внутри Glassfish, так как это начинало
    становиться узким местом. Минимизируйте простой от блокировок для
    достижения полного параллелизма.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="istochniki-informatsii-i-dopolnitelnye-materialy"&gt;Источники информации и дополнительные материалы&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/796d6b53/" rel="nofollow" target="_blank" title="http://highscalability.com/blog/2011/2/8/mollom-architecture-killing-over-373-million-spams-at-100-re.html"&gt;Mollom Architecture - Killing Over 373 Million Spams At 100 Request
    Per
    Second&lt;/a&gt;
    (основной источник информации)&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/a695ef0e/" rel="nofollow" target="_blank" title="http://mollom.com/files/mollom-technical-whitepaper.pdf"&gt;Mollom Technical
    Whitepaper&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/23d06e29/" rel="nofollow" target="_blank" title="http://blogs.sun.com/glassfishpodcast/entry/episode_072_mollom_com_s"&gt;Episode #072 - Mollom.com's GlassFish backend with Dries and
    Johan&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/c1eeadac/" rel="nofollow" target="_blank" title="http://buytaert.net/mollom-gets-a-new-backend"&gt;Mollom gets a new
    backend&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/fd87538b/" rel="nofollow" target="_blank" title="http://blogs.lodgon.com/johan/"&gt;Fighting spam with Mollom on
    Glassfish&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/9c3dc3c9/" rel="nofollow" target="_blank" title="http://mollom.com/api"&gt;Mollom API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Если Вам понравилась данная статья, можете ознакомиться с другими
&lt;a href="https://www.insight-it.ru/highload/"&gt;материалами по архитектуре высоконагруженных систем&lt;/a&gt; и &lt;a href="/feed/"&gt;подписаться на RSS&lt;/a&gt;.&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Tue, 15 Feb 2011 19:19:00 +0300</pubDate><guid>tag:www.insight-it.ru,2011-02-15:highload/2011/arkhitektura-mollom/</guid><category>Cassandra</category><category>Drupal</category><category>Glassfish</category><category>Hudson</category><category>Intel</category><category>Java</category><category>Mollom</category><category>Munin</category><category>MySQL</category><category>Pingdom</category><category>saas</category><category>SoftLayer</category><category>Unfuddle</category><category>Xeon</category><category>Zendesk</category><category>Архитектура Mollom</category></item><item><title>Архитектура Вконтакте</title><link>https://www.insight-it.ru//highload/2010/arkhitektura-vkontakte/</link><description>&lt;p&gt;&lt;img alt="Логотип Вконтакте" class="left" src="https://www.insight-it.ru/images/vkontakte-logo.png" title="Логотип Вконтакте"/&gt;
Самая популярная социальная сеть в рунете пролила немного света на то,
как же она работает. Представители проекта в лице Павла Дурова и Олега
Илларионова на конференции &lt;a href="https://www.insight-it.ru/event/2010/highload-2010/"&gt;HighLoad++&lt;/a&gt; ответили на шквал вопросов по совершенно разным аспектам работы
&lt;a href="https://www.insight-it.ru/goto/1a5d3494/" rel="nofollow" target="_blank" title="https://vk.com"&gt;Вконтакте&lt;/a&gt;, в том числе и техническим. Спешу
поделиться своим взглядом на архитектуру проекта по результатам данного
выступления.&lt;!--more--&gt;&lt;/p&gt;
&lt;h2 id="platforma"&gt;Платформа&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/debian/"&gt;Debian&lt;/a&gt;&amp;ensp;&lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; - основная операционная
    система&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/nginx/"&gt;nginx&lt;/a&gt; - балансировка нагрузки&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; + &lt;a href="/tag/xcache/"&gt;XCache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; + &lt;a href="/tag/mod_php/"&gt;mod_php&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/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Собственная СУБД на &lt;a href="/tag/c/"&gt;C&lt;/a&gt;, созданная "лучшими умами" России&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/node-js/"&gt;node.js&lt;/a&gt; - прослойка для реализации XMPP, живет за
    &lt;a href="/tag/haproxy/"&gt;HAProxy&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Изображения отдаются просто с файловой системы &lt;a href="/tag/xfs/"&gt;xfs&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/ffmpeg/"&gt;ffmpeg&lt;/a&gt; - конвертирование видео&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;95 миллионов учетных записей&lt;/li&gt;
&lt;li&gt;40 миллионов активных пользователей во всем мире (сопоставимо с
    аудиторией интернета в России)&lt;/li&gt;
&lt;li&gt;11 миллиардов запросов в день&lt;/li&gt;
&lt;li&gt;200 миллионов личных сообщений в день&lt;/li&gt;
&lt;li&gt;Видеопоток достигает 160Гбит/с&lt;/li&gt;
&lt;li&gt;Более 10 тысяч серверов, из которых только 32 - фронтенды на
    &lt;a href="/tag/nginx/"&gt;nginx&lt;/a&gt; (количество серверов с
    &lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; неизвестно)&lt;/li&gt;
&lt;li&gt;30-40 разработчиков, 2 дизайнера, 5 системных администраторов, много
    людей в датацентрах&lt;/li&gt;
&lt;li&gt;Каждый день выходит из строя около 10 жестких дисков&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="arkhitektura"&gt;Архитектура&lt;/h2&gt;
&lt;h3 id="obshchie-printsipy"&gt;Общие принципы&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Cервера многофункциональны и используются одновременно в нескольких
    ролях:&lt;ul&gt;
&lt;li&gt;Перебрасывание полуавтоматическое&lt;/li&gt;
&lt;li&gt;Требуется перезапускать daemon'ы&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Генерация страниц с новостями (микроблоги) происходит очень похожим
    образом с &lt;a href="/tag/facebook/"&gt;Facebook&lt;/a&gt; (см. &lt;a href="https://www.insight-it.ru/highload/2010/arkhitektura-facebook/"&gt;Архитектура&amp;nbsp;Facebook&lt;/a&gt;), основное
    отличие - использование собственной СУБД вместо MySQL&lt;/li&gt;
&lt;li&gt;При балансировке нагрузки используются:&lt;ul&gt;
&lt;li&gt;Взвешенный round robin внутри системы&lt;/li&gt;
&lt;li&gt;Разные сервера для разных типов запросов&lt;/li&gt;
&lt;li&gt;Балансировка на уровне ДНС на 32 IP-адреса&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Мощные сервера:&lt;ul&gt;
&lt;li&gt;8-ядерные процессоры Intel (по два на сервер, видимо)&lt;/li&gt;
&lt;li&gt;64Гб оперативной памяти&lt;/li&gt;
&lt;li&gt;8 жестких дисков (соответственно скорее всего корпуса 2-3U)&lt;/li&gt;
&lt;li&gt;RAID не используется&lt;/li&gt;
&lt;li&gt;Не брендированные&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Вычислительные мощности серверов используются менее, чем на 20%&lt;/li&gt;
&lt;li&gt;Сейчас проект расположен в 4 датацентрах в Санкт-Петербурге и
    Москве, причем:&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;li&gt;&lt;a href="/tag/cdn/"&gt;CDN&lt;/a&gt; на данный момент не используется, но в планах есть&lt;/li&gt;
&lt;li&gt;Резервное копирование данных происходит ежедневно и инкрементально&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="volshebnaia-baza-dannykh-na-c"&gt;Волшебная база данных на &lt;a href="/tag/c/"&gt;C&lt;/a&gt;&lt;/h3&gt;
&lt;p&gt;Этому продукту, пожалуй, уделялось максимум внимания аудитории, но при
этом почти никаких подробностей о том, что он собственно говоря собой
представляет, так и не было обнародовано. Известно, что:&lt;/p&gt;
&lt;ul&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;Используется в огромном количестве сервисов:&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Нереляционная модель данных&lt;/li&gt;
&lt;li&gt;Большинство операций осуществляется в оперативной памяти&lt;/li&gt;
&lt;li&gt;Интерфейс доступа представляет собой расширенный протокол
    &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;, специальным образом составленные ключи
    возвращают результаты сложных запросов (чаще всего специфичных для
    конкретного сервиса)&lt;/li&gt;
&lt;li&gt;Хотели бы сделать из данной системы универсальную СУБД и
    опубликовать под GPL, но пока не получается из-за высокой степени
    интеграции с остальными сервисами&lt;/li&gt;
&lt;li&gt;Кластеризация осуществляется легко&lt;/li&gt;
&lt;li&gt;Есть репликация&lt;/li&gt;
&lt;li&gt;Если честно, я так и не понял зачем им &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt; с такой
    штукой - возможно просто как legacy живет со старых времен&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="audio-i-video"&gt;Аудио и видео&lt;/h3&gt;
&lt;p&gt;Эти подпроекты являются побочными для социальной сети, на них особо не
фокусируются. В основном это связанно с тем, что они редко коррелируют с
основной целью использования социальной сети - &lt;em&gt;общением&lt;/em&gt;, а также
создают большое количество проблем: видео траффик - основная статья
расходов проекта, плюс всем известные проблемы с нелегальным контентом и
претензиями правообладателей. Медиа-файлы банятся по хэшу при удалении
по просьбе правообладателей, но это неэффективно и планируется
усовершенствовать этот механизм.&lt;/p&gt;
&lt;p&gt;1000-1500 серверов используется для перекодирования видео, на них же оно
и хранится.&lt;/p&gt;
&lt;h3 id="xmpp"&gt;XMPP&lt;/h3&gt;
&lt;p&gt;Как известно, некоторое время назад появилась возможность общаться на
Вконтакте через протокол Jabber (он же XMPP). Протокол совершенно
открытый и существует масса opensource реализаций.&lt;/p&gt;
&lt;p&gt;По ряду причин, среди которых проблемы с интеграцией с остальными
сервисами, было решено за месяц создать собственный сервер,
представляющий собой прослойку между внутренними сервисами Вконтакте и
реализацией XMPP протокола. Основные особенности этого сервиса:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Реализован на &lt;a href="/tag/node-js/"&gt;node.js&lt;/a&gt; (выбор обусловлен тем, что
    JavaScript знают практически все разработчики проекта, а также
    хороший набор инструментов для реализации задачи)&lt;/li&gt;
&lt;li&gt;Работа с большими контакт-листами - у многих пользователей
    количество друзей на Вконтакте измеряется сотнями и тысячами&lt;/li&gt;
&lt;li&gt;Высокая активность смены статусов - люди появляются и исчезают из
    онлайна чаще, чем в других аналогичных ситуациях&lt;/li&gt;
&lt;li&gt;Аватарки передаются в &lt;code&gt;base64&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Тесная интеграция с внутренней системой обмена личными сообщениями
    Вконтакте&lt;/li&gt;
&lt;li&gt;60-80 тысяч человек онлайн, в пике - 150 тысяч&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/mysql/"&gt;MySQL&lt;/a&gt; (думали о MongoDB, но
    передумали)&lt;/li&gt;
&lt;li&gt;Сервис работает на 5 серверах разной конфигурации, на каждом из них
    работает код на&lt;a href="/tag/node-js/"&gt;node.js&lt;/a&gt; (по 4 процесса на сервер), а
    на трех самых мощных - еще и &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;В &lt;a href="/tag/node-js/"&gt;node.js&lt;/a&gt; большие проблемы с использованием
    &lt;a href="/tag/openssl/"&gt;OpenSSL&lt;/a&gt;, а также течет память&lt;/li&gt;
&lt;li&gt;Группы друзей в XMPP не связаны с группами друзей на сайте - сделано
    по просьбе пользователей, которые не хотели чтобы их друзья из-за
    плеча видели в какой группе они находятся&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="integratsiia-so-vneshnimi-resursami"&gt;Интеграция со внешними ресурсами&lt;/h3&gt;
&lt;p&gt;Во Вконтакте считают данное направление очень перспективным и
осуществляют массу связанной с этим работы. Основные предпринятые шаги:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Максимальная кроссбраузерность для виджетов на основе библиотек
    easyXDM и fastXDM&lt;/li&gt;
&lt;li&gt;Кросс-постинг статусов в &lt;a href="/tag/twitter/"&gt;Twitter&lt;/a&gt;, реализованный с
    помощью очередей запросов&lt;/li&gt;
&lt;li&gt;Кнопка "поделиться с друзьями", поддерживающая openGraph теги и
    автоматически подбирающая подходящую иллюстрацию (путем сравнивание
    содержимых тега &lt;code&gt;&amp;lt;title&amp;gt;&lt;/code&gt; и атрибутов alt у изображений, чуть ли не
    побуквенно)&lt;/li&gt;
&lt;li&gt;Возможность загрузки видео через сторонние видео-хостинги (YouTube,
    RuTube, Vimeo, и.т.д.), открыты к интеграции с другими&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="interesnye-fakty-ne-po-teme_1"&gt;Интересные факты не по теме&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Процесс разработки близок к Agile, с недельными итерациями&lt;/li&gt;
&lt;li&gt;Ядро операционной системы модифицированно (на предмет работы с
    памятью), есть своя пакетная база для &lt;a href="/tag/debian/"&gt;Debian&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Фотографии загружаются на два жестких диска одного сервера
    одновременно, после чего создается резервная копия на другом сервере&lt;/li&gt;
&lt;li&gt;Есть много доработок над &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;, в.т.ч. для
    более стабильного и длительного размещения объектов в памяти; есть
    даже persistent версия&lt;/li&gt;
&lt;li&gt;Фотографии не удаляются для минимизации фрагментации&lt;/li&gt;
&lt;li&gt;Решения о развитии проекта принимают Павел Дуров и Андрей Рогозов,
    ответственность за сервисы - на них и на реализовавшем его
    разработчике&lt;/li&gt;
&lt;li&gt;Павел Дуров откладывал деньги на хостинг с 1 курса :)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="podvodim-itogi"&gt;Подводим итоги&lt;/h2&gt;
&lt;p&gt;В целом Вконтакте развивается в сторону увеличения скорости
распространения информацию внутри сети. Приоритеты поменялись в этом
направлении достаточно недавно, этим обусловлено, например, перенос
выхода почтового сервиса Вконтакте, о котором очень активно говорили
когда появилась возможность забивать себе текстовые URL вроде
&lt;code&gt;vkontakte.ru/ivan.blinkov&lt;/code&gt;. Сейчас этот подпроект имеет низкий приоритет
и ждет своего часа, когда они смогут предложить что-то более удобное и
быстрое, чем Gmail.&lt;/p&gt;
&lt;p&gt;Завеса тайны насчет технической реализации Вконтакте была немного
развеяна, но много моментов все же остались секретом. Возможно в будущем
появится более детальная информация о собственной СУБД Вконтакте,
которая как оказалось является ключом к решению всех самых сложных
моментов в масштабируемости системы.&lt;/p&gt;
&lt;p&gt;Как я уже упоминал этот пост написан почти на память, на основе
небольшого конспекта "круглого стола Вконтакте", так что хочется сразу
извиниться за возможные неточности и недопонимания. Я лишь
структурировал хаотичную кучу ответов на вопросы. Буду рад уточнениям и
дополнениям.&lt;/p&gt;
&lt;p&gt;Если хотите быть в курсе новых веяний в сфере масштабируемости
высоконагруженных интернет-проектов - по традиции рекомендую
&lt;a href="/feed/"&gt;подписаться на RSS&lt;/a&gt;.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Thu, 28 Oct 2010 21:12:00 +0400</pubDate><guid>tag:www.insight-it.ru,2010-10-28:highload/2010/arkhitektura-vkontakte/</guid><category>Apache</category><category>C++</category><category>Debian</category><category>featured</category><category>ffmpeg</category><category>HAProxy</category><category>highload</category><category>Linux</category><category>Memcached</category><category>mod_php</category><category>MySQL</category><category>nginx</category><category>node.js</category><category>openssl</category><category>PHP</category><category>XCache</category><category>xfs</category><category>Архитектура Вконтакте</category><category>Вконтакте</category></item><item><title>Архитектура Facebook</title><link>https://www.insight-it.ru//highload/2010/arkhitektura-facebook/</link><description>&lt;p&gt;&lt;img alt="Facebook Logo" class="left" src="https://www.insight-it.ru/images/facebook_logo.jpg" title="Facebook Logo"/&gt;
На сегодняшний день &lt;a href="https://www.insight-it.ru/goto/fbae133c/" rel="nofollow" target="_blank" title="https://www.facebook.com"&gt;Facebook&lt;/a&gt; является пожалуй
самым обсуждаемым интернет-проектом во всем мире. Не смотря на довольно
низкий уровень проникновения Facebook в России, темпы захвата аудитории
этим проектом мягко говоря поражают. Как же им удается управляться с
таким огромным социальным графом и удовлетворять потребности в общении
невероятно большого количества людей по всему миру?&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="platforma"&gt;Платформа&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; - операционная система&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; с &lt;a href="/tag/hiphop/"&gt;HipHop&lt;/a&gt; - код на PHP компилируется в
    C++&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/mysql/"&gt;MySQL&lt;/a&gt; - используется как хранилище пар ключ-значение,
    никаких join'ов&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/scribe/"&gt;Scribe&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;Более миллиарда социальных связей&lt;/li&gt;
&lt;li&gt;Более 200 миллиардов просмотров страниц в месяц&lt;/li&gt;
&lt;li&gt;Более 4 триллионов действий попадает в новостные ленты каждый день&lt;/li&gt;
&lt;li&gt;Более 150 миллионов обращений к кэшу в секунду; 2 триллиона объектов
    в кэше&lt;/li&gt;
&lt;li&gt;Более 8 миллиардов минут провели пользователи на Facebook'е
    ежедневно&lt;/li&gt;
&lt;li&gt;Более 3 миллиардов фотографий загружается каждый месяц, до 1.2
    миллиона фотографий в секунду&lt;/li&gt;
&lt;li&gt;20 миллиардов фотографий в 4 разрешениях = 80 миллиардов фотографий,
    их бы хватило чтобы покрыть поверхность земли в 10 слоев; это
    больше, чем на всех других фото-ресурсах в месте взятых&lt;/li&gt;
&lt;li&gt;О более чем 5 миллиардах единиц контента рассказывается друзьям
    еженедельно&lt;/li&gt;
&lt;li&gt;Более миллиарда сообщений в чате каждый день&lt;/li&gt;
&lt;li&gt;Более ста миллионов поисковых запросов в день&lt;/li&gt;
&lt;li&gt;Более 250 приложений и 80 тысяч сторонних ресурсов на платформе
    Facebook Connect&lt;/li&gt;
&lt;li&gt;Более 400 тысяч разработчиков сторонних приложений&lt;/li&gt;
&lt;li&gt;Менее 500 разработчиков и системных администраторов в штате&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;h3 id="obshchie-printsipy"&gt;Общие принципы&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Балансировщик нагрузки выбирает веб-сервер для обработки запроса&lt;/li&gt;
&lt;li&gt;PHP-код в веб-сервере подготавливает HTML, пользуясь данными из
    различных источников:&lt;ul&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;memcached&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;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Использование открытых технологий там, где это возможно&lt;/li&gt;
&lt;li&gt;Поиск возможностей оптимизации используемых продуктов&lt;/li&gt;
&lt;li&gt;Философия Unix:&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;li&gt;Все усилия направлены на масштабируемость&lt;/li&gt;
&lt;li&gt;Попытки минимизации количества точек отказа&lt;/li&gt;
&lt;li&gt;Простота, простота, простота!&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="php"&gt;PHP&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Почему PHP?&lt;/strong&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;Легок в чтении: синтаксис похож на C++ и Java&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;strong&gt;Как оказалось на самом деле?&lt;/strong&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;/ul&gt;
&lt;p&gt;&lt;strong&gt;Доработки:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Оптимизация байт-кода&lt;/li&gt;
&lt;li&gt;Улучшения в APC (ленивая загрузка, оптимизация блокировок,
    "подогрев" кэша)&lt;/li&gt;
&lt;li&gt;Свои расширения (клиент memcache, формат сериализации, логи,
    статистика, мониторинг, механизм асинхронной обработки событий)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://www.insight-it.ru/goto/169aa287/" rel="nofollow" target="_blank" title="http://github.com/facebook/hiphop-php"&gt;HipHop&lt;/a&gt;&lt;/strong&gt; - трансформатор
    исходных кодов:&lt;ul&gt;
&lt;li&gt;Разработчики пишут на PHP, который конвертируется в
    оптимизированный C++&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;Опубликован под opensource лицензией в начале года, нет
    необходимости проходить этот же путь с нуля&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mysql"&gt;MySQL&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Как используется MySQL?&lt;/strong&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;strong&gt;не&lt;/strong&gt; используется&lt;/li&gt;
&lt;li&gt;Большинство запросов касаются самой свежей информации: оптимизация
    таблиц для доступа к новым данным, архивация старых записей&lt;/li&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;em&gt;очень&lt;/em&gt; сложна&lt;/li&gt;
&lt;li&gt;Создавать большое количество логических баз данных и
    перераспределять их между физическими узлами, балансируя таким
    образом нагрузку, намного удобнее&lt;/li&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;/ul&gt;
&lt;p&gt;&lt;strong&gt;Доработки:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Практически никаких модификаций исходного кода MySQL&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;
&lt;li&gt;Реплицированные связи (ребра графа)&lt;/li&gt;
&lt;li&gt;Аналоги распределенных внешних ключей (foreign keys)&lt;/li&gt;
&lt;li&gt;Большинство данных распределено случайно&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="memcache"&gt;Memcache&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Как используется memcached?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Высокопроизводительная распределенная хэш-таблица&lt;/li&gt;
&lt;li&gt;Содержит "горячие" данные из MySQL&lt;/li&gt;
&lt;li&gt;Снижает нагрузку на уровень баз данных&lt;/li&gt;
&lt;li&gt;Основная форма кэширования&lt;/li&gt;
&lt;li&gt;Используется более 25TB памяти на нескольких тысячах серверов&lt;/li&gt;
&lt;li&gt;Среднее время отклика менее 250 микро-секунд&lt;/li&gt;
&lt;li&gt;Кэшируются сериализованные структуры данных PHP&lt;/li&gt;
&lt;li&gt;Отсутствие автоматического механизма проверки консистенции данных
    между memcached и MySQL - приходится делать это на уровне
    программного кода&lt;/li&gt;
&lt;li&gt;Множество multi-get запросов для получения данных на другом конце
    ребер графа&lt;/li&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;Порт на 64-битную архитектуру&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;Доступ к memcache через UDP:&lt;ul&gt;
&lt;li&gt;уменьшает расход памяти благодаря отсутствию тысяч буферов TCP
    соединений&lt;/li&gt;
&lt;li&gt;управление ходом исполнения приложение (оптимизация для
    multi-get)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Статистика о работе потоков по запросу - уменьшает блокировки&lt;/li&gt;
&lt;li&gt;Ряд изменений в ядре Linux для оптимизации работы memcache:&lt;ul&gt;
&lt;li&gt;распределение управления сетевыми прерывания по всем ядрам&lt;/li&gt;
&lt;li&gt;оппортунистический опрос сетевых интерфейсов&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;После вышеперечисленных модификаций memcached способен выполнять до
    250 тысяч операций в секунду, по сравнению со стандартными 30-40
    тысячами без данных изменений&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="thrift"&gt;Thrift&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Что это?&lt;/strong&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;a href="/tag/c/"&gt;C++&lt;/a&gt;, &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt;,
    &lt;a href="/tag/python/"&gt;Python&lt;/a&gt;, &lt;a href="/tag/java/"&gt;Java&lt;/a&gt;, &lt;a href="/tag/ruby/"&gt;Ruby&lt;/a&gt;,
    &lt;a href="/tag/erlang/"&gt;Erlang&lt;/a&gt;, &lt;a href="/tag/perl/"&gt;Perl&lt;/a&gt;, &lt;a href="/tag/haskell/"&gt;Haskell&lt;/a&gt; и
    многие другие&lt;/li&gt;
&lt;li&gt;Транспорты: простой интерфейс для ввода-вывода (сокеты, файлы,
    буферы в памяти)&lt;/li&gt;
&lt;li&gt;Протоколы: стандарты сериализации (бинарный, JSON)&lt;/li&gt;
&lt;li&gt;Серверы: неблокирующие, асинхронные, как однопоточные, так и
    многопоточные&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;Почему именно Thrift?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Альтернативные технологии: SOAP, CORBA, COM, Pillar, Protocol
    Buffers - но у всех есть свои существенные недостатки, что вынудило
    Facebook создать свою технологию&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;h3 id="scribe"&gt;Scribe&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Что это?&lt;/strong&gt;&lt;/p&gt;
&lt;ul&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;li&gt;Публикации в новостных лентах&lt;/li&gt;
&lt;li&gt;Данные по A/B тестированиям&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Более надежен, чем традиционные системы логгирования, но
    недостаточно надежен для транзакций баз данных&lt;/li&gt;
&lt;li&gt;Простая модель данных&lt;/li&gt;
&lt;li&gt;Построен на основе Thrift&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="khranenie-fotografii"&gt;Хранение фотографий&lt;/h3&gt;
&lt;p&gt;&lt;strong&gt;Сначала сделали это просто:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Загрузка на сервер: приложение принимает изображение, создает
    миниатюры в нужных разрешениях, сохраняет в NFS&lt;/li&gt;
&lt;li&gt;Загрузка с сервера: изображения отдаются из NFS через HTTP&lt;/li&gt;
&lt;li&gt;NFS построена на коммерческих продуктах&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;li&gt;Ограничивающим фактором является ввод-вывод, а не плотность
    хранения&lt;/li&gt;
&lt;/ul&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;/li&gt;
&lt;li&gt;Распределение их по &lt;a href="/tag/cdn/"&gt;CDN&lt;/a&gt; для уменьшения сетевых задержек&lt;/li&gt;
&lt;li&gt;Возможно сделать еще лучше:&lt;ul&gt;
&lt;li&gt;Хранение изображений в больших бинарных файлах (blob)&lt;/li&gt;
&lt;li&gt;Сервис, отвечающий за фотографии имеет информацию о том, в каком
    файле и с каким отступом от начала расположена каждая фотография
    (по ее идентификатору)&lt;/li&gt;
&lt;li&gt;Этот сервис в Facebook называется Haystack и он оказался в 10
    раз эффективнее "простого" подхода и в 3 раза эффективнее
    "оптимизированного"&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="drugie-servisy"&gt;Другие сервисы&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;SMC&lt;/strong&gt;: консоль управления сервисами - централизованная
    конфигурация, определение на какой физической машине работает
    логический сервис&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ODS&lt;/strong&gt;:&amp;nbsp;инструмент для визуализации изменений любых статистических
    данных, имеющихся в системе; удобен для мониторинга и оповещений&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Gatekeeper:&lt;/strong&gt; разделение развертывания и запуска, A/B
    тестирования, таргетированный запуск, постепенный запуск&lt;/li&gt;
&lt;li&gt;И еще около 50 других сервисов...&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="kak-eto-rabotaet-vse-vmeste_1"&gt;Как это работает все вместе?&lt;/h2&gt;
&lt;h3 id="novye-albomy-druzei"&gt;Новые альбомы друзей&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Facebook Screenshot" class="responsive-img" src="https://www.insight-it.ru/images/facebook_screenshot.jpg" title="Facebook"/&gt;&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Получаем профиль по идентификатору пользователя (скорее всего из
    кэша, но потенциально возможно обращение к базе данных)&lt;/li&gt;
&lt;li&gt;Получаем список друзей (опять же на основе идентификатора
    пользователя из кэша или из базы данных в случае промаха)&lt;/li&gt;
&lt;li&gt;Параллельно запрашиваем идентификаторы последних 10 альбомов для
    каждого из друзей (multi-get, каждый промах мимо кэша индивидуально
    вытаскивается из MySQL)&lt;/li&gt;
&lt;li&gt;Параллельно получаем данные о всех альбомах (на основе
    идентификаторов альбомов из предыдущего шага)&lt;/li&gt;
&lt;li&gt;Все данные получены, выполняем логику отрисовки конкретной страницы
    на PHP&lt;/li&gt;
&lt;li&gt;Отправляем HTML в браузер, пользователь счастлив :)&lt;/li&gt;
&lt;/ol&gt;
&lt;h3 id="novostnaia-lenta"&gt;Новостная лента&lt;/h3&gt;
&lt;p&gt;&lt;img alt="News Feed Screenshot" class="responsive-img" src="https://www.insight-it.ru/images/facebook_screenshot_2.jpg" title="News Feed"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="News Feed Scheme" class="responsive-img" src="https://www.insight-it.ru/images/facebook_screenshot_3.jpg" title="News Feed"/&gt;&lt;/p&gt;
&lt;h3 id="poisk"&gt;Поиск&lt;/h3&gt;
&lt;p&gt;&lt;img alt="Search Screenshot" class="responsive-img" src="https://www.insight-it.ru/images/facebook_screenshot_4.jpg" title="Search"/&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="Search Scheme" class="responsive-img" src="https://www.insight-it.ru/images/facebook_screenshot_5.jpg" title="Search"/&gt;&lt;/p&gt;
&lt;h2 id="podvodim-itogi_1"&gt;Подводим итоги&lt;/h2&gt;
&lt;p&gt;LAMP не идеален&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;PHP+MySQL+Memcache решает большинство задач, но не может решить
    совсем все:&lt;ul&gt;
&lt;li&gt;PHP не может хранить состояния&lt;/li&gt;
&lt;li&gt;PHP не самый производительный язык&lt;/li&gt;
&lt;li&gt;Все данные находятся удаленно&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Facebook разрабатывает собственные внутренние сервисы, чтобы:&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;li&gt;Философия сервисов:&lt;ul&gt;
&lt;li&gt;Создание сервисов только при необходимости (минимизация издержек
    по развертке, поддержке и ведению отдельной кодовой базы;
    потенциальная дополнительная точка сбоя)&lt;/li&gt;
&lt;li&gt;Создание общего набора инструментов для создания сервисов
    (Thrift, Scribe, ODS, средства мониторинга и уведомлений)&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Использование правильных языка программирования, библиотек и
    инструментов для решения задачи&lt;/em&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Возвращение инноваций общественности - важный аспект разработки в
    Facebook:&lt;ul&gt;
&lt;li&gt;Опубликованные свои проекты:&lt;ul&gt;
&lt;li&gt;Thrift&lt;/li&gt;
&lt;li&gt;Scribe&lt;/li&gt;
&lt;li&gt;Tornado&lt;/li&gt;
&lt;li&gt;Cassandra&lt;/li&gt;
&lt;li&gt;Varnish&lt;/li&gt;
&lt;li&gt;Hive&lt;/li&gt;
&lt;li&gt;xhprof&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Доработки популярных решений:&lt;ul&gt;
&lt;li&gt;PHP&lt;/li&gt;
&lt;li&gt;MySQL&lt;/li&gt;
&lt;li&gt;memcached&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Информация о взаимодействии Facebook с opensource-сообществом,
    этих и других проектах расположена на &lt;a href="https://www.insight-it.ru/goto/535d8e6b/" rel="nofollow" target="_blank" title="http://developers.facebook.com/opensource/"&gt;странице, посвященной
    opensource&lt;/a&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Ключевые моменты культуры разработки в Facebook:&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;/li&gt;
&lt;/ul&gt;
&lt;h2 id="istochniki-informatsii"&gt;Источники информации&lt;/h2&gt;
&lt;p&gt;Данная статья не является переводом готовой статьи, в качестве
источников информации послужили записи выступлений сотрудников Facebook
на конференциях:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/4c672c94/" rel="nofollow" target="_blank" title="http://www.infoq.com/presentations/Facebook-Software-Stack"&gt;Facebook Architecture: Science and the Social Graph&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/2ccd1899/" rel="nofollow" target="_blank" title="http://www.infoq.com/presentations/Facebook-Moving-Fast-at-Scale"&gt;Facebook: Moving Fast at Scale&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/3867625a/" rel="nofollow" target="_blank" title="http://www.infoq.com/presentations/Scale-at-Facebook"&gt;Scale at Facebook&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Очень рекомендую посмотреть материалы в оригинале, так как естественно я
осветил в статье далеко не все, да и неточности какие-либо неисключены.
Помимо этого возможно многим будет интересно мероприятие &lt;a href="https://www.insight-it.ru/goto/ff11ad2b/" rel="nofollow" target="_blank" title="http://styleru.timepad.ru/event/3571"&gt;"Facebook: how we scaled to 500 000 000 users "&lt;/a&gt;,
где Robert Johnson выступает 22 октября в Москве. Еще он числится в
списке докладчиков &lt;a href="https://www.insight-it.ru/goto/727c9436/" rel="nofollow" target="_blank" title="http://www.highload.ru"&gt;Highload++&lt;/a&gt; с аналогичным
выступлением. Дополнительную информацию можно почерпнуть в &lt;a href="https://www.insight-it.ru/goto/f38bc794/" rel="nofollow" target="_blank" title="http://facebook.com/eblog"&gt;блоге инженеров Facebook&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;UPD:&lt;/strong&gt; Обновил некоторые моменты после посещения вышеупомянутого
выступления Роберта.&lt;/p&gt;
&lt;p&gt;И по традиции напоминаю, что так как я пишу довольно редко - читать мой
блог намного удобнее по &lt;a href="/feed/"&gt;RSS&lt;/a&gt;. Спасибо за внимание :)&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Wed, 20 Oct 2010 13:02:00 +0400</pubDate><guid>tag:www.insight-it.ru,2010-10-20:highload/2010/arkhitektura-facebook/</guid><category>CDN</category><category>Facebook</category><category>featured</category><category>HipHop</category><category>Linux</category><category>Memcached</category><category>MySQL</category><category>ODS</category><category>PHP</category><category>Scribe</category><category>Thrift</category><category>Архитектура Facebook</category></item><item><title>Как проект Ravelry дорос до 10 миллионов запросов с помощью Rails</title><link>https://www.insight-it.ru//highload/2009/kak-proekt-ravelry-doros-do-10-millionov-zaprosov-s-pomoshhyu-rails/</link><description>&lt;p&gt;Данная статься основана на замечательном интервью, взятом Tim Bray у
Casey Forbes, создателя &lt;a href="https://www.insight-it.ru/goto/ce0996b1/" rel="nofollow" target="_blank" title="http://www.ravelry.com/"&gt;Ravelry&lt;/a&gt;, сайта на
Ruby on Rails, поддерживаемое сообществом вязальщиц и специалистов по
вышивке крючком численностью более 400000 человек.&lt;/p&gt;
&lt;p&gt;Casey и его небольшой команде удалось реализовать массу великолепных
идей на Ravelry. Этот сайт очень сфокусирован на своей тематике и
представляет собой большую информационную ценность для заинтересованных
лиц. Все пользователи Ravelry просто обожают этот сайт, этот факт
очевиден по их комментариям полным энтузиазма и невероятно быстрому
освоению Ravelry.&lt;/p&gt;
&lt;p&gt;Десять лет назад сайт масштаба Ravelry потребовал бы далеко не один
миллион долларов для поддержания своего функционирования. Сегодня же
Casey является единственным разработчиком Ravelry, а поддержанием
работоспособности системы занимается всего несколько человек.
Изначальный процесс разработки занял у Casey 4 месяца работы по ночам и
выходным. Если Вы взглянете на список технологий, используемых в
Ravelry, Вам станет видно, что проект построен практически полностью на
свободном и бесплатном программном обеспечении, которые просто было
собрано вместе в единую полноценную систему. В сегодняшней экосистеме
существует множество возможностей для того чтобы делать новые вещи
просто комбинируя существующие качественные приложения, языки
программирования, системы хранения, а также услуги по размещению и
предоставлению доступа к веб-приложениям и данным.&lt;/p&gt;
&lt;p&gt;Сейчас Casey и еще несколько сотрудников живут за счет Ravelry. Не это
ли является мечтой любого предприятия малого бизнеса? Хотите узнать как
и Вы могли бы достичь подобных успехов?
&lt;!--more--&gt;
&lt;em&gt;Данный текст является переводом статьи &lt;a href="https://www.insight-it.ru/goto/24572014/" rel="nofollow" target="_blank" title="http://highscalability.com/how-ravelry-scales-10-million-requests-using-rails"&gt;How Ravelry Scales to 10 Million Requests Using Rails&lt;/a&gt;,
автор оригинала - &lt;a href="https://www.insight-it.ru/goto/f3f1b405/" rel="nofollow" target="_blank" title="http://highscalability.com/user/todd-hoff"&gt;Todd Hoff&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;10 миллионов запросов ежедневно обрабатывается &lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt; (AJAX + RSS + API)&lt;/li&gt;
&lt;li&gt;3.6 миллиона просмотров страниц ежедневно&lt;/li&gt;
&lt;li&gt;430,000 зарегистрированных пользователей. 70,000 активно пользуются
    сайтом ежедневно. 900 новых пользователей регистрируется ежедневно.&lt;/li&gt;
&lt;li&gt;2.3 миллиона проектов по вязанию, 50000 новых сообщений на форуме
    ежедневно, всего 19 миллионов сообщений на форуме, 13 миллионов
    сообщений, 8 миллионов фотографий (большая часть размещена на
    &lt;a href="/tag/flickr/"&gt;Flickr&lt;/a&gt;).&lt;/li&gt;
&lt;li&gt;Проект начинался на небольшом VPS, но потребности в ресурсах очень
    быстро вышли за его возможности.&lt;/li&gt;
&lt;li&gt;Монетизация: рекламодатели + магазин соответствующей продукции +
    продажа узоров&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="platform"&gt;Platform&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/ruby-on-rails/"&gt;Ruby on Rails&lt;/a&gt; (1.8.6, Ruby GC патчи)&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/percona/"&gt;Percona&lt;/a&gt; сборка &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/gentoo/"&gt;Gentoo&lt;/a&gt; &lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Servers: Silicon Mechanics (не арендуемые, в их собственности)&lt;/li&gt;
&lt;li&gt;Хостинг: Colocation от Hosted Solutions&lt;/li&gt;
&lt;li&gt;Интернет-канал: Cogent (очень дешево)&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/capistrano/"&gt;Capistrano&lt;/a&gt; для развертывания&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/nginx/"&gt;Nginx&lt;/a&gt; существенно более быстрый и менее требовательный к оперативной памяти по сравнению с Apache&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/xen/"&gt;Xen&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/munin/"&gt;Munin&lt;/a&gt; для мониторинга&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/tokyo-cabinet/"&gt;Tokyo Cabinet&lt;/a&gt; / &lt;a href="/tag/tokyo-tyrant/"&gt;Tokyo Tyrant&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/hoptoad/"&gt;HopToad&lt;/a&gt; для уведомлений об исключительных ситуациях.&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/newrelic/"&gt;NewRelic&lt;/a&gt; для тонкой настройки&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/syslog-ng/"&gt;Syslog-ng&lt;/a&gt; для агрегации логов&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/s3/"&gt;S3&lt;/a&gt; для хранения данных&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/cloudfront/"&gt;Cloudfront&lt;/a&gt; в роли CDN&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/sphinx/"&gt;Sphinx&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;h2 id="arkhitektura"&gt;Архитектура&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;7 серверов (Gentoo Linux). Средствами виртуализации (Xen) создано 13
    виртуальных серверов:&lt;ul&gt;
&lt;li&gt;Для обработки пользовательских запросов используются Nginx и
Haproxy. Запросы проходят следущую цепочку: &lt;code&gt;nginx -&amp;gt; haproxy -&amp;gt; apache + mod_passenger&lt;/code&gt;.&lt;/li&gt;
&lt;li&gt;Один небольшой сервер для резервного копирования данных.&lt;/li&gt;
&lt;li&gt;Один небольшой вспомогательный сервер для некритичных процессов
и тестирования новых версий.&lt;/li&gt;
&lt;li&gt;2 сервера с 32 GB оперативной памяти для master+slave баз
данных, а также поисковой системы Sphinx.&lt;/li&gt;
&lt;li&gt;3 сервера приложений, состоящих из 6 Apache Passenger и
запущенных экземпляров Ruby, каждый ограничен 20-ю потоками.
Суммарно 6 четырехядерных процессоров и 40 GB оперативной памяти.
Часть оперативной памяти большую часть времени простаивает.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;5 терабайт данных располагается в Amazon S3. Cloudfront используется
    как CDN.&lt;/li&gt;
&lt;li&gt;Tokyo Cabinet/Tyrant используется вместо memcached в некоторых
    местах для кеширования более крупных объектов, в частности уже
    размеченного текста в HTML.&lt;/li&gt;
&lt;li&gt;HAproxy и Capistrano используются для вывода новых версий сайта без
    негативного влияния на производительность и работу пользователей.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="podvodim-itogi"&gt;Подводим итоги&lt;/h2&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;. Ravelry
    частично был создан за счет его пользователей, которые пожертвовали
    в пользу проекта более 71 тысячи долларов. Эти средства были
    переданы проекту просто как дар, а не в обмен на акции. Не
    недооценивайте значимость капитала компании. Ravelry потребовалось 6
    месяцев непрерывной работы и экономии на издержках, связанных с
    серверным оборудованием и каналами связи, чтобы наконец-то начать
    получать прибыль, и полученные от пользователей средства оказались
    основным фактором, позволившим проекту пережить этот тяжелый период.
    Залогом их успеха является поддержание интереса и искры в глазах
    своих пользователей, подталкивание пользователей к оказанию помощи и
    поддержки проекту. Для этого требуется любовь к своему делу и
    самоотдача.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Станьте центром выбранной ниши&lt;/strong&gt;. Найдите нишу на рынке с
    недостаточным предложением. Не стремитесь к массовым рынкам. Совсем
    не обязательно делать что-то для многих миллионов людей. Миллионы
    скорее всего просто зевнут от скуки и в скором времени о Вас
    забудут. Лучше создайте что-нибудь очень полезное для небольшой
    заинтересованной группы лиц и их страсть к их интересам перейдет и к
    Вам.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Успех не обязательно должен быть связан с масштабностью проекта, намного большее значение имеет стабильная и качественная реализация&lt;/strong&gt; &amp;copy; Jeff Putz.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Основная проблема в базе данных&lt;/strong&gt;. Практически вся работа,
    относящаяся к масштабируемости/настройке/производительности, так или
    иначе связана с базой данных. Например, изменение схемы данных для
    больших таблиц в MySQL всегда связано с рядом проблем, особенно если
    простой сервиса неприемлем. Еще один аргумент в пользу баз данных,
    не имеющих схем данных.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Продолжайте получать удовольствие&lt;/strong&gt;. Casey перешел на Ruby on
    Rails так как ему хотелось снова заняться программированием с
    энтузиазмом. Этот факт стал одним из основных факторов, которые
    помогли сделать проект успешным.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Придумывайте новые вещи, которые будут приводить в восторг Ваших
    пользователей&lt;/strong&gt;. Воспользуйтесь магией, людям это нравится. Это тоже
    один из принципов данного проекта. Например по этой
    &lt;a href="https://www.insight-it.ru/goto/e231d34/" rel="nofollow" target="_blank" title="http://www.tbray.org/ongoing/When/200x/2009/09/02/Ravelry#c1252474782.65559"&gt;ссылке&lt;/a&gt;, можно почитать об использовании очень инновационных подходов к управлению форумами.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Ruby &amp;mdash; это круто&lt;/strong&gt;. Он представляет собой интересный язык
    программирования, позволивший Ravelry быстро пройти стадию
    изначальной разработки и выпускать новые версии дважды в день в
    период бета-тестирования.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Получайте большую прибыль за счет минимизации издержек&lt;/strong&gt;. У
    Ravelry есть свой магазин с соответствующей тематике продукцией,
    оптовые счета, принтеры и реализующая компания. Это позволяет им
    поддерживать издержки на низком уровне, таким образом их прибыль не
    уходит сторонним компаниям вроде CafePress.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Наиболее сложный переход заключается в переходе от одного сервера к нескольким&lt;/strong&gt;. В этом процессе все меняется и становится более
    сложным и комплексным. Всегда имейте этот переход ввиду, когда
    планируете архитектуру веб-приложения.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;В сегодняшней экосистеме имеется возможность делать массу различных вещей даже обладая минимумом ресурсов&lt;/strong&gt;. Для создания
    комплексного сайта вроде Ravelry больше не нужно много людей или
    финансов. Взгляните на список различных программ, используемых в
    Ravelry, а также на небольшое количество людей, работающих над
    поддержанием работы проекта.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Некоторые люди могут жаловаться, что здесь нет практически никаких
подробностей о том, как же все таки работает Ravelry. Сайты таких
размеров не должны иметь развернутого описания мистического процесса его
масштабирования, такие проекты могут быть построены просто из составных
частей, с умом собранных вместе. И это очень здорово.&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Thu, 24 Sep 2009 11:31:00 +0400</pubDate><guid>tag:www.insight-it.ru,2009-09-24:highload/2009/kak-proekt-ravelry-doros-do-10-millionov-zaprosov-s-pomoshhyu-rails/</guid><category>Ravelry</category><category>Ruby</category><category>Rails</category><category>Ruby on Rails</category><category>Percona</category><category>MySQL</category><category>Gentoo</category><category>Linux</category><category>Capistrano</category><category>nginx</category><category>HAProxy</category><category>Munin</category><category>Tokyo Cabinet</category><category>Tokyo Tyrant</category><category>Xen</category><category>Nagios</category><category>HopToad</category><category>NewRelic</category><category>syslog-ng</category><category>Cloudfront</category><category>S3</category><category>Sphinx</category><category>memcached</category></item><item><title>Архитектура LinkedIn</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-linkedin/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/801d7bb4/" rel="nofollow" target="_blank" title="https://www.linkedin.com"&gt;LinkedIn&lt;/a&gt; является крупнейшей в мире
социальной сетью для профессионалов. Популярность этого проекта может
быть далека, от более общетематических социальных сетей, таких как,
скажем Facebook, но, тем не менее, нагрузка на серверную часть проекта
создается пользователями серьезная. О том как этот проект с ней
справляется и пойдет речь далее.
&lt;!--more--&gt;&lt;/p&gt;
&lt;h3 id="predislovie"&gt;Предисловие&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Сообщение о публикации двух презентаций c JavaOne 2008 о LinkedIn и их
&lt;a href="https://www.insight-it.ru/goto/36e64126/" rel="nofollow" target="_blank" title="http://hurvitz.org/blog/2008/06/linkedin-architecture"&gt;обобщении&lt;/a&gt; от
Overn Hurvitz пронеслось по русскоязычным новостным ресурсам уже
достаточно давно, но время черкнуть пару строк обо всем этом нашлось у
меня только сейчас.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/aef5ee94/" rel="nofollow" target="_blank" title="http://www.slideshare.net/linkedin/linkedins-communication-architecture"&gt;LinkedIn - A Professional Social Network Built with Java&amp;trade; Technologies and Agile Practices&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/515b891c/" rel="nofollow" target="_blank" title="http://www.slideshare.net/linkedin/linked-in-javaone-2008-tech-session-comm"&gt;LinkedIn Communication Architecture&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="statistika"&gt;Статистика&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;22 миллиона пользователей;&lt;/li&gt;
&lt;li&gt;4+ миллиона уникальных посетителей в день;&lt;/li&gt;
&lt;li&gt;40 миллионов просмотров страниц в день;&lt;/li&gt;
&lt;li&gt;2 миллиона поисковых запросов в день;&lt;/li&gt;
&lt;li&gt;ежедневно отправляются 250 тысяч приглашений;&lt;/li&gt;
&lt;li&gt;1 миллион ответов в день;&lt;/li&gt;
&lt;li&gt;2 миллиона электронных сообщений ежедневно.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="platforma"&gt;Платформа&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/solaris/"&gt;Solaris&lt;/a&gt; (как x86, так и SPARC)&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/tomcat/"&gt;Tomcat&lt;/a&gt; и &lt;a href="/tag/jetty/"&gt;Jetty&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/oracle/"&gt;Oracle&lt;/a&gt; и &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Никакого ORM&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/activemq/"&gt;ActiveMQ&lt;/a&gt; для JMS&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/lucene/"&gt;Lucene&lt;/a&gt; в качестве основы для поиска&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/spring/"&gt;Spring&lt;/a&gt; в роли "клея"&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="servernaia-arkhitektura"&gt;Серверная архитектура&lt;/h3&gt;
&lt;h4&gt;2003-2005&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;поиск пользователей реализован с помощью &lt;a href="/tag/lucene/"&gt;Lucene&lt;/a&gt;, он
    работал на той же машине, что и "Облако", так как поиск был
    отфильтрован в соответствии с сетью пользователя, таким образом было
    удобно совмещать эти две функции на одной машине;&lt;/li&gt;
&lt;li&gt;веб-приложение напрямую обновляет базу данных, а она, в свою
    очередь, обновляет "Облако".&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2006&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Добавлена репликация для уменьшения нагрузки на основную базу
    данных. Реплики предоставляют данные в режиме "только для чтения", а
    репликация ведется в асинхронном режиме с помощью дополнительного
    компонента под названием Databus, с его появлением обновление данных
    стало выглядеть следующим образом:&lt;ul&gt;
&lt;li&gt;сначала какие-либо изменения происходят в веб-приложении;&lt;/li&gt;
&lt;li&gt;веб-приложение обновляет основную базу данных;&lt;/li&gt;
&lt;li&gt;она, в свою очередь, отправляет обновления на Databus;&lt;/li&gt;
&lt;li&gt;далее уже Databus обновляет: реплики, Облако и поисковый индекс.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Поиск был вынесен на отдельный сервер.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;2008&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;такой подход позволяет другим приложениям (помимо основного)
    получать доступ к LinkedIn, такие приложения были созданы для
    работодателей, рекламных служб, и так далее.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="oblako"&gt;Облако&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;"Облаком" в LinkedIn называют сервер, который кэширует весь граф
    социальной сети в памяти;&lt;/li&gt;
&lt;li&gt;его размеры: 22 миллиона вершин и 120 миллионов ребер;&lt;/li&gt;
&lt;li&gt;занимает 12GB оперативной памяти;&lt;/li&gt;
&lt;li&gt;одновременно держится в памяти в 40 экземплярах;&lt;/li&gt;
&lt;li&gt;построение Облака из данных, в дисковой системе, занимает 8 часов;&lt;/li&gt;
&lt;li&gt;обновления происходят в режиме реального времени с помощью Databus;&lt;/li&gt;
&lt;li&gt;во время остановки данные записываются на диск;&lt;/li&gt;
&lt;li&gt;кэш реализован с помощью C++, а доступ предоставляется по JNI;&lt;/li&gt;
&lt;li&gt;они выбрали именно C++ так как требовалось использовать минимум
    оперативной памяти, а также, задержки, связанные с Garbage
    Collection, были неприемлемыми.&lt;/li&gt;
&lt;li&gt;размещение всех данных в памяти является ограничением, но, как
    удалось выяснить в LinkedIn, разбиение графов на части - не самая
    тривиальная задача.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Облако кэширует целиком весь граф социальной сети LinkedIn, но на
практике же пользователям требуется видеть его со своей точки зрения.
Данная задача является вычислительно сложной, по-этому она выполняется
лишь один раз при создании новой сессии, а затем система поддерживает
результат в кэше. Такой подход требует 2 MB оперативной памяти на
каждого активного пользователя. В течении сессии такой кэш обновляется
только если сам пользователь сделал какие-либо изменения в нем, если же
изменение вызвано другими пользователями - владелец сессии не заметит
изменений.&lt;/p&gt;
&lt;p&gt;Помимо этого используется кэширование профилей пользователей средствами
&lt;a href="/tag/ehcache/"&gt;EHcache&lt;/a&gt;. Одновременно в памяти хранится до 2 миллионов
профилей (из 22 миллионов). Изначально планировалось использовать
алгоритм &lt;abbr title="Least Frequently Used"&gt;LFU&lt;/abbr&gt;, но оказалось,
что иногда &lt;a href="/tag/ehcache/"&gt;EHcache&lt;/a&gt; зависал секунд на 30 во время
перерасчета &lt;abbr title="Least Frequently Used"&gt;LFU&lt;/abbr&gt;, таким
образом было принято решение о использовании вместо него алгоритма
&lt;abbr title="Least Recently Used"&gt;LRU&lt;/abbr&gt;.&lt;/p&gt;
&lt;h3 id="arkhitektura-kommunikatsii"&gt;Архитектура коммуникации&lt;/h3&gt;
&lt;p&gt;Как известно, пользователи практически любой социальной сети генерируют
огромное количество сообщений в единицу времени, причем каждый тип
сообщений обычно требует индивидуального подхода, но в целом их можно
разделить на две категории: постоянные и временные. В LinkedIn
разработчики построили по отдельному сервису, для обработки каждой из
этих категорий. Каждый из них определенно заслуживает отдельного
внимания, так как общего в них мало.&lt;/p&gt;
&lt;h4&gt;Сервис постоянных сообщений&lt;/h4&gt;
&lt;p&gt;Этот коммуникационный сервис выполняет все операции, связанные с
постоянными сообщениями: приватными сообщениями и электронной почтой.
Перед ним ставится вполне тривиальный ряд задач: доставлять сообщения
получателям и сохранять их на постоянной основе, но на самом деле этим
все не ограничивается: должны также поддерживаться, скажем, доставка
сообщений с задержкой, массовые рассылки, отмена отправки сообщения,
возможность добавления в сообщения какого-либо интерактивного контента.
Реализован он был примерно следующим образом:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;вся система работает асинхронно и активно использует JMS;&lt;/li&gt;
&lt;li&gt;клиенты отправляют сообщения так же через JMS;&lt;/li&gt;
&lt;li&gt;далее сообщения перенаправляются с помощью сервиса маршрутизации в
    соответствующий почтовый ящик или напрямую в обработку электронной
    почты;&lt;/li&gt;
&lt;li&gt;доставка сообщений происходит как с помощью Pull (клиенты
    запрашивают свои сообщения), так и с использованием Push (т.е.
    отправки сообщений);&lt;/li&gt;
&lt;li&gt;помимо этого используется &lt;a href="/tag/spring/"&gt;Spring&lt;/a&gt; с их собственными
    закрытыми расширениями, использующими HTTP-RPC.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Приемы, способствующие масштабируемости&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Функциональное сегментирование:&lt;/strong&gt; отправленные, полученные,
    архивные сообщения. &lt;em&gt;(т.е. вертикальное сегментирование)&lt;/em&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;em&gt;(т.е.
    горизонтальное сегментирование)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Асинхронное выполнение операций&lt;/strong&gt;.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Сервис сетевых обновлений&lt;/h4&gt;
&lt;p&gt;Этот сервис обеспечивает работу любых временных уведомлений, например,
вызванных изменением статуса пользователей в контакт-листах. Такие
сообщения должны с течением времени удаляться из-за быстрой потери
актуальности, а также должна поддерживаться группировка и приоритезация
сообщений. Функционирование этого сервиса оказалось не настолько
очевидно, по сравнению с предыдущим, так что до итогового варианта было
перепробовано масса менее удачных решений, но обо всем по порядку.&lt;/p&gt;
&lt;h5&gt;Изначальная архитектура (до 2007 года)&lt;/h5&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;В 2008 году вся эта система поэтапно эволюционировала собственно в сам
сервис сетевых обновлений:&lt;/p&gt;
&lt;h5&gt;Первая итерация&lt;/h5&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;весь процесс основывается на Pull.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Вторая итерация&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;стал использоваться метод Push: каждый раз, когда происходит
    какое-либо событие, они помещаются в пользовательский "почтовый
    ящик", в момент запроса пользователя ему возвращается просто
    содержимое, уже ожидающее своего звездного часа в специально том
    самом "ящике";&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;abbr title="Character Large OBject"&gt;CLOB&lt;/abbr&gt;'ах: по одному &lt;abbr title="Character Large OBject"&gt;CLOB&lt;/abbr&gt;'у на каждый тип
    обновления для каждого пользователя (то есть в сумму около 15 &lt;abbr title="Character Large OBject"&gt;CLOB&lt;/abbr&gt;'ов на каждого пользователя);&lt;/li&gt;
&lt;li&gt;сначала использовался размер &lt;abbr title="Character Large OBject"&gt;CLOB&lt;/abbr&gt;'ов равный 8 KB,
    что было явно больше требуемого и приводило к существенному
    количеству неиспользуемого дискового пространства.&lt;/li&gt;
&lt;li&gt;вместо &lt;abbr title="Character Large OBject"&gt;CLOB&lt;/abbr&gt;'ов можно
    было бы использовать дополнительные таблици по одной на каждый
    тип обновлений, но в этом случае пришлось бы постоянно удалять
    из них устаревшие записи, что было бы чрезвычайно неэффективно.&lt;/li&gt;
&lt;li&gt;в дополнение к этому использовался &lt;abbr title="Java Management eXtensions"&gt;JMX&lt;/abbr&gt; для
    мониторинга и изменения конфигурации в реальном времени, что
    оказалось очень удобным и полезным.&lt;/li&gt;
&lt;/ul&gt;
&lt;h5&gt;Третья итерация&lt;/h5&gt;
&lt;ul&gt;
&lt;li&gt;Цель: повысить производительность путем сокращения количества
    обновлений &lt;abbr title="Character Large OBject"&gt;CLOB&lt;/abbr&gt;'ов,
    так как они требуют много вычислительных ресурсов.&lt;/li&gt;
&lt;li&gt;Был добавлен буфер: колонки в таблицах типа &lt;code&gt;varchar(4000)&lt;/code&gt;, в
    которых данные помещались изначально. При полном заполнении
    ячейки данные перемещаются в &lt;abbr title="Character Large OBject"&gt;CLOB&lt;/abbr&gt;; это позволило
    на порядок сократить количество их обновлений.&lt;/li&gt;
&lt;li&gt;Уменьшен размер самих сообщений об обновлениях.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="i-naposledok-paru-sovetov-ot-linkedin"&gt;И напоследок пару советов от LinkedIn&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;нельзя бесконечно долго ограничиваться одной базой данных:
    используйте много баз данных как с вертикальным, так и с
    горизонтальным сегментированием данных;&lt;/li&gt;
&lt;li&gt;забудьте о ссылочной целостности и кросс-серверных JOIN'ах;&lt;/li&gt;
&lt;li&gt;забудьте о 100% целостности данных;&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;h3 id="ps"&gt;P.S.&lt;/h3&gt;
&lt;p&gt;Когда уже закончил переводить в голову пришла мысль, что если читателям
будет интересно взглянуть на оригинальные презентации (хотябы ради
иллюстрационного материала, который там вполне нагляден), то было бы
проще сделать это прямо здесь, так что вот, для Вашего же удобства:&lt;/p&gt;
&lt;div class="video-container"&gt;&lt;iframe allowfullscreen="" frameborder="0" height="355" marginheight="0" marginwidth="0" scrolling="no" src="//www.slideshare.net/slideshow/embed_code/key/uHbsRNnQFZwThD" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" width="425"&gt; &lt;/iframe&gt;&lt;/div&gt;
&lt;div class="video-container"&gt;&lt;iframe allowfullscreen="" frameborder="0" height="355" marginheight="0" marginwidth="0" scrolling="no" src="//www.slideshare.net/slideshow/embed_code/key/16CML2N96CDeWv" style="border:1px solid #CCC; border-width:1px; margin-bottom:5px; max-width: 100%;" width="425"&gt; &lt;/iframe&gt;&lt;/div&gt;
&lt;p&gt;&lt;strong&gt;&lt;em&gt;Кстати если Вы еще не успели подписаться на &lt;a href="/feed/"&gt;RSS&lt;/a&gt; - сейчас
самое время!&lt;/em&gt;&lt;/strong&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Thu, 11 Sep 2008 04:00:00 +0400</pubDate><guid>tag:www.insight-it.ru,2008-09-11:highload/2008/arkhitektura-linkedin/</guid><category>ActiveMQ</category><category>C++</category><category>EHcache</category><category>Java</category><category>Jetty</category><category>LinkedIn</category><category>Lucene</category><category>MySQL</category><category>Oracle</category><category>Solaris</category><category>Spring</category><category>Tomcat</category><category>архитектура</category><category>архитектура LinkedIn</category><category>Масштабируемость</category></item><item><title>Архитектура 37signals</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-37signals/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/7457badf/" rel="nofollow" target="_blank" title="http://www.37signals.com"&gt;37signals&lt;/a&gt; больше всего известны благодаря
выпуску в свет &lt;a href="/tag/ruby-on-rails/"&gt;Ruby on Rails&lt;/a&gt; грамотному его
использованию для запуска их очень популярных продуктов: Basecamp,
Highrise, Backpack и Campfire. RoR как обычно пытаются винить во всех
проблемах с производительностью, но 37signals казалось бы справляется с
большой нагрузкой, используя вполне разумное количество вычислительных
ресурсов.
&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/goto/23721415/" rel="nofollow" target="_blank" title="http://highscalability.com/37signals-architecture"&gt;статьи&lt;/a&gt;, автор -
&lt;a href="https://www.insight-it.ru/goto/f3f1b405/" rel="nofollow" target="_blank" title="http://highscalability.com/user/todd-hoff"&gt;Todd Hoff&lt;/a&gt;. Извиняюсь за не
сильно оригинальный контент (да и, как выяснилось, практически не
технической направленности), но на написание своих полноценных текстов у
меня последнее время все никак не хватает то креатива, то времени :( .&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/d744e02/" rel="nofollow" target="_blank" title="http://www.37signals.com/svn/posts/749-ask-37signals-numbers"&gt;Спросите 37signals:
    цифры?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/aed84967/" rel="nofollow" target="_blank" title="http://www.37signals.com/svn/posts/753-ask-37signals-how-do-you-process-credit-cards"&gt;Спросите 37signals: как вы работаете с кредитными
    картами?&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/df60cd7c/" rel="nofollow" target="_blank" title="http://www.37signals.com/svn/posts/759-behind-the-scenes-at-37signals-support"&gt;За сценой 37signals:
    поддержка.&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/61db4355/" rel="nofollow" target="_blank" title="http://www.37signals.com/svn/posts/772-ask-37signals-why-did-you-restart-highrise"&gt;Спросите 37signals: почему вы перезапустили
    Highrise?&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/memcached/"&gt;Memcached&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/xen/"&gt;Xen&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/amazon-s3/"&gt;Amazon S3&lt;/a&gt; для хранения изображений&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="statistika"&gt;Статистика&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;30 серверов: от простых однопроцессорных файловых серверов до
    восьмипроцессорных серверов приложений, в сумме около 100
    процессоров и 200 GB оперативной памяти.&lt;/li&gt;
&lt;li&gt;В планах диагональное масштабирование: уменьшение количества
    серверов до 16, но более производительных - в сумме 92 процессоров и
    230 GB RAM.&lt;/li&gt;
&lt;li&gt;Виртуализация средствами &lt;a href="/tag/xen/"&gt;Xen&lt;/a&gt; для более гибкого
    управления системой.&lt;/li&gt;
&lt;li&gt;Basecamp (управление проектами):&lt;ul&gt;
&lt;li&gt;2000000 пользователей с учетными записями&lt;/li&gt;
&lt;li&gt;13200000 задач&lt;/li&gt;
&lt;li&gt;9200000 сообщений&lt;/li&gt;
&lt;li&gt;12200000 комментариев&lt;/li&gt;
&lt;li&gt;5500000 записей о распределении времени&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Backpack (управление информацией для личного использования и малого
    бизнеса):&lt;ul&gt;
&lt;li&gt;Около миллиона страниц&lt;/li&gt;
&lt;li&gt;6800000 задач&lt;/li&gt;
&lt;li&gt;1500000 записей&lt;/li&gt;
&lt;li&gt;829000 фотографий&lt;/li&gt;
&lt;li&gt;370000 файлов&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Общая статистика проектов (на ноябрь 2007 г.):&lt;ul&gt;
&lt;li&gt;5.9 TB загруженных пользователями данных&lt;/li&gt;
&lt;li&gt;888 GB загружено (upload)&lt;/li&gt;
&lt;li&gt;2 TB скачано (download)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="arkhitektura"&gt;Архитектура&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Кэширование средствами &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt; уже используется,
    но они ищут способы более активно его применять. Позволяет достичь
    впечатляющих результатов в плане производительности.&lt;/li&gt;
&lt;li&gt;Методы для составления URL используются вместо ручного их
    составления.&lt;/li&gt;
&lt;li&gt;Используются стандартные ActiveRecord запросы, но при необходимости
    они используют и ручную настройку.&lt;/li&gt;
&lt;li&gt;Иногда они дорабатывают Rails, если сталкиваются с проблемами с
    производительностью.&lt;/li&gt;
&lt;li&gt;Amazon S3 используется для хранения данных, загруженных
    пользователями. Разработчики очень довольны результатами.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="rabota-s-kreditnymi-kartami"&gt;Работа с кредитными картами&lt;/h3&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; Кто-то определенно должен
    обрабатывать операции с кредитными картами. Они используют Chase
    Bank. Воспользуйтесь услугами кого-нибудь, кому вы доверяете, а
    когда масштаб ваших сделок станет существенным - будет возможность
    получить более выгодные условия контракта.&lt;/li&gt;
&lt;li&gt;Они используют authorize.net в роли шлюза для процессинга операций с
    кредитными картами.&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;a href="https://www.insight-it.ru/goto/963f6a2d/" rel="nofollow" target="_blank" title="http://en.wikipedia.org/wiki/PCI_DSS"&gt;PCI DSS (Payment Card Industry Data
    Security Standard)&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Пользуйтесь услугами шлюзов, это позволит не хранить номера
    кредитных карт на своем сайте, что сильно упрощает жизнь в плане
    безопасности. Некоторые из них предоставляют и биллинговые услуги,
    что позволяет также не заниматься этим самостоятельно.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="podderzhka-polzovatelei"&gt;Поддержка пользователей&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Campfire используется для работы с клиентами. По сути эта система
    представляет собой групповой веб-чат с расширенными возможностями в
    виде опциональной защиты паролем, личных сообщений, обмена файлами,
    предпросмотра изображений, а также коллективного принятия решений.&lt;/li&gt;
&lt;li&gt;Поднимаемые вопросы используются для поиска ошибок в коде, а
    обновление данных в SVN отображается прямо в процессе общения.
    Bugtracking система обходится стороной, что казалось бы должно лишь
    усложнять исправление неполадок, например из-за отсутствия
    возможности проследить связь между конкретным изменением в коде и
    вызвавшей его неполадкой.&lt;/li&gt;
&lt;li&gt;Зато служба поддержки может решать проблемы клиентов с помощью
    общения в чате в реальном времени, с возможностью обмена
    изображениями и снимками экранов, демонстрирующими неисправность.&lt;/li&gt;
&lt;li&gt;Разработчики также всегда доступны с помощью Campfire для помощи в
    решении проблем клиентов.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="podvodim-itogi"&gt;Подводим итоги&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Возьмите пример с &lt;a href="/tag/amazon/"&gt;Amazon&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;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Thu, 05 Jun 2008 18:49:00 +0400</pubDate><guid>tag:www.insight-it.ru,2008-06-05:highload/2008/arkhitektura-37signals/</guid><category>Amazon S3</category><category>Memcached</category><category>MySQL</category><category>RoR</category><category>Ruby on Rails</category><category>Xen</category><category>архитектура</category><category>архитектура 37signals</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><item><title>Архитектура LiveJournal</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-livejournal/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/e53eaf70/" rel="nofollow" target="_blank" title="http://www.livejournal.com"&gt;LiveJournal&lt;/a&gt; был одним из первых сервисов,
бесплатно предоставляющих всем желающим личный блог. Практически с
самого начала своего существования в далеком 1999 году проект столкнулся
с непрерывно растущим потоком желающих воспользоваться услугами сервиса.
Как же проекту удалось справиться с предоставлением маленького кусочка
интернета каждому желающему, обойдя при этом всех конкурентов?
&lt;!--more--&gt;&lt;/p&gt;
&lt;h3 id="istochniki-informatsii"&gt;Источники информации&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Возможно Вы ожидали увидеть здесь очередной перевод статьи с
английского, но тогда придется Вас разочаровать, на этот раз я решил
попробовать свои силы в самостоятельном написании статьи на такую
серьезную тему. Просьба особо сильно помидорами в меня не кидаться :)&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Основным источником информации послужила &lt;a href="https://www.insight-it.ru/goto/a945bdaf/" rel="nofollow" target="_blank" title="http://video.google.com/videoplay?docid=-8953828243232338732"&gt;презентация Brad Fitzpatrick&lt;/a&gt;
в Токио.&lt;/p&gt;
&lt;h3 id="platforma"&gt;Платформа&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; (&lt;a href="/tag/debian/"&gt;Debian Sarge&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/perl/"&gt;Perl&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/mysql/"&gt;MySQL&lt;/a&gt; 4.0/4.1 в основном с InnoDB&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/perlbal/"&gt;Perlbal&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/mogilefs/"&gt;MogileFS&lt;/a&gt;, распределенная файловая система&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/gearman/"&gt;Gearman&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/theshwartz/"&gt;TheShwartz&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/djabberd/"&gt;djabberd&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="statistika"&gt;Статистика&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;на данный момент 15320315 учетных записей; &lt;em&gt;(10.04.08)&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;из них активно используется 551589;&lt;/li&gt;
&lt;li&gt;наиболее активно сервис используется в США и Российской федерации, а
    2/3 пользователей - девушки и женщины;&lt;/li&gt;
&lt;li&gt;более 15 миллионов новых записей в блогах за месяц;&lt;/li&gt;
&lt;li&gt;более 50 миллионов просмотров страниц в день, при пиковой нагрузке -
    несколько тысяч в секунду &lt;em&gt;(сильно устаревшие цифры, 2004 год);&lt;/em&gt;&lt;/li&gt;
&lt;li&gt;связь с внешним миром осуществляется через два BIG-IP (активный + в
    режиме ожидания) с автоматическим восстановлением работоспособности
    в случае сбоя в работе одного из них, защитой от DDoS, L7 набором
    правил, включая TCL;&lt;/li&gt;
&lt;li&gt;более сотни серверов, насчет конфигурации известен только тот факт,
    что практически на каждом сервере установлены огромные объемы
    оперативной памяти (более 12 GB) для эффективного кэширования.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="istoriia"&gt;История&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Все началось с одного обычного сервера. Он выполнял роль как
    веб-сервера так и базы данных. Единственный плюс такого подхода к
    организации работы оборудования - достаточно дешево. Само собой
    достаточно скоро этот сервер перестал справляться с нагрузкой.&lt;/li&gt;
&lt;li&gt;Следующим шагом было разнесение веб-сервера и базы данных на разные
    серверы, всего их получилось два. По прежнему имелось два узла, сбой
    в которых означал недоступность сервиса. По прежнему вычислительная
    мощность такой системы оставалась более чем скромной.&lt;/li&gt;
&lt;li&gt;Первым из тех двух серверов, как ни странно, перестал справляться с
    нагрузкой веб-сервер - докупили еще два. Веб-сервера три, внешний
    IP - один, теперь приходится как-то распределять нагрузку! А как
    добавить еще одну базу данных?&lt;/li&gt;
&lt;li&gt;Новый сервер баз данных был подключен в роли slave к исходному,
    данные в нем обновлялись с помощью репликации, а обрабатывал он
    только операции чтения, оставив все операции записи первому серверу.&lt;/li&gt;
&lt;li&gt;Есть предположения о том, к чему привело дальнейшее добавление новых
    серверов? Правильно - к полнейшему хаосу! Со временем стала
    возникать проблема масштабируемости баз данных. Операции чтения
    производились на каком-то одном сервере, но когда приходил запрос на
    запись данных, так или иначе данные приходилось производить
    обновление на каждом из slave серверов. В итоге выполнение
    синхронизации данных стало занимать подавляющее большинство
    процессорного времени slave серверов, что привело к отсутствию
    возможности продолжать масштабирование просто добавлением
    дополнительных серверов.&lt;/li&gt;
&lt;li&gt;Пришло время задуматься над архитектурой системы и распределением
    операций записи. Основной целью стало избавиться от такой серьезной
    избыточности данных, так как это было практически пустой тратой
    времени копировать одни и те же данные на десяток машин, да еще и с
    RAID на каждой из них.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Наиболее эффективным подходом в такой ситуации является
сегментирование базы данных. Все серверы баз данных разбиваются на
небольшие кластеры. Каждый пользователь системы прозрачно
привязывается к определенному кластеру, таким образом когда он
обновляет свой блог или какие-либо еще данные, запись ведется в
рамках только небольшой группы серверов, такой же принцип справедлив
и для чтения.&lt;/p&gt;
&lt;p&gt;Применительно к LiveJournal эту схему лучше всего демонстрирует один
из слайдов презентации, указанной в источниках информации:
&lt;img alt="Сегментирование базы данных в Livejournal" class="responsive-img" src="https://www.insight-it.ru/images/lj-scheme.jpeg" title="Механизм работы сегментированной базы данных в LiveJournal"/&gt;&lt;/p&gt;
&lt;p&gt;При работе такой системы не используется &lt;code&gt;auto_increment&lt;/code&gt; в
&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;, а также используется составной primary key из
номера пользователя и номера записи. Таким образом пространство имен
объектов разбито на группы, соответствующие конкретному
пользователю.&lt;/p&gt;
&lt;p&gt;Дальнейшим развитием решения проблемы излишней избыточности данных
может послужить отказ от кластеров, аналогичных по структуре
исходному для хранения сегментов базы данных. Это может быть как
вариант с общим на несколько серверов хранилищем данных, так и более
низкоуровневая репликация данных средствами &lt;abbr title="Distributed Replicated Block Device"&gt;DRBD&lt;/abbr&gt; в
совокупности с HeartBeat. Каждый из возможных вариантов
кластеризации MySQL имеет массу положительных и отрицательных
сторон, так что конкретного лидера среди них выделить достаточно
сложно. Возможно именно это и подтолкнуло разработчиков построить
собственное решение, комбинируя их с целью получения наилучшего
эффекта.&lt;/p&gt;
&lt;h3 id="programmnoe-obespechenie"&gt;Программное обеспечение&lt;/h3&gt;
&lt;p&gt;В ситуации, когда не удавалось найти готового программного решения для
какой-то конкретной задачи, они не боялись взяться за написание его
самостоятельно, это стало одним из основных компонентов успеха проекта.
Существенная часть программной платформы LiveJournal написана специально
для этого проекта и выпущено под свободной лицензией с открытым исходным
кодом, доступным в &lt;a href="https://www.insight-it.ru/goto/f135e7bd/" rel="nofollow" target="_blank" title="http://code.sixapart.com/"&gt;официальном SVN репозитории&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;memcached&lt;/h4&gt;
&lt;p&gt;Залогом быстрой загрузки любой страницы крупного интернет-проекта
является кэширование. Но как всегда возникает вопрос: а на каком уровне
обработки данных его стоит выполнять? Для динамических страниц
недопустимо кэширование на уровне готовых страниц. Можно кэшировать на
уровне &lt;code&gt;mod_perl&lt;/code&gt;, но по сути это пустая трата оперативной памяти, так
как создастся отдельный кэш для каждого потока &lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt;, и
количество промахов мимо кэша будет огромно. Кэширование запросов MySQL
или HEAP таблицы также не дали бы требуемого результата ввиду
чрезвычайной распределенности базы данных.&lt;/p&gt;
&lt;p&gt;Выходом из сложившейся ситуации стало написание собственной
распределенной системы кэширования объектов, получившей название
&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;. Она позволяет:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;использовать для кэширования свободную оперативную память
    практически любого компьютера, задействованного в системе;&lt;/li&gt;
&lt;li&gt;кэшировать объекты практически любого языка программирования в
    сериализованном виде: &lt;a href="/tag/perl/"&gt;Perl&lt;/a&gt;, &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt;,
    &lt;a href="/tag/java/"&gt;Java&lt;/a&gt;, &lt;a href="/tag/c/"&gt;C++&lt;/a&gt; и так далее;&lt;/li&gt;
&lt;li&gt;использовать для передачи кэшируемых данных простой протокол, не
    требующий избыточности данных;&lt;/li&gt;
&lt;li&gt;избегать даже теоретической возможности полного сбоя работы
    кэшируещей системы в связи с полной равнозначностью серверов;&lt;/li&gt;
&lt;li&gt;достигать превосходной производительности при формировании HTML-кода
    страниц;&lt;/li&gt;
&lt;li&gt;в разы снизить нагрузку на базы данных в проекте любого масштаба.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Этот продукт на практике оказался более чем эффективен, о чем
свидетельствует его более чем успешное использование во многих
крупнейших веб-проектах.&lt;/p&gt;
&lt;h4&gt;Perlbal&lt;/h4&gt;
&lt;p&gt;При решении вопроса, связанного с балансировкой нагрузки между
веб-серверами, пришлось перепробовать далеко не один десяток готовых
решений, но, к сожалению, ни один из них не смог удовлетворить все
потребности проекта. Не растерявшись, разработчики написали свое решение
этой задачи и назвали его &lt;a href="/tag/perlbal/"&gt;Perlbal&lt;/a&gt;. Конкурентов у него
множество, начиная от решений на уровне оборудования, например от
Foundry, заканчивая proxy балансировщиками нагрузки встроенные в более
популярные веб-сервера, но, тем не менее, продукт получился достаточно
конкурентноспособным. Он удовлетворял всем требованиям, выдвигаемым
разработчиками проекта:&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;может выступать как в роли reverse proxy, так и балансировщика
    нагрузки;&lt;/li&gt;
&lt;li&gt;базовый функционал классического веб-сервера;&lt;/li&gt;
&lt;li&gt;реализация внутреннего перенаправления данных;&lt;/li&gt;
&lt;li&gt;поддержка некоторых менее существенных трюков, реализованных обычно
    в виде plug-in'ов.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="/tag/perlbal/"&gt;Perlbal&lt;/a&gt; не так активно используется вне LiveJournal, по
сравнению с &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;, но для решения конкретной
задачи он подошел как нельзя лучше.&lt;/p&gt;
&lt;h4&gt;MogileFS&lt;/h4&gt;
&lt;p&gt;Идея распределенных файловых систем далеко не нова, достаточно вспомнить
лишь &lt;a href="/tag/gfs/"&gt;GFS&lt;/a&gt; или любой ее opensource аналог. Сам факт создания
такой системы был очень легок, изначальная версия была написана за одни
выходные, но при доведении ее до требуемого уровня качества пришлось
попотеть. Решение о ее создании было развитием идеи распределения
операций записи. Общая принцип хранения файлов прост: каждый файл в ФС
относится к определенному классу файлов, который определяет все правила
работы с файлом, в основном механизм его реплицирования, об остальном
заботится сама система.&lt;/p&gt;
&lt;p&gt;Как и все файловые системы этого класса,
&lt;acronym title="oMgFileS"&gt;MogileFS&lt;/acronym&gt; работает на уровне
пользовательских приложений и использует достаточно тривиальные протокол
передачи данных и общую архитектуру: клиенты, управляющие серверы,
абстрактные базы данных, сервера для хранения самих данных - в этом
плане ничего нового придумано не было. Доступ к файлам осуществляется с
помощью HTTP-запросов PUT/GET либо через виртуальный NFS-раздел.
Единственной особенностью можно назвать уклон в построение собой
абстрактной прослойки между приложением и собственно кластером базы
данных (в случае LiveJournal - сегмента), используемой в роли
альтернативы более тривиальной master/slave схемы.&lt;/p&gt;
&lt;h4&gt;Gearman&lt;/h4&gt;
&lt;p&gt;&lt;acronym title="manaGer"&gt;Gearman&lt;/acronym&gt; по сути прост до безобразия,
но это не мешает ему быть чрезвычайно эффективным. Возможно Вы уже
догадались в чем суть этого еще одного продукта, написанного специально
для LJ, если уже навели курсор на акроним в начале этого абзаца, если же
нет - поясню: он управляет общей работой системы средствами
клиент-серверной архитектуры и высокопроизводительного бинарного
протокола. С их помощью он способен удаленно вызывать практически любые
процедуры на удаленных серверах с минимальными задержками во времени.
Казалось бы ничего особенного он сам по себе не делает, но на самом деле
он выполняет очень важную функцию: увеличивает степень параллельности
выполнения операций, необходимых для полноценного функционирования
проекта. Единственное &lt;strong&gt;но&lt;/strong&gt; в работе этого механизма заключается в том,
что он не предоставляет никаких гарантий успешности выполнения работ.&lt;/p&gt;
&lt;p&gt;В рамках LiveJournal &lt;acronym title="manaGer"&gt;Gearman&lt;/acronym&gt;
применяется в основном для:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;обработка изображений средствами Image::Magick вне perl-приложений;&lt;/li&gt;
&lt;li&gt;создание pool'а DBI соединений (DBD::Gofer + Gearman);&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;h4&gt;TheShwartz&lt;/h4&gt;
&lt;p&gt;В качестве альтернативы gearman'у для работ, для выполнения которых
необходимы некоторые гарантии успешности, а также некоторая
стабильность, была разработана эта библиотека. Общая схема работы
осталась та же: клиент-серверная, но за стабильность приходится
платить - производительность существенно ниже, возможно возникновение
задержек.&lt;/p&gt;
&lt;p&gt;Хоть эти два продукта и выполняют схожие функции, используются они
обычно в совокупности друг с другом, просто-напросто обрабатывая разные
типы работ.&lt;/p&gt;
&lt;p&gt;Основными сферами применения TheShwartz в LJ являются:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;отправка электронной почты (SMTP клиент);&lt;/li&gt;
&lt;li&gt;LJ Notifications: каждое событие может вызывать за собой цепочку из
    тысяч уведомлений по электронной почте, SMS, XMPP и так далее;&lt;/li&gt;
&lt;li&gt;отправка RPC сообщений внешним сервисам;&lt;/li&gt;
&lt;li&gt;внедрение Atom потоков;&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;djabberd&lt;/h4&gt;
&lt;p&gt;Как всегда следуя принципу "чем проще - тем лучше", разработки LJ
написали этот крошечный daemon, лежащий в основе их Jabber/LJTalk. Он
способен спокойно работать с более чем 300 тысячами соединений,
используя очень скромное количество оперативной памяти для поддержания
каждого соединения.&lt;/p&gt;
&lt;p&gt;Основной причиной для написания собственного Jabber-сервера, стало
недостаточная расширяемость и масштабируемость существующих решений.
Была необходимость в реализации многих нестандартных функций, вроде
индивидуальных обработчиков пользовательских изображений и личных
данных, обычно в других решениях было доступно только изменение методов
аутентификации.&lt;/p&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;Распределение нагрузок и параллельное операций порой заслуживают
    того, чтобы разработчики обратили на них внимание;&lt;/li&gt;
&lt;li&gt;"Мы ненавидим изобретать колесо! Но тем не менее, если колесо не
    существует или оно квадратное, то мы не боимся изобретать круглое
    колесо." (с)&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Thu, 10 Apr 2008 00:24:00 +0400</pubDate><guid>tag:www.insight-it.ru,2008-04-10:highload/2008/arkhitektura-livejournal/</guid><category>Apache</category><category>Debian</category><category>djabberd</category><category>gearman</category><category>Memcached</category><category>MogileFS</category><category>MySQL</category><category>opensource</category><category>Perl</category><category>Perlbal</category><category>TheShwartz</category><category>архитектура</category><category>архитектура LiveJournal</category><category>Масштабируемость</category></item><item><title>Архитектура Digg</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-digg/</link><description>&lt;p&gt;Трафик, генерируемый более чем 1.2 миллионами пользователей
&lt;a href="https://www.insight-it.ru/goto/e072c5ff/" rel="nofollow" target="_blank" title="http://www.digg.com"&gt;Digg&lt;/a&gt;, знаменитых своей жаждой информации,
способен загнать любой невинный сайт за рамки его вычислительных
ресурсов и пропускной способности канала. Как же сам Digg справляется с
такой нагрузкой?
&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/goto/83eb8e27/" rel="nofollow" target="_blank" title="http://highscalability.com/digg-architecture"&gt;статьи&lt;/a&gt;, автор - &lt;a href="https://www.insight-it.ru/goto/f3f1b405/" rel="nofollow" target="_blank" title="http://highscalability.com/user/todd-hoff"&gt;Todd
Hoff&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/3c9da0db/" rel="nofollow" target="_blank" title="http://www.computerworld.com/action/article.do?command=viewArticleBasic&amp;amp;articleId=9017778"&gt;Как Digg.com использует LAMP для масштабирования&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/fa3d3949/" rel="nofollow" target="_blank" title="http://www.oreillynet.com/onlamp/blog/2006/04/digg_phps_scalability_and_perf.html"&gt;Масштабируемость и производительность PHP в Digg&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/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/php/"&gt;PHP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/lucene/"&gt;Lucene&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/apc/"&gt;APC PHP Accelerator&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;Проект стартовал в конце 2004 года на одном сервере под управлением
    &lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; с использованием &lt;a href="/tag/apache/"&gt;Apache 1.3&lt;/a&gt;, &lt;a href="/tag/php/"&gt;PHP
    4&lt;/a&gt; и &lt;a href="/tag/mysql/"&gt;MySQL 4.0&lt;/a&gt; (со стандартной системой
    хранения данных - MyISAM).&lt;/li&gt;
&lt;li&gt;Более 1.2 миллиона пользователей.&lt;/li&gt;
&lt;li&gt;Более 200 миллионов просмотров страниц в месяц.&lt;/li&gt;
&lt;li&gt;100 серверов расположены в нескольких датацентрах, из них:
    &amp;ndash; 20 серверов баз данных;
    &amp;ndash; 30 веб-серверов;
    &amp;ndash; несколько поисковых серверов, использующих Lucene;
    &amp;ndash; остальные используются для обеспечения избыточности.&lt;/li&gt;
&lt;li&gt;30 GB данных.&lt;/li&gt;
&lt;li&gt;Ни одна из проблем, с которыми пришлось столкнуться проекту не была
    связана с &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt;, в основном они касались базы данных.&lt;/li&gt;
&lt;li&gt;Легковесная природа &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; позволила переместить
    вычислительные работы из базы данных в приложение для улучшения
    производительности.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="chto-vnutri"&gt;Что внутри?&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Балансировщик нагрузки равномерно распределяет запросы между
    &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; серверами.&lt;/li&gt;
&lt;li&gt;MySQL используется по принципу master-slave:
    -&amp;nbsp; Сервера, обрабатывающие большое количество транзакций, используют
    движок InnoDB.
    -&amp;nbsp; Сервера, выполняющие аналитическую обработку данных в реальном
    времени, используют MyISAM.
    -&amp;nbsp; Снижения производительности при переходе с &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt; 4.1
    на версию 5 замечено не было.&lt;/li&gt;
&lt;li&gt;Для кэширования используется &lt;a href="/tag/memcached/"&gt;Memcached&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Используется сегментирование баз данных.&lt;/li&gt;
&lt;li&gt;Особенности использования Digg существенно облегчают процесс
    масштабирования. Большинство посетителей просто просматривают
    главную страницу и уходят. Это приводит к тому, что 98% запросов к
    базе данных являются операциями чтения. Такое соотношение операций
    чтения и записи позволяет не беспокоиться о комплексной работе по
    проектированию операций записи, что позволяет намного проще
    масштабировать проект.&lt;/li&gt;
&lt;li&gt;Возникали проблемы, связанные с системой хранения данных, которые
    сообщали, что данные уже записаны на диск, когда на самом деле это
    было не так. Контроллеры делали это для создания впечатления более
    высокой производительности. Но на практике это приводило лишь к
    проблемам с целостностью данных. Это достаточно распространенная
    проблема, которую порой не так уж просто решить, правда все зависит
    от используемого оборудования.&lt;/li&gt;
&lt;li&gt;Для облегчения нагрузки на базы данных используется кэширование и
    &lt;a href="/tag/apc/"&gt;APC PHP Accelerator&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;С использованием рабочих потоков &lt;a href="/tag/apache/"&gt;Apache2&lt;/a&gt;, FastCGI и
    &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; акселератора возможно избежать необходимости каждый
    раз заново интерпретировать и компилировать PHP скрипты: скрипт
    компилируется только при первом обращении, что существенно ускоряет
    скорость его выполнения при последующих обращениях.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="podvodim-itogi"&gt;Подводим итоги&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Используйте возможность выбора движка для &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;. Если
    Вам нужны транзакции - используйте InnoDB, если нет - MyISAM.
    Например, если на master сервере расположены транзакционные таблицы,
    то для slave серверов можно использовать и MyISAM.&lt;/li&gt;
&lt;li&gt;В определенный момент рост стал невозможен путем добавления
    дополнительной оперативной памяти, пришлось продолжать рост путем
    изменения архитектуры.&lt;/li&gt;
&lt;li&gt;Люди часто жалуются, что Digg медлителен. Скорее это вызвано их
    огромными &lt;a href="/tag/javascript/"&gt;JavaScript&lt;/a&gt; библиотеками, чем работой их
    серверной системы.&lt;/li&gt;
&lt;li&gt;Стоит тщательно выбирать какие именно приложения развертывать. Они
    приложили все усилия, чтобы не использовать приложения, требующие
    больших вычислительных мощностей. Очевидно, что Digg работает на
    совершенно стандартной &lt;a href="/tag/lamp/"&gt;LAMP&lt;/a&gt; архитектуре, но тем не
    менее реализована она достаточно интересно. У инженеров часто
    возникает желание реализовать какой-либо дополнительный функционал,
    но всегда стоит иметь ввиду, что они могут разрушить инфраструктуру,
    если она не сможет расти теми же темпами. Так что с этим стоит
    повременить до тех пор пока система сможет выдерживать все
    необходимые нагрузки. Это приводит к планированию ресурсов, особенно
    большое внимание этому аспекту уделяет &lt;a href="/tag/flickr/"&gt;Flickr&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Вам остается лишь догадываться, сможет ли &lt;a href="/tag/digg/"&gt;Digg&lt;/a&gt; удержать
    свои позиции, если и дальше будет ограничивать добавление новых
    возможностей, или уступит более активно развивающимся сервисам
    социальных закладок? Возможно если бы была возможность увеличивать
    масштабы более простыми методами, более быстрое добавление новых
    функций и возможностей позволило бы более эффективно конкурировать
    на этом рынке? С другой стороны, просто добавление новых
    возможностей может и не поменять ситуацию кардинальным образом.&lt;/li&gt;
&lt;li&gt;Основные проблемы с масштабируемостью и производительностью связаны
    с обработкой данных и в большинстве случаев они не зависят от
    используемого языка программирования. Вы столкнетесь с ними при
    работе с &lt;a href="/tag/java/"&gt;Java&lt;/a&gt;, &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt;, &lt;a href="/tag/ruby/"&gt;Ruby&lt;/a&gt;, или
    подставьте сюда Ваш любимый язык программирования.&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Tue, 01 Apr 2008 20:49:00 +0400</pubDate><guid>tag:www.insight-it.ru,2008-04-01:highload/2008/arkhitektura-digg/</guid><category>APC</category><category>Digg</category><category>LAMP</category><category>Linux</category><category>Lucene</category><category>Memcached</category><category>MySQL</category><category>online</category><category>PHP</category><category>архитектура</category><category>архитектура Digg</category><category>интернет</category></item><item><title>Архитектура Wikimedia</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-wikimedia/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/687b5b81/" rel="nofollow" target="_blank" title="http://wikimedia.org"&gt;Wikimedia&lt;/a&gt; является платформой для
&lt;a href="https://www.insight-it.ru/goto/35f4fea7/" rel="nofollow" target="_blank" title="http://wikipedia.org"&gt;Wikipedia&lt;/a&gt;, &lt;a href="https://www.insight-it.ru/goto/389e980c/" rel="nofollow" target="_blank" title="http://wiktionary.org"&gt;Wiktionary&lt;/a&gt; и
еще семи менее крупных wiki-проектов. Этот документ очень пригодится
новичкам, пытающимся довести свои проекты до масштабов гигантских
вебсайтов. Здесь можно найти множество интересных деталей и
инновационных идей, которые уже успели доказать свою работоспособность
на самых посещаемых сайтах всего Интернета.
&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/goto/cd47c021/" rel="nofollow" target="_blank" title="http://highscalability.com/wikimedia-architecture"&gt;статьи&lt;/a&gt;.
Автор - &lt;a href="https://www.insight-it.ru/goto/f3f1b405/" rel="nofollow" target="_blank" title="http://highscalability.com/user/todd-hoff"&gt;Todd Hoff&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/c8e5f8d0/" rel="nofollow" target="_blank" title="http://www.nedworks.org/~mark/presentations/san/Wikimedia%20architecture.pdf"&gt;Архитектура Wikimedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/62eceab/" rel="nofollow" target="_blank" title="http://meta.wikimedia.org/wiki/Wikimedia_servers"&gt;Серверы Wikimedia&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/c56ad62f/" rel="nofollow" target="_blank" title="http://oracle2mysql.wordpress.com/2007/08/22/12/"&gt;scale-out vs scale-up&lt;/a&gt; из блога "Oracle to MySQL"&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="platforma"&gt;Платформа&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/linux/"&gt;Linux&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/php/"&gt;PHP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/lvs/"&gt;LVS&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/lucene/"&gt;Lucene&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/lighttpd/"&gt;lighttpd&lt;/a&gt; для работы с изображениями&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="statitstika"&gt;Статитстика&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;8 миллионов статей распределены по сотням языковых подпроектов
    (английские, голландские, ...)&lt;/li&gt;
&lt;li&gt;В десятке самых высоконагруженных проектов по данным
    &lt;a href="https://www.insight-it.ru/goto/3b390e59/" rel="nofollow" target="_blank" title="http://alexa.com"&gt;Alexa&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Экспоненциальный рост: в терминах посетителей, трафика и серверов
    удвоение происходит каждые 4-6 месяцев&lt;/li&gt;
&lt;li&gt;30000 HTTP запросов в секунду в периоды пиковой нагрузки&lt;/li&gt;
&lt;li&gt;3 GBps трафик данных&lt;/li&gt;
&lt;li&gt;3 датацентра: Тампа, Амстердам, Сеул&lt;/li&gt;
&lt;li&gt;350 серверов, конфигурации варьируются от однопроцессорных Pentium 4
    с 512 MB оперативной памяти до двухпроцессорных Xeon Quad-Core с 16
    GB RAM.&lt;/li&gt;
&lt;li&gt;Управляется ~6 людьми&lt;/li&gt;
&lt;li&gt;Три кластера на трех разных континентах&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="arkhitektura"&gt;Архитектура&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Географическая балансировка нагрузки, основываясь на IP клиента,
    перенаправляет их на ближайший кластер. Происходит статическое
    отображение множества IP адресов на множество стран, а затем и на
    множество кластеров.&lt;/li&gt;
&lt;li&gt;Кэширование с помощью &lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt; группируется по типу
    контента: текст для wiki отдельно от изображений и больших
    статических файлов.&lt;/li&gt;
&lt;li&gt;На данный момент функционирует 55 &lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt; серверов, плюс
    еще 20 подготавливается к запуску.&lt;/li&gt;
&lt;li&gt;1000 HTTP запросов в секунду на каждый сервер, в периоды повышенной
    нагрузки эта цифра может достигать 2500.&lt;/li&gt;
&lt;li&gt;~ 100-250 MBps на сервер.&lt;/li&gt;
&lt;li&gt;~ 14000-32000 открытых соединений на каждом сервере.&lt;/li&gt;
&lt;li&gt;До 40 GB дискового кэша на каждом Squid сервере.&lt;/li&gt;
&lt;li&gt;До 4 дисков в каждом сервере (1U серверы).&lt;/li&gt;
&lt;li&gt;8 GB оперативной памяти, половину использует &lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/e669c01a/" rel="nofollow" target="_blank" title="http://www.powerdns.com"&gt;PowerDNS&lt;/a&gt; предоставляет геораспределение.&lt;/li&gt;
&lt;li&gt;В основном и региональных датацентрах текстовые и медиа кластеры
    построены на &lt;a href="/tag/lvs/"&gt;LVS&lt;/a&gt;,
    &lt;abbr title="Common Address Redundancy Protocol"&gt;CARP&lt;/abbr&gt;
&lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt;, кэш &lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt;. В основном датацентре
    также находится хранилище медиа-данных.&lt;/li&gt;
&lt;li&gt;Для того, чтобы обеспечить предоставление только последних версий
    страниц, всем Squid-серверам отправляются инвалидационные запросы.&lt;/li&gt;
&lt;li&gt;Централизованно управляемая и синхронизированная установка
    программного обеспечения для сотен серверов.&lt;/li&gt;
&lt;li&gt;MediaWiki отлично масштабируется с несколькими процессорами, так что
    закупаются двухпроцессорный четырех ядерные серверы (8 ядер на
    сервер).&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/memcached/"&gt;Memcached&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;Один master и много реплицированных slave серверов.&lt;/li&gt;
&lt;li&gt;Операции чтения равномерно распределяются по slave серверам,
    операции записи направляются на master.&lt;/li&gt;
&lt;li&gt;Иногда master используется и для операция чтения, когда репликация
    на slave еще не завершена.&lt;/li&gt;
&lt;li&gt;Внешнее хранение данных:&lt;ul&gt;
&lt;li&gt;Текст статей хранится на отдельных кластерах, которые представляют
собой простой средство хранения данных с возможностью только
дописывания новых данных. Такой подход позволяет сохранить
дорогостоящее место в высоконагруженных основных базах данных от
редко используемой информации.&lt;/li&gt;
&lt;li&gt;Благодаря этому появляются дополнительные неиспользованные ресурсы
на серверах приложений (порой 250-500 GB на сервер).&lt;/li&gt;
&lt;li&gt;На данной момент используются реплицируемые кластеры из 3
&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt; серверов, но в будущем это может измениться, так
как требуется более удобное управление ими.&lt;/li&gt;
&lt;/ul&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;Старайтесь избегать сложных алгоритмов, запросов к базе данных и
    тому подобного.&lt;/li&gt;
&lt;li&gt;Кэшируйте каждый результат, который дорого вам обошелся и является
    относительно локальным.&lt;/li&gt;
&lt;li&gt;Сфокусируйтесь на "горячих точках" в коде.&lt;/li&gt;
&lt;li&gt;Масштабируйтесь разделением:&lt;ul&gt;
&lt;li&gt;операций чтения и записи (master/slave);&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;/li&gt;
&lt;li&gt;Казалось бы простые вызовы библиотечных функций порой на практике
    могут занимать слишком много времени.&lt;/li&gt;
&lt;li&gt;Скорость поиска данных на диске ограничена, так что чем больше
    дисков - тем лучше!&lt;/li&gt;
&lt;li&gt;Масштабирование с использованием обычного оборудование не означает
    использование самых дешевых вещей, которые удастся найти. Серверы
    баз данных Wikipedia сегодня представляют собой 16GB RAM, двух- или
    четырех-ядерные серверы с 6 15000 rpm SCSI дисками, организованными
    в RAID 0. Возможно они бы и использовали более дешевые системы, но
    16 GB как раз хватает для размещения основного объема данных, а
    остальное берут на себя жесткие диски, это вполне соответствует
    потребностям системы, которую они построили. Примерно по таким же
    причинам их веб-сервера имеют 8 ядер, так как это позволяет достичь
    неплохой производительности &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; при достаточно простой
    организации балансировки нагрузки.&lt;/li&gt;
&lt;li&gt;Для масштабирования требуется выполнение массы работы, но если
    заранее этого не предусмотреть - понадобится сделать еще больше.
    MediaWiki изначально была написана для одного master сервера баз
    данных. Затем добавилась поддержка slave. Затем добавилось
    распределение по языкам и проектам. Дизайн системы с тех пор
    прекрасно выдерживает все нагрузки, но без очистки от новых узких
    мест системы не обошлось.&lt;/li&gt;
&lt;li&gt;Каждый, кто хочет разработать свою базу данных таким образом, чтобы
    она позволила недорого масштабироваться с уровня одного сервера до
    уровня десятки лучших сайтов Интернета, должен начать с обработки
    слегка устаревших данных на реплицированных slave серверах, при этом
    не забывать балансировать нагрузку операций чтения между slave
    серверами. Если это возможно - блоки данных (группы пользователей,
    учетных записей, или чего угодно) должны размещаться каждый на
    разных серверах. Можно делать это с самого начала используя
    виртуализацию, чтобы удостовериться в работоспособности архитектуры,
    когда вы еще "маленькие". Это &lt;strong&gt;намного&lt;/strong&gt; проще, чем когда вы
    делаете то же самое, но под ежемесячно удваивающейся нагрузкой.&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Fri, 28 Mar 2008 15:32:00 +0300</pubDate><guid>tag:www.insight-it.ru,2008-03-28:highload/2008/arkhitektura-wikimedia/</guid><category>Apache</category><category>lighttpd</category><category>Linux</category><category>Lucene</category><category>LVS</category><category>Memcached</category><category>MySQL</category><category>PHP</category><category>Squid</category><category>архитектура</category><category>архитектура Wikimedia</category><category>геораспределение</category><category>Масштабируемость</category></item><item><title>Архитектура Friends for Sale</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-friends-for-sale/</link><description>&lt;p&gt;&lt;img alt="Friends for Sale Logo" class="right" src="https://www.insight-it.ru/images/friends-for-sale.png" title="Friends for Sale"/&gt;
За три коротких месяца &lt;em&gt;&lt;a href="https://www.insight-it.ru/goto/616a7ee4/" rel="nofollow" target="_blank" title="http://www.facebook.com/apps/application.php?id=7019261521"&gt;Friend for Sale&lt;/a&gt;&lt;/em&gt;
(рейтинговая система в условиях рыночной экономики) попала в десятку
лучших приложений &lt;em&gt;Facebook&lt;/em&gt;, непринужденно обрабатывая 200 запросов в
секунду и демонстрируя шокирующее количество просмотров страниц, за
месяц достигающее 300 миллионов просмотров. Все это дело рук двух
разработчиков, работающих не полный рабочий день, которые смогли создать
успешное веб-приложение, имея в своем распоряжении лишь кластер из
дюжины серверов и &lt;a href="/tag/ruby-on-rails/"&gt;Ruby on Rails&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Как Friends for Sale масштабируется для того, чтобы обеспечить торговлю
всеми этими красивыми людьми? Как Вы думаете, сколько стоят Ваши друзья
на открытом рынке?
&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/goto/2ee4cfe9/" rel="nofollow" target="_blank" title="http://highscalability.com/friends-sale-architecture-300-million-page-view-month-facebook-ror-app"&gt;оригиналу&lt;/a&gt;
и его &lt;a href="https://www.insight-it.ru/goto/f3f1b405/" rel="nofollow" target="_blank" title="http://highscalability.com/user/todd-hoff"&gt;автору&lt;/a&gt;. Продолжаем:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ответы на стандартный набор вопросов от Siqi Chen и Alexander Le,
    создателей Friends for Sale;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/2266d3f8/" rel="nofollow" target="_blank" title="http://highscalability.com/docs/EmergingTechSIGPresentation.pdf"&gt;Virality on Facebook&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/centos/"&gt;CentOS&lt;/a&gt; (64 bit)&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/capistrano/"&gt;Capistrano&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/mysql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/nginx/"&gt;nginx&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/starling/"&gt;Starling&lt;/a&gt; - распределенный сервер очередей&lt;/li&gt;
&lt;li&gt;Softlayer - хостинг&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/pingdom/"&gt;Pingdom&lt;/a&gt; - мониторинг&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/lvm/"&gt;LVM&lt;/a&gt; -   &lt;a href="https://www.insight-it.ru/goto/157d64d2/" rel="nofollow" target="_blank" title="http://magicmodels.rubyforge.org/magic_multi_connections/"&gt;Magic Multi-Connections Gem&lt;/a&gt; -
    разделение операций чтения и записи между серверами&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="statistika"&gt;Статистика&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Это Facebook приложение находится в десятке наиболее популярных;&lt;/li&gt;
&lt;li&gt;Около 600 тысяч активных пользователей;&lt;/li&gt;
&lt;li&gt;Полмиллиона уникальных посетителей ежедневно, и эта цифра неуклонно
    растет;&lt;/li&gt;
&lt;li&gt;Темпы роста проекта достигают 300% в месяц;&lt;/li&gt;
&lt;li&gt;200 запросов в секунду;&lt;/li&gt;
&lt;li&gt;5 TB трафика в месяц;&lt;/li&gt;
&lt;li&gt;Над проектом работают 2 разработчика и 1 админимтратор баз данных.&lt;/li&gt;
&lt;li&gt;4 сервера баз данных, 6 серверов приложений, 1 тестовый сервер и 1
    сервер для балансировки нагрузки:&lt;ul&gt;
&lt;li&gt;Каждый из серверов приложений содержит 4 ядра и 8 GB оперативной
памяти.&lt;/li&gt;
&lt;li&gt;На каждом из них работает 16 сервисов &lt;a href="/tag/mongrel/"&gt;mongrel&lt;/a&gt; (в
сумме - 96).&lt;/li&gt;
&lt;li&gt;4 GB оперативной памяти на каждом из них отведено под
&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Сервера баз данных имеют более серьезное оборудование: при тех же
4-х ядрах, они имеют 32 GB оперативной памяти и RAID 10 массив из
четырех 15000rpm SCSI дисков, работающих в режиме "master/slave".&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="davaite-znakomitsia"&gt;Давайте знакомиться&lt;/h3&gt;
&lt;h4&gt;Для чего нужна ваша система?&lt;/h4&gt;
&lt;p&gt;Наша система разработана в качестве платформы для нашего Facebook
приложения, Friends for Sale.
В целом оно представляет собой аналог рейтинговой системы
&lt;a href="https://www.insight-it.ru/goto/d7a8b770/" rel="nofollow" target="_blank" title="http://www.hotornot.com/"&gt;Hot-or-Not&lt;/a&gt; с некоторым добавлением рыночной
экономики. В момент проведения интервью это приложение было на 10-м
месте по популярности среди приложений Facebook.&lt;/p&gt;
&lt;p&gt;Описание этого приложения на самом Facebook гласит:&lt;/p&gt;
&lt;div class="card blue lighten-1"&gt;
&lt;div class="card-content white-text"&gt;
Покупайте и продавайте своих друзей как питомцев! Вы можете научить их
толкаться, отправлять подарки или просто представлять Вас в выгодном
свете.

Зарабатывайте как практичный инвестор в питомцев или как популярный
товар!
&lt;/div&gt;
&lt;/div&gt;
&lt;h4&gt;Почему вы решили построить эту систему?&lt;/h4&gt;
&lt;p&gt;Мы разработали ее скорее как эксперимент для того, чтобы проверить
удалось ли нам понять концепции и измерения вирусного эффекта в рамках
Facebook. Мне кажется нам это удалось. :)&lt;/p&gt;
&lt;h4&gt;С какими конкретными сложными задачами, связанными с дизайном, архитектурой или реализацией системы, вам пришлось столкнуться при построении системы?&lt;/h4&gt;
&lt;p&gt;Как и в любом Facebook приложении, каждый запрос является динамическим,
так что кэширование страниц невозможно. Так как приложение является
интерактивным, со множеством операций записи, определенные трудности
вызвало масштабирование базы данных.&lt;/p&gt;
&lt;h4&gt;Каковы были ваши&lt;/h4&gt;
&lt;p&gt;действия, направленные для решения этих задач?&lt;/p&gt;
&lt;p&gt;С самого начала мы активно использовали &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt; -
для перезагрузки страницы совсем не требуется выполнение SQL запросов. В
основном мы использовали кэширование фрагментов Rails с индивидуальной
логикой актуальности.&lt;/p&gt;
&lt;h4&gt;Как вы оцениваете размеры вашей системы?&lt;/h4&gt;
&lt;p&gt;Вчера статистика показала более полумиллиона уникальных посетителей, и
эта цифра неуклонно растет.
За этот месяц было зарегистрировано более 300 миллионов просмотров
страниц.&lt;/p&gt;
&lt;h4&gt;Каковы показатели использования пропускной способности интернет-канала?&lt;/h4&gt;
&lt;p&gt;В прошлом месяце было потрачено 3 терабайта трафика, но в этом месяце
ожидается цифра не меньше 5 терабайт. Эти цифры состоят по большей части
из XHTML / CSS и нескольких небольших иконок.&lt;/p&gt;
&lt;h4&gt;Как много документов используется в системе? Сколько изображений? Какой объем данных?&lt;/h4&gt;
&lt;p&gt;По большому счету у нас нет уникальных документов... но зато у нас есть
около 10 миллионов профилей пользователей.
Единственными используемыми изображениями являются несколько
статических иконок.&lt;/p&gt;
&lt;h4&gt;Как вы оцениваете темпы роста вашей системы?&lt;/h4&gt;
&lt;p&gt;Месяц назад за сутки просматривалось около трех миллионов страниц, на
данный момент эта цифра достигла 10 миллионов в сутки. Из чего можно
сделать вывод, что ориентировочные темпы роста проекта составляют 300% в
месяц. Если говорить о ежесекундной нагрузке, то на данный момент она
составляет около 200 запросов в секунду.&lt;/p&gt;
&lt;h4&gt;Какая часть посетителей платит вам за участие в вашем проекте?&lt;/h4&gt;
&lt;p&gt;Он абсолютно бесплатен для пользователей.&lt;/p&gt;
&lt;h4&gt;Каковы показатели "текучести" пользователей?&lt;/h4&gt;
&lt;p&gt;В среднем около 1% в сутки, с ежедневным ростом в 3% от этой цифры, если
говорить в терминах новых установок .&lt;/p&gt;
&lt;h4&gt;Как много учетных записей активно принимали участие в проекте за последний месяц?&lt;/h4&gt;
&lt;p&gt;По данным &lt;a href="/tag/google/"&gt;Google&lt;/a&gt; за последний месяц проект посетил 2.1
миллион уникальных пользоывтелей.&lt;/p&gt;
&lt;h4&gt;Какова архитектура вашей системы?&lt;/h4&gt;
&lt;p&gt;Она представляет собой относительно стандартный Rails кластер. В
качестве интерфейса между запросами пользователей и серверами приложений
используется proxy балансировщик нагрузки, который перенаправляет
запросы напрямую шести четырехядерным серверам приложений. На каждом
сервере приложений запущено 16 &lt;a href="/tag/mongrel/"&gt;mongrel&lt;/a&gt;'ов, что в сумме
дает 96. Балансировщик нагрузки перенаправляет запросы напрямую на порты
серверов &lt;a href="/tag/mongrel/"&gt;mongrel&lt;/a&gt;. В дополнение к этому на каждом сервере
приложений выделено 4 GB оперативной памяти под
&lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt;, а также работает локальный сервер
распределенного менеджера очередей &lt;a href="/tag/starling/"&gt;Starling&lt;/a&gt; и несколько
менее важных фоновых процессов.&lt;/p&gt;
&lt;p&gt;&lt;a href="/tag/subd/"&gt;СУБД&lt;/a&gt; работает на двух серверах (четыре ядра, 32 GB
оперативной памяти, четыре 15000rpm SCSI диска в RAID 10) в режиме
"master/slave". Для организации распределения операций чтения и записи
между серверами используется &lt;a href="https://www.insight-it.ru/goto/157d64d2/" rel="nofollow" target="_blank" title="http://magicmodels.rubyforge.org/magic_multi_connections/"&gt;Magic Multi-Connections Gem&lt;/a&gt; от Dr
Nic.&lt;/p&gt;
&lt;p&gt;На данный момент ведется работа над добавлением дополнительных серверов,
работающих в роли "slave", для обеспечения более эффективного
распределения нагрузки, избыточности и политик хранения запасных копий
данных. Помимо этого нам помогают Percona (ребята из
mysqlperformanceblog) с удаленной работой над архитектурой базы данных.&lt;/p&gt;
&lt;p&gt;Нашим хостинг-провайдером является Softlayer - он просто фантастический.
Основной проблемой был тот факт, что их балансировщик нагрузки не
справлялся со своей задачей ... поначалу у нас возникала масса проблем,
связанных с задержками и повисшими соединениями. Переход на отдельный
сервер с запущенным только nginx в режиме proxy балансировщика нагрузки
позволила решить все проблемы.&lt;/p&gt;
&lt;h4&gt;Каким образом планируется масштабировать архитектуру вашего проекта?&lt;/h4&gt;
&lt;p&gt;Каких-то конкретных планов нет. На уровне приложения система не
использует какие-либо общие ресурсы, так что все достаточно тривиально.
На уровне баз данных на данный момент все еще используется один сервер в
роли "master", но мы стараемся отложить неизбежный переход к
сегментированной базе данных на как можно более длительный срок. На
данный момент базы данных масштабируются вертикально, но со временем,
надеюсь, мы сможем от этого избавиться.&lt;/p&gt;
&lt;h4&gt;Назовите самые интересные уникальные факты о вашем проекте?&lt;/h4&gt;
&lt;p&gt;Я могу назвать:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Ни один из двух разработчиков ранее не имел опыта в крупномасштабных
    разработках на основе &lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Наша траектория роста проекта достаточно редка в истории разработок
    с использованием &lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;У нас практически не было возможностей для кэширования статических
    страниц - каждый запрос страницы приходилось обрабатывать
    &lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt;.&lt;/li&gt;
&lt;/ol&gt;
&lt;h4&gt;Чему вам удалось научиться? Каков залог вашего успеха? Чего бы вам хотелось сделать по-другому в прошлом, если бы была такая возможность? Что бы вы оставили как есть?&lt;/h4&gt;
&lt;p&gt;Отличные хостинг, оборудование и архитектура БД являются очень важными
факторами. Мы привыкли пользоваться услугами хостинга Railsmachine,
который честно говоря является отличным провайдером shared хостинга, но
со временем они потеряли возможность выдерживать необходимую нагрузку. В
итоге почти месяц мы были едва способны отвечать на запросы браузеров
из-за проблем с оборудованием, хотя последующий переход на Softlayer
занял всего два часа. Стоит заранее выбирать качественный хостинг, если
планируется масштабирование проекта, смена хостинг-провайдера - не очень
веселое занятие.&lt;/p&gt;
&lt;p&gt;Основным выводом, который нам удалось сделать, является тот факт, что
причиной проблемы с масштабированием практически всегда является база
данных. Все без исключений проблемы с производительностью в итоге
сводились к серверу баз данных, конфигурации СУБД, эффективности
запросов или решению вопроса насчет необходимости использования
индексов.&lt;/p&gt;
&lt;p&gt;Определенно нам нужен был более качественный хостинг намного раньше.&lt;/p&gt;
&lt;p&gt;Мы определенно не сменим наш framework - &lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt; был
незаменим при быстрой разработке приложения, нам удалось доказать, что
для масштабирования проекта на &lt;a href="/tag/ror/"&gt;RoR&lt;/a&gt; достаточно двух парней,
абсолютно не имеющих опыта в этом.&lt;/p&gt;
&lt;h4&gt;Кто входит в состав вашей команды?&lt;/h4&gt;
&lt;p&gt;У нас есть два разработчика, включая меня. Помимо этого недавно мы
начали пользоваться услугами помощи с DBA, о которой уже упоминалось.&lt;/p&gt;
&lt;h4&gt;Сколько всего людей участвует в проекте?&lt;/h4&gt;
&lt;p&gt;В технической части - два разработчика и один администратор баз данных,
работающий на контрактной основе.&lt;/p&gt;
&lt;h4&gt;Где они расположены с географической точки зрения?&lt;/h4&gt;
&lt;p&gt;Все участники проекта живут в районе SOMA, San Francisco.&lt;/p&gt;
&lt;h4&gt;Каковы обязанности каждого из участников проекта?&lt;/h4&gt;
&lt;p&gt;Оба разработчика проекта по совместительству являются и его создателями.
Поначалу я (Siqi) был ответственным за дизайн и разработку
пользовательского интерфейса, но так как у меня был некоторый опыт с
развертыванием систем я взял на себя и разработку управления сетевыми
операциями и развертывания. Мой коллега Alex был ответственным за
большую часть &lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt; кода, вся логика приложения - его рук
дело.&lt;/p&gt;
&lt;p&gt;На данный момент я по большей части занимаюсь более техническими
моментами, такими как оптимизация сетевых операций и работы и репликации
&lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt;. С трудом получается вернуться к работе над
пользовательским интерфейсом - к тому, что мне по-настоящему нравится.
Но это был опыт, который явно стоило получить, так что я стараюсь
извлекать максимум выгоды из этого занятия.&lt;/p&gt;
&lt;h4&gt;У вас есть какая-то определенная философия менеджмента?&lt;/h4&gt;
&lt;p&gt;Да - найти самых умелых и сообразительных людей, сделать им наилучшее
возможное предложение и убраться с их пути. Самые лучшие менеджеры
должны уметь НЕ МЕШАТЬ работникам, так что я стараюсь максимально этому
следовать при работе с другими участниками проекта. Но, к сожалению, мне
удается это далеко не всегда.&lt;/p&gt;
&lt;h4&gt;Если ваша команда работает раздельно, как вам удается координировать свою работу?&lt;/h4&gt;
&lt;p&gt;Нам стоило бы задуматься об использования каких-либо эффективных средств
общения. Мне кажется, что использование удаленной работа / outsourcing'а
является по-настоящему сложной задачей - я предпочитаю обходиться без
этого в разработке основы системы. Для системного администрирования или
разработки архитектуры БД это было бы более оправданно.&lt;/p&gt;
&lt;h3 id="chto-vy-ispolzuete-dlia-razrabotki"&gt;Что вы используете для разработки?&lt;/h3&gt;
&lt;p&gt;Мы используем &lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt; с несколькими plug-in'ами, самыми
важными являются cache-fu от Cris Wanstrath и magic multi connections от
Dr Nic. В качестве текстового редактора я предпочитаю vim с плагином
rails.vim.&lt;/p&gt;
&lt;h4&gt;Какие языки программирования используются?&lt;/h4&gt;
&lt;p&gt;&lt;a href="/tag/ruby-on-rails/"&gt;Ruby on Rails&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Сколько используется серверов?&lt;/h4&gt;
&lt;p&gt;На данный момент используется кластер из 12 серверов.&lt;/p&gt;
&lt;h4&gt;Как они используются?&lt;/h4&gt;
&lt;p&gt;4 сервера баз данных, 6 серверов приложений, 1 тестовый сервер и 1
сервер для балансировки нагрузки.&lt;/p&gt;
&lt;h4&gt;Кто их предоставляет?&lt;/h4&gt;
&lt;p&gt;Мы заказываем их у Softlayer - до подключения их к системе проходит
порой менее четырех часов, что очень неплохо.&lt;/p&gt;
&lt;h4&gt;Какая операционная система используется?&lt;/h4&gt;
&lt;p&gt;CentOS 5 (64 бит)&lt;/p&gt;
&lt;h4&gt;Какой http сервер используется?&lt;/h4&gt;
&lt;p&gt;nginx&lt;/p&gt;
&lt;h4&gt;Какая СУБД используется?&lt;/h4&gt;
&lt;p&gt;MySQL 5.1&lt;/p&gt;
&lt;h4&gt;Вы используете обратную proxy?&lt;/h4&gt;
&lt;p&gt;Мы просто используем встроенный в nginx proxy балансировщик нагрузки.&lt;/p&gt;
&lt;h4&gt;Как вы развертываете вышу систему в датацентре?&lt;/h4&gt;
&lt;p&gt;Мы используем хостинг выделенных серверов, Softlayer.&lt;/p&gt;
&lt;h4&gt;Какова ваша стратегия хранения данных?&lt;/h4&gt;
&lt;p&gt;Мы используем резервное копирование NAS помимо внутренних SCSI RAID
массивов.&lt;/p&gt;
&lt;h4&gt;Какой объем дискового пространства вам доступен?&lt;/h4&gt;
&lt;p&gt;На всех серверах в сумме около 5 TB.&lt;/p&gt;
&lt;h4&gt;Как вы наращиваете объем дискового пространства?&lt;/h4&gt;
&lt;p&gt;Спонтанно. Мы еще не выполнили каких-либо исследований в планировании
дискового пространство, но это было явно зря не сделано.&lt;/p&gt;
&lt;h4&gt;Вы используйте какой-либо сервис хранения информации?&lt;/h4&gt;
&lt;p&gt;Нет.&lt;/p&gt;
&lt;h4&gt;Вы используете виртуализацию хранимых данных?&lt;/h4&gt;
&lt;p&gt;Нет.&lt;/p&gt;
&lt;h4&gt;Как организована работа с сессиями?&lt;/h4&gt;
&lt;p&gt;На данный момент она поручена СУБД, но передача их обслуживания напрямую
memcached - достаточно несложная задача.&lt;/p&gt;
&lt;h4&gt;Как организована архитектура вашей БД?&lt;/h4&gt;
&lt;p&gt;На данный момент - "master/slave". Мы осуществляем переход к нескольким
"slave" с proxy балансировщиком нагрузки для режима "только для чтения".&lt;/p&gt;
&lt;h4&gt;Как организована балансировка нагрузки?&lt;/h4&gt;
&lt;p&gt;На программном уровне средствами nginx.&lt;/p&gt;
&lt;h4&gt;Какой framework / AJAX библиотеку вы используете?&lt;/h4&gt;
&lt;p&gt;Rails.&lt;/p&gt;
&lt;h4&gt;Какие средства распределенного управления задачами вы используете?&lt;/h4&gt;
&lt;p&gt;&lt;a href="/tag/starling/"&gt;Starling&lt;/a&gt;&lt;/p&gt;
&lt;h4&gt;Как вы управляете рекламой в проекте?&lt;/h4&gt;
&lt;p&gt;Мы участвуем в нескольких рекламных сетях. Мы оцениваем эффективность
каждой рекламной сети с помощью eCPM на уровне приложения.&lt;/p&gt;
&lt;h4&gt;Имеете ли вы стандартную API на вашем сайте?&lt;/h4&gt;
&lt;p&gt;Нет.&lt;/p&gt;
&lt;h4&gt;Сколько человек в вашей команде?&lt;/h4&gt;
&lt;p&gt;2 разработчика.&lt;/p&gt;
&lt;h4&gt;Какими наборами способностей обладают участники вашей команды?&lt;/h4&gt;
&lt;p&gt;Я: дизайн пользовательского интерфейса, разработка, ограниченные знания
в Rails, оптимизация MySQL, развертывание Rails.&lt;/p&gt;
&lt;p&gt;Alex: разработка логики приложения, дизайн пользовательского интерфейса,
программная инженерия в целом.&lt;/p&gt;
&lt;h4&gt;Какие средства разработки вы используете?&lt;/h4&gt;
&lt;p&gt;Alex работает в OS X, а я предпочитаю Ubuntu. Для контроля за версиями
используется &lt;a href="/tag/svn/"&gt;SVN&lt;/a&gt;. В качестве текстового редактора я
использую VIM, а Alex - TextMate.&lt;/p&gt;
&lt;h4&gt;Как проходит процесс разработки?&lt;/h4&gt;
&lt;p&gt;На логическом уровне все упирается в тесты, мы проводим их достаточно
экстенсивно. На уровне приложения все ограничивается быстрыми итерациями
и не менее быстры тестированием.&lt;/p&gt;
&lt;h4&gt;Какова ваша стратегия кэширования объектов и контента?&lt;/h4&gt;
&lt;p&gt;Мы используем &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt; без TTL и просто вручную
очищаем кэш при необходимости.&lt;/p&gt;
&lt;h4&gt;Как происходит кэширование на клиентской стороне?&lt;/h4&gt;
&lt;p&gt;Никак.&lt;/p&gt;
&lt;h4&gt;Как вы проверяете глобальную доступность и моделируете производительность для конечных пользователей?&lt;/h4&gt;
&lt;p&gt;Мы используем &lt;a href="/tag/pingdom/"&gt;Pingdom&lt;/a&gt; для внешнего мониторинга за
сайтом - они отлично справляются.&lt;/p&gt;
&lt;h4&gt;Как вы проверяете работоспособность ваших серверов и сетей?&lt;/h4&gt;
&lt;p&gt;На данный момент мы полагаемся на внешний мониторинг и ping мониторинг
от Softlayer. В перспективе мы рассматриваем FiveRuns как возможное
решение для мониторинга серверов.&lt;/p&gt;
&lt;h4&gt;Как вы строите на графиках или диаграммах сетевую и серверную статистику, а также тенденции?&lt;/h4&gt;
&lt;p&gt;Мы не занимаемся этим.&lt;/p&gt;
&lt;h4&gt;Как вы тестируете систему?&lt;/h4&gt;
&lt;p&gt;Сначала мы разворачиваем ее на тестовом сервере и проводим несколько
тестов, после чего разворачиваем систему уже на серверах приложений.&lt;/p&gt;
&lt;h4&gt;Как вы анализируете производительность?&lt;/h4&gt;
&lt;p&gt;Мы отслеживаем каждый SQL-запрос в процессе разработки, это позволяет
нам убедиться, что не выполняются никакие ненужные запросы или создание
экземпляра модели. Помимо этого мы не выполняем каких-либо тестов на
производительность.&lt;/p&gt;
&lt;h4&gt;Как вы обеспечиваете безопасность?&lt;/h4&gt;
&lt;p&gt;Тщательно.&lt;/p&gt;
&lt;h4&gt;Как вы решаете какие возможности добавить или оставить?&lt;/h4&gt;
&lt;p&gt;Решения основываются на отзывах пользователей и критическом взгляде на
них. Мы верим в простоту, так что нам приходится как следует все
взвесить перед добавлением каких-либо существенных возможностей.&lt;/p&gt;
&lt;h4&gt;Как вы реализуете веб-аналитику?&lt;/h4&gt;
&lt;p&gt;Мы используем собственную систему оценок для оптимизации вирусного
эффекта, но помимо этого пользуемся и услугами &lt;a href="https://www.insight-it.ru/goto/d303d8e3/" rel="nofollow" target="_blank" title="http://www.google.com/analytics"&gt;Google
Analytics&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Используете ли вы A/B тестирование?&lt;/h4&gt;
&lt;p&gt;Да, время от времени мы используем их для тонкой настройки аспектов
дизайна для того, чтобы оптимизировать его под вирусный эффект.&lt;/p&gt;
&lt;h4&gt;Как вы выполняете резервное копирование и восстановление?&lt;/h4&gt;
&lt;p&gt;Мы используем LVM для создания ежедневных и еженедельных инкрементальных
резервных копий.&lt;/p&gt;
&lt;h4&gt;Как выполняются обновления оборудования и программного обеспечения?&lt;/h4&gt;
&lt;p&gt;На данный момент мы делаем это вручную, за исключением развертывания
&lt;a href="/tag/rails/"&gt;Rails&lt;/a&gt; приложения. Для обновления и перезапуска серверов
приложений мы используем &lt;a href="/tag/capistrano/"&gt;Capistrano&lt;/a&gt;.&lt;/p&gt;
&lt;h4&gt;Как вы выполняете глобальные изменения в структуре базы данных при обновлениях?&lt;/h4&gt;
&lt;p&gt;Обычно мы начинаем переход с второстепенных серверах баз данных, а затем
просто переключаем основные.&lt;/p&gt;
&lt;h4&gt;Каковы ваши планы насчет защиты от сбоев и развития бизнеса?&lt;/h4&gt;
&lt;p&gt;Не самым лучшим образом...&lt;/p&gt;
&lt;h4&gt;Есть ли у вас отдельная операционная команда, работающая над сайтом?&lt;/h4&gt;
&lt;p&gt;Было бы неплохо, но нет :)&lt;/p&gt;
&lt;h4&gt;Используете ли вы &lt;abbr title="Content Delivery Network"&gt;CDN&lt;/abbr&gt;? Если да, то какую и для каких целей?&lt;/h4&gt;
&lt;p&gt;Нет.&lt;/p&gt;
&lt;h4&gt;Как выглядит модель ваших доходов?&lt;/h4&gt;
&lt;p&gt;&lt;abbr title="Costs per thousand impressions"&gt;CPM&lt;/abbr&gt;: больше просмотров страниц - больше денег. Помимо этого у нас бывают прямые
поощрительные предложения через нашу виртуальную валюту.&lt;/p&gt;
&lt;h4&gt;Как вы продвигаете ваш продукт?&lt;/h4&gt;
&lt;p&gt;Это же социальная сеть. Мы просто используем вирусный эффект для
поддержания роста проекта.&lt;/p&gt;
&lt;h4&gt;Используете ли вы какие-либо особенно интересные технологии или алгоритмы?&lt;/h4&gt;
&lt;p&gt;Я думаю Ruby запросто мог бы подойти под это определение, но на самом
деле нет - мы не проводим научных исследований, мы просто стараемся быть
полезными для посетителей.&lt;/p&gt;
&lt;h4&gt;Храните ли вы изображения в базе данных?&lt;/h4&gt;
&lt;p&gt;Нет, это бы была не самая лучшая идея.&lt;/p&gt;
&lt;h4&gt;Как много работы над организацией взаимодействия с пользователями приходится выполнять?&lt;/h4&gt;
&lt;p&gt;Я бы сказал, что никакой, если вам не приходилось раньше масштабировать
что-либо, и достаточно много, если приходилось. Достаточно сложно
сказать что именно станет проблемой до тех пор, пока на самом деле с
ними не столкнешься. Как только ты пройдешь через это, у тебя будет
достаточно знаний, чтобы осознанно проводить какую-либо работу в этом
направлении.&lt;/p&gt;
&lt;h4&gt;Приходилось ли вам сталкиваться с какими-либо сюрпризами, положительными или отрицательными?&lt;/h4&gt;
&lt;p&gt;Было удивительно, насколько ненадежным может оказаться поставщик
оборудования, и как может отличаться уровень технической поддержки
одного хостинг-провайдера по сравнению с другим. Одной из основных
вещей, которая вам понадобится при масштабировании системы - хостинг,
способный поддерживать ваши потребности.&lt;/p&gt;
&lt;p&gt;С другой стороны, было удивительно насколько далеко смогла наз завести
архитектура с одним "master" и несколькими "slave" на самом обыкновенном
оборудовании. Я думаю, что даже миллиард просмотров страниц в месяц
достижим при таком подходе к базе данных.&lt;/p&gt;
&lt;h4&gt;Как ваша система эволюционирует для соответствия новым требованиям к масштабируемости?&lt;/h4&gt;
&lt;p&gt;По большому счету она этого не делает, мы просто исправляем узкие места
в системе и смотрим что же будет дальше.&lt;/p&gt;
&lt;h4&gt;Кем вы восхищаетесь?&lt;/h4&gt;
&lt;p&gt;Brad Fitzpatrick за изобретение memcache, а также каждым, кому успешно
удалось горизонтально масштабировать свой проект.&lt;/p&gt;
&lt;h4&gt;Каковы ваши планы по изменению архитектуры в будущем?&lt;/h4&gt;
&lt;p&gt;Скоро предется переходить к сегментированной по пользователям базе
данных, так как скоро мы достигнем пределов базы данных по операциям
записи и размерам.&lt;/p&gt;
&lt;h3 id="ikh-mysli-o-virusnom-effekte-facebook"&gt;Их мысли о вирусном эффекте Facebook&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Facebook моделирует социальную сеть в цифровой форме максимально
    точно и полно, по крайней мере насколько это возможно.&lt;/li&gt;
&lt;li&gt;Построение социальной сети более важно, чем возможности,
    предоставляемые пользователям.&lt;/li&gt;
&lt;li&gt;Facebook позволяет быстро распространять новые приложения через
    социальную сеть.&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;Friends for Sale - социальный проект, так как предоставляет
    возможность торговать своей частью социального графа.&lt;/li&gt;
&lt;li&gt;Он затягивает, так как в основе лежит в какой-то степени сумасшедшая
    идея, ненавязчивая, слегка флиртующая, и немного циничная.&lt;/li&gt;
&lt;li&gt;Он универсальный, так как все люди в какой-то степени самовлюбленны,
    знают себе цену, и хотят флиртовать с "горячими" людьми.&lt;/li&gt;
&lt;li&gt;Каждая часть приложения является потенциальной для вовлечения новых
    пользователей.&lt;/li&gt;
&lt;li&gt;Каждый пользователь в среднем приводит 1.4 новых, что является
    залогом экспонентациального роста.&lt;/li&gt;
&lt;li&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;На Facebook требуется масштабирование с самого начала. Дорога до
    миллиона просмотров страниц в сутки заняла 4 недели.&lt;/li&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;/li&gt;
&lt;li&gt;Вам определенно нужна продуманная архитектура базы данных,
    качественный хостинг, а также правильно настроенное оборудование.&lt;/li&gt;
&lt;li&gt;С использованием кэширования и современных серверов, может пройти
    достаточно длительный период времени до тех пор, пока понадобится
    использование баз данных с более сложной структурой, такой как
    сегментирование.&lt;/li&gt;
&lt;li&gt;Социальная сеть - это реальность. Количество новых пользователей в
    хорошо реализованном Facebook приложении на самом деле ошеломляет.&lt;/li&gt;
&lt;li&gt;Большая часть проблем с производительностью в итоге сводится к базе
    данных. Лишний раз обратите внимание на конфигурацию СУБД, запросы и
    использование индексов.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Люди до сих пор пользуются Vi!&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Mon, 17 Mar 2008 21:44:00 +0300</pubDate><guid>tag:www.insight-it.ru,2008-03-17:highload/2008/arkhitektura-friends-for-sale/</guid><category>Capistrano</category><category>CentOS</category><category>Facebook</category><category>Friends for Sale</category><category>LVM</category><category>Memcached</category><category>mongrel</category><category>MySQL</category><category>nginx</category><category>online</category><category>Pingdom</category><category>Rails</category><category>RoR</category><category>Ruby on Rails</category><category>Starling</category><category>SVN</category><category>архитектура</category><category>интернет</category><category>Масштабируемость</category><category>социальные сети</category></item><item><title>Архитектура YouTube</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-youtube/</link><description>&lt;p&gt;Рост &lt;a href="https://www.insight-it.ru/goto/628b8f6a/" rel="nofollow" target="_blank" title="http://www.youtube.com"&gt;YouTube&lt;/a&gt; был феноменально быстр,
количество просмотров видео превысило 100 миллионов в сутки при том, что
только около пяти человек работало над масштабированием проекта. Как им
удается управлять предоставлением всех этих видеороликов своим
посетителям? Как они развивались с тех пор, как были приобретены
&lt;a href="/tag/google/"&gt;Google&lt;/a&gt;?
&lt;!--more--&gt;&lt;/p&gt;
&lt;h3 id="platforma"&gt;Платформа&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/python/"&gt;Python&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; (SuSe)&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/psyco/"&gt;psyco&lt;/a&gt;, динамический компилятор &lt;a href="/tag/python/"&gt;Python&lt;/a&gt; &amp;rarr;
    &lt;a href="/tag/c/"&gt;C&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/lighttpd/"&gt;lighttpd&lt;/a&gt; для видео&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="chto-vnutri"&gt;Что внутри?&lt;/h3&gt;
&lt;h4&gt;Статистика&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Поддержка обработки более 100 миллионов видеороликов в сутки&lt;/li&gt;
&lt;li&gt;Сервис был запущен в феврале 2005 года&lt;/li&gt;
&lt;li&gt;В марте 2006 года в среднем производилось около 30 миллионов
    просмотров видео в день&lt;/li&gt;
&lt;li&gt;К июлю 2006 года эта цифра достигла 100 миллионов просмотров в день&lt;/li&gt;
&lt;li&gt;Над проектом работают: 2 системных администратора, 2 архитектора
    масштабируемости программного обеспечения, 2 разработчика новых
    возможностей, 2 инженера по сетям, 1 архитектор баз данных&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Рецепт управления огромными темпами роста&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
   &lt;span class="n"&gt;identify_and_fix_bottlenecks&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="n"&gt;drink&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="n"&gt;sleep&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
   &lt;span class="n"&gt;notice_new_bottleneck&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Этот цикл проходит далеко не одну итерацию ежедневно.&lt;/p&gt;
&lt;h3 id="veb-servery"&gt;Веб-серверы&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="/tag/netscalar/"&gt;NetScalar&lt;/a&gt; используется для балансировки нагрузки и
    кэширования статического контента.&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; работает с включенным &lt;code&gt;mod_fast_cgi&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Запросы отправляются на обработку с помощью серверного приложения на
    &lt;a href="/tag/python/"&gt;Python&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Приложение взаимодействует с различными базами данных и другими
    источниками информации для формирования финальной
    &lt;a href="/tag/html/"&gt;HTML&lt;/a&gt;-страницы.&lt;/li&gt;
&lt;li&gt;Масштабирование обычно происходит просто добавлением дополнительных
    компьютеров.&lt;/li&gt;
&lt;li&gt;Код на &lt;a href="/tag/python/"&gt;Python&lt;/a&gt; обычно не является узким местом
    системы, он проводит большую часть времени заблокированным RPC.&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/python/"&gt;Python&lt;/a&gt; предоставляет быстроту и гибкость в процессе
    разработки и развертывания. Этот факт является очень актуальным,
    если учесть кто является их конкурентами.&lt;/li&gt;
&lt;li&gt;На формирование страницы обычно уходит не более 100 миллисекунд.&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/psyco/"&gt;psyco&lt;/a&gt;, динамический компилятор &lt;a href="/tag/python/"&gt;Python&lt;/a&gt; &amp;rarr;
    &lt;a href="/tag/c/"&gt;C&lt;/a&gt;, использует JIT подход к компилированию для оптимизации
    внутренних циклов&lt;/li&gt;
&lt;li&gt;Для интенсивных вычислений, таких как шифрование, используются
    расширения, написанные на &lt;a href="/tag/c/"&gt;C&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Какая-то часть заранее сгенерированного &lt;a href="/tag/html/"&gt;HTML&lt;/a&gt; хранится в
    кэше.&lt;/li&gt;
&lt;li&gt;Кэширование данных в &lt;a href="/tag/subd/"&gt;СУБД&lt;/a&gt; на уровне строк.&lt;/li&gt;
&lt;li&gt;Кэшируются полностью сформированные объекты &lt;a href="/tag/python/"&gt;Python&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;Некие данные вычисляются и отправляется каждому серверу для
    кэширования в локальной оперативной памяти. Эта стратегия годится
    далеко не всегда, чаще всего более эффективен другой метод: самым
    быстрым кэшем является само серверное приложение, а отправка уже
    готовых данных остальным серверам для дальнейшей обработки обычно не
    занимает так много времени. Для организации такого подхода
    необходимы агенты, осуществляющие отслеживание изменений,
    предварительную обработку и отправку данных.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="upravlenie-video"&gt;Управление видео&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Издержки включают в себя затраты на пропускную способность каналов
    связи, приобретение нового оборудования и оплату огромных счетов за
    электроэнергию.&lt;/li&gt;
&lt;li&gt;Каждый видеоролик расположен на мини-кластере, что означает
    управление работой с ним группой из нескольких компьютеров.&lt;/li&gt;
&lt;li&gt;Использование кластеров влечет за собой:
    &amp;ndash; увеличение производительности пропорционально количеству дисков,
    на которых расположен контент;
    &amp;ndash; возможность поддержания функционирования всей системы даже в
    случае прекращения работоспособности части компьютеров;
    &amp;ndash; возможность организации создания резервных копий
    &lt;a href="/tag/online/"&gt;online&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;В роли HTTP-сервера для работы с видео используется
    &lt;a href="/tag/lighttpd/"&gt;lighttpd&lt;/a&gt;:
    &amp;ndash; Он способен дать фору &lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; в плане
    производительности предоставления статического контента;
    &amp;ndash; Для работы с событиями ввода-вывода используется &lt;strong&gt;epoll&lt;/strong&gt;;
    &amp;ndash; Многопоточная конфигурация способна обрабатывать большее
    количество соединений одновременно;&lt;/li&gt;
&lt;li&gt;Самая популярная часть контента размещается в &lt;abbr title="Content Delivery Network"&gt;CDN&lt;/abbr&gt;
    &amp;ndash; &lt;abbr title="Content Delivery Network"&gt;CDN&lt;/abbr&gt; реплицирует весь контент в разных частях системы;
    &amp;ndash; Компьютеры &lt;abbr title="Content Delivery Network"&gt;CDN&lt;/abbr&gt; в основном предоставляют данные напрямую из кэша в оперативной памяти, так как ассортимент популярного видео с течением времени
    меняется достаточно медленно.&lt;/li&gt;
&lt;li&gt;Менее популярный контент, количество просмотров в день которого
    варьируется в диапазоне от одного до двадцати, обычно размещается на
    серверах &lt;a href="/tag/youtube/"&gt;YouTube&lt;/a&gt;, расположенных в датацентрах на
    &lt;em&gt;colocation&lt;/em&gt;:
    &amp;ndash; Не смотря на тот факт, что такое видео может быть просмотрено
    всего несколько раз за день, количество таких роликов велико, что
    приводит к случайным блокировкам данных на жестких дисках;
    &amp;ndash; В такой ситуации кэширование практически бесполезно, инвестиции в
    кэширование контента с низкой вероятностью востребованности обычно
    является пустой тратой средств;
    &amp;ndash; Более детальная настройка низкоуровневых компонентов системы,
    таких как, например, RAID-контроллеры, в этой ситуации может
    достаточно положительно повлиять на производительность;
    &amp;ndash; Выбор оптимального размера оперативной памяти на каждой машине
    также очень важен: как недостаточное, так и излишнее ее количество
    не являются эффективными решениями.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Ключевые моменты&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Чем &lt;strong&gt;проще&lt;/strong&gt; - тем &lt;strong&gt;лучше&lt;/strong&gt;;&lt;/li&gt;
&lt;li&gt;Старайтесь минимизировать количество устройств (маршрутизаторов,
    коммутаторов и тому подобных) между контентом и пользователями:
    далеко не факт, что все они будут способны выдерживать интенсивную
    нагрузку;&lt;/li&gt;
&lt;li&gt;Старайтесь использовать самое обыкновенное оборудование. Hi-end
    оборудование обычно влечет за собой рост издержек, связанных с
    сопутствующими процессами, например технической поддержкой, а также
    уменьшает вероятность нахождение решения той или иной проблемы с
    оборудованием в Сети;&lt;/li&gt;
&lt;li&gt;Используйте самые простые распространенные утилиты.
    &lt;a href="/tag/youtube/"&gt;YouTube&lt;/a&gt; использует идущий в комплекте с
    &lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; набор утилит для построения системы именно на их
    основе;&lt;/li&gt;
&lt;li&gt;Не забывайте о случайных доступах к жестким дискам, эту, казалось
    бы, мелочь тоже стоит настроить.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="upravlenie-miniatiurami-video"&gt;Управление миниатюрами видео&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;На удивление сложно решаемая задача, особенно если необходима
    эффективность;&lt;/li&gt;
&lt;li&gt;Для каждого видео хранится 4 миниатюры, что приводит к существенному
    преобладанию количества миниатюр над количеством видеороликов;&lt;/li&gt;
&lt;li&gt;Миниатюры хранятся всего на нескольких компьютерах;&lt;/li&gt;
&lt;li&gt;Некоторые проблемы наблюдаются в связи с работой с большим
    количеством маленьких объектов:
    &amp;ndash; Проблемы на уровне операционной системы, связанные с большим
    количеством запросов на поиск данных, а также кэшем страниц и
    &lt;em&gt;inode&lt;/em&gt;'ов файловой системы;
    &amp;ndash; Ограничение на количество файлов в одной директории (особенно
    актуально для &lt;strong&gt;ext3&lt;/strong&gt;), возможно частичное решение в виде перехода
    к более иерархической структуре хранения данных, а также переходе к
    ядру &lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; версии 2.6, что может привести к более чем
    стократному росту производительности, но в любом случае хранение
    такого огромного количества файлов в локальной файловой системе - не
    самая лучшая идея;
    &amp;ndash; Большое количество запросов в секунду, так как одна страница может
    содержать до 60 миниатюр различных видеороликов;
    &amp;ndash; В условиях таких нагрузок &lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; показывает плохую
    производительность;
    &amp;ndash; Проводились эксперименты с использованием &lt;a href="/tag/squid/"&gt;squid&lt;/a&gt;
    (обратной proxy) между &lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt; и посетителями.
    Какое-то время такой вариант казался работоспособным, но с ростом
    нагрузки производительность начала падать. С обработки 300 запросов
    в секунду она упала до 20;
    &amp;ndash; Попытки использовать &lt;a href="/tag/lighttpd/"&gt;lighttpd&lt;/a&gt; также не
    завершились успехом: однопоточный режим не справлялся с задачей, а
    многопоточный требовал отдельного кэша для каждого потока, что
    сводило на нет его эффективность;
    &amp;ndash; С таким количеством изображений добавление в систему нового
    компьютера могло занимать более 24 часов;
    &amp;ndash; Перезагрузка занимала 6-10 часов, так как кэш должен был
    "разогреться" прежде чем перестать использовать данные с жестких
    дисков.&lt;/li&gt;
&lt;li&gt;Решением всех описанных выше проблем стала распределенная система
    хранения данных &lt;a href="/tag/bigtable/"&gt;BigTable&lt;/a&gt; от &lt;a href="/tag/google/"&gt;Google&lt;/a&gt;:
    &amp;ndash; Она позволяет избежать проблем, связанных с большим количеством
    файлов, так как объединяет маленькие файлы вместе.
    &amp;ndash; Она работает быстро и устойчива к сбоям, помимо этого она
    прекрасно приспособлена для работы по ненадежной сети.
    &amp;ndash; Уменьшает задержки, так как использует распределенный
    многоуровневый кэш, который способен работать даже между удаленными
    датацентрами.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="bazy-dannykh"&gt;Базы данных&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Раньше:
    &amp;ndash; &lt;a href="/tag/mysql/"&gt;MySQL&lt;/a&gt; использовалась для хранения данных:
    пользователей, тэгов, описаний и так далее.
    &amp;ndash; Данные хранились на монолитном RAID 10 массиве, состоящем из 10
    жестких дисков;
    &amp;ndash; Оборудование арендовалось, что негативно сказывалось на состоянии
    их кредитных карточек. В случае необходимости нового оборудования,
    на оформление заказа и доставку мог уходить далеко не один день.
    &amp;ndash; Они прошли через весь путь эволюции: сначала был один сервер,
    затем добавилось несколько дополнительных серверов, обслуживающих
    операции чтения, после чего они решили разбить базу данных на части,
    и, наконец, они пришли к полноценной распределенной архитектуре.
    &amp;ndash; Поначалу их система страдала от задержек, связанных с
    реплицированием. Основной сервер, обрабатывающий операции записи,
    являлся мощным сервером, работающим в многопоточном режиме, это было
    необходимо для своевременного выполнения большого объема работы.
    Второстепенные сервера, которые обрабатывали только операции чтения,
    асинхронно реплицировали данные в одном потоке, что влекло за собой
    возможность серьезного отставания некоторых из них.
    &amp;ndash; Обновления были причиной частого отсутствия необходимой информации
    в кэше, что заставляло сервера читать данные с жестких дисков. Этот
    факт сильно замедлял процесс чтения и репликации.
    &amp;ndash; Реплицирующая архитектура требует немалых вложений в оборудование,
    необходимого для поддержания постоянно растущих темпов записи
    информации.
    &amp;ndash; Основным из кардинальных решений, принятых в архитектуре системы
    было отделение обеспечения процесса просмотра видео от основного
    кластера. Основной целью посетителей является просмотр видео, а
    второстепенные задачи можно возложить и на менее производительный
    кластер.&lt;/li&gt;
&lt;li&gt;Сейчас:
    &amp;ndash; Используются распределенные базы данных;
    &amp;ndash; Сегментированная система &lt;em&gt;(прим.: &lt;a href="https://www.insight-it.ru/highload/2008/arkhitektura-flickr/"&gt;по аналогии с Flickr&lt;/a&gt;)&lt;/em&gt;;
    &amp;ndash; Распределенные чтение и запись;
    &amp;ndash; Более эффективное расположение кэша, что ведет к уменьшению работы
    с жесткими дисками;
    &amp;ndash; Такая архитектура привела к 30%-й экономии на оборудовании;
    &amp;ndash; Задержки в реплицировании сведены к нулю;
    &amp;ndash; Размеры базы данных могут расти практически неограниченно&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="strategiia-razmeshcheniia-v-datatsentrakh"&gt;Стратегия размещения в датацентрах&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Поначалу использовались хостинг провайдеры, предоставляющие услуги
    colocation. Не самый экономичный подход, но тогда не было другого
    выхода.&lt;/li&gt;
&lt;li&gt;Хостинг провайдеры не могут поспеть за темпами роста проекта. Не
    всегда получается получить контроль над необходимым оборудованием
    или сделать необходимые соглашения о предоставлению сетевых услуг.&lt;/li&gt;
&lt;li&gt;Решением этой проблемы стало создание собственной базы для
    размещения оборудования. Появилась возможность настраивать абсолютно
    все и подписывать свои собственные контракты такого рода.&lt;/li&gt;
&lt;li&gt;Было использовано 5 или 6 разных датацентров в дополнение к
    &lt;abbr title="Content Delivery Network"&gt;CDN&lt;/abbr&gt;.&lt;/li&gt;
&lt;li&gt;Видео поступает из случайного датацентра, никаких специальных
    проверок не проводится. Если ролик становится достаточно
    популярным - он перемещается в
    &lt;abbr title="Content Delivery Network"&gt;CDN&lt;/abbr&gt;.&lt;/li&gt;
&lt;li&gt;Основным фактором, влияющим на доступность того или иного ролика
    является пропускная способность канала связи.&lt;/li&gt;
&lt;li&gt;Для изображений же более актуальны задержки, особенно если на одной
    страницы должно быть размещено под 60 изображений.&lt;/li&gt;
&lt;li&gt;Репликация изображений производится средствами
    &lt;a href="/tag/bigtable/"&gt;BigTable&lt;/a&gt;. В этом случае используются различные меры
    для определения ближайшего места, откуда можно получить необходимые
    данные.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="podvodim-itogi"&gt;Подводим итоги&lt;/h3&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;a href="/tag/youtube/"&gt;YouTube&lt;/a&gt; использует
    &lt;abbr title="Content Delivery Network"&gt;CDN&lt;/abbr&gt; для распределения
    своего наиболее популярного контента. Создание своей собственной
    подобной сети стоило бы им слишком много и потребовало бы слишком
    много времени. Возможно у Вас появятся подобные возможности в
    отношении Вашей системы.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Будьте проще!&lt;/strong&gt; Простота позволяет изменять архитектуру более
    быстро, что позволяет своевременно реагировать на возникающие
    проблемы. Никто на самом деле не знает что такое &lt;em&gt;простота&lt;/em&gt;, но если
    Вы не боитесь делать изменения, то это неплохой знак что вашей
    системе свойственна та самая &lt;em&gt;простота&lt;/em&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;
    &amp;ndash; на программном уровне это чаще всего бывает кэширование и работа с
    &lt;a href="/tag/subd/"&gt;СУБД&lt;/a&gt;;
    &amp;ndash; на уровне операционной системы - операции ввода-вывода;
    &amp;ndash; на уровне оборудования - оперативная память и RAID массивы.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Залог Вашего успеха - командная работа.&lt;/strong&gt; Хорошая команда разного
    рода специалистов должна понимать принцип системы вцелом и того, что
    лежит &lt;em&gt;под&lt;/em&gt; ней. Каждый должен знать свое дело: настраивать
    принтеры, подключать к системе новые компьютеры, строить сети и так
    далее. С отличной командой Вам по силам все что угодно.&lt;/li&gt;
&lt;/ul&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/ea16b832/" rel="nofollow" target="_blank" title="http://highscalability.com/youtube-architecture"&gt;статьи&lt;/a&gt; от &lt;a href="https://www.insight-it.ru/goto/f3f1b405/" rel="nofollow" target="_blank" title="http://highscalability.com/user/todd-hoff"&gt;Todd Hoff&lt;/a&gt;'а уже был выполнен до
меня (при желании можно найти в любой поисковой системе), но я все равно
решил опубликовать свою версию просто для собственного развития и
полноты &lt;a href="https://www.insight-it.ru/highload/"&gt;коллекции&lt;/a&gt;, да и многим читателям, возможно,
покажется интересным. Что ж, перейдем к источнику информации оригинала:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/f5823d0b/" rel="nofollow" target="_blank" title="http://video.google.com/videoplay?docid=-6304964351441328559"&gt;Google Video&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, 01 Mar 2008 16:07:00 +0300</pubDate><guid>tag:www.insight-it.ru,2008-03-01:highload/2008/arkhitektura-youtube/</guid><category>Apache</category><category>BigTable</category><category>lighttpd</category><category>Linux</category><category>MySQL</category><category>NetScalar</category><category>psyco</category><category>Python</category><category>YouTube</category><category>архитектура</category><category>архитектура YouTube</category><category>интернет</category><category>Масштабируемость</category><category>производительность</category><category>хранение данных</category></item><item><title>Архитектура Flickr</title><link>https://www.insight-it.ru//highload/2008/arkhitektura-flickr/</link><description>&lt;p&gt;&lt;a href="https://www.insight-it.ru/goto/f50a76e1/" rel="nofollow" target="_blank" title="http://www.flickr.com"&gt;Flickr&lt;/a&gt; является мировым лидером среди сайтов
размещения фотографий. Перед Flickr стоит впечатляющая задача, они
должны контролировать обширное море ежесекундно обновляющегося контента,
непрерывно пополняющиеся легионы пользователей, постоянный поток новых
предоставляемых пользователям возможностей, а делается все это при
постоянной поддержке отличной производительности. Как же они это
делают?
&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/2008/arkhitektura-google/"&gt;"Архитектура Google"&lt;/a&gt;, этот тоже является
переводом &lt;a href="https://www.insight-it.ru/goto/e7a0ee0d/" rel="nofollow" target="_blank" title="http://highscalability.com/flickr-architecture"&gt;статьи&lt;/a&gt; от
&lt;a href="https://www.insight-it.ru/goto/f3f1b405/" rel="nofollow" target="_blank" title="http://highscalability.com/user/todd-hoff"&gt;Todd'а Hoff'а&lt;/a&gt;. Возможно
читателям &lt;a href="/tag/google/"&gt;Google&lt;/a&gt; был более интересен, но подход Flickr к
масштабируемости тоже более чем заслуживает внимания. Далее привожу
источники информации из оригинальной статьи:&lt;/em&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/88014756/" rel="nofollow" target="_blank" title="http://www.niallkennedy.com/blog/uploads/flickr_php.pdf"&gt;Flickr и PHP&lt;/a&gt;
    (ранний документ)&lt;/li&gt;
&lt;li&gt;Планирование нагрузок на LAMP&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/6df1dabf/" rel="nofollow" target="_blank" title="http://www.bytebot.net/blog/archives/2007/04/25/federation-at-flickr-a-tour-of-the-flickr-architecture"&gt;Федерация Flickr: Тур по архитектуре Flickr&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/9e0a13a1/" rel="nofollow" target="_blank" title="http://highscalability.com/book-building-scalable-web-sites"&gt;Построение масштабируемых веб-сайтов&lt;/a&gt;
    от Call Handerson'а из Flickr&lt;/li&gt;
&lt;li&gt;История войн баз данных #3: Tim O'Reilly о Flickr&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.insight-it.ru/goto/d881b0d9/" rel="nofollow" target="_blank" title="http://www.iamcal.com/talks/"&gt;Cal Henderson's Talks&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/php/"&gt;PHP&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/sql/"&gt;MySQL&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Сегментирование &lt;em&gt;(прим.: разбиение системы на части, обслуживающие
    каждая свою группу пользователей; называть можно было по-разному, но
    давайте остановимся на этом варианте перевода слова "Shards")&lt;/em&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/squid/"&gt;Squid&lt;/a&gt; в качестве обратной-прокси для html и
    изображений&lt;/li&gt;
&lt;li&gt;&lt;a href="/linux"&gt;Linux&lt;/a&gt; (&lt;a href="/tag/redhat/"&gt;RedHat&lt;/a&gt;)&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/smarty/"&gt;Smarty&lt;/a&gt; в роли шаблонизатора&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/perl/"&gt;Perl&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;PEAR для парсинга e-mail и XML&lt;/li&gt;
&lt;li&gt;ImageMagick для обработки изображений&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/java/"&gt;Java&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/systemimager/"&gt;SystemImager&lt;/a&gt; для развертывания систем&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/ganglia/"&gt;Ganglia&lt;/a&gt; для мониторинга распределенных систем&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/subcon/"&gt;Subcon&lt;/a&gt; хранит важные системные конфигурационные файлы
    в SVN-репозитории для легкого развертывания на машины в кластере.&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/cvsup/"&gt;Cvsup&lt;/a&gt; для распространения и обновления коллекций
    файлов по сети&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="statistika"&gt;Статистика&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Более четырех миллиардов запросов в день&lt;/li&gt;
&lt;li&gt;Примерно 35 миллионов фотографий в кэше &lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Около двух миллионов фотографий в оперативной памяти
    &lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Всего приблизительно 470 миллионов изображений, каждое представлено
    в 4 или 5 размерах&lt;/li&gt;
&lt;li&gt;38 тысяч запросов к &lt;a href="/tag/memcached/"&gt;memcached&lt;/a&gt; (12 миллионов
    объектов)&lt;/li&gt;
&lt;li&gt;2 петабайта дискового пространства&lt;/li&gt;
&lt;li&gt;Более 400000 фотографий добавляются ежедневно&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="arkhitektura"&gt;Архитектура&lt;/h3&gt;
&lt;p&gt;Симпатичное изображение архитектуры Flickr можно увидеть на &lt;a href="https://www.insight-it.ru/goto/d30e097b/" rel="nofollow" target="_blank" title="http://www.slideshare.net/techdude/scalable-web-architectures-common-patterns-and-approaches/138"&gt;этом слайде&lt;/a&gt;.
Краткое ее описание выглядит следующим образом:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Два ServerIron&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/squid/"&gt;Squid&lt;/a&gt; кэши&lt;/li&gt;
&lt;li&gt;Системы хранения NetApp&lt;/li&gt;
&lt;li&gt;Серверы &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; приложений&lt;/li&gt;
&lt;li&gt;Менеджер хранения данных&lt;/li&gt;
&lt;li&gt;Master-master сегменты&lt;/li&gt;
&lt;li&gt;Центральная база данных, структурированная по принципу Dual
Tree&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/memcached/"&gt;Memcached&lt;/a&gt; кластер&lt;/li&gt;
&lt;li&gt;Поисковая система&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Хранение данных&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Структура Dual Tree является индивидуальным набором модификаций для
&lt;a href="/tag/sql/"&gt;MySQL&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;Отсутствие состояний заключается в том, что в случае необходимости
    они имеют возможность передать пользователей от сервера к серверу,
    что стало намного проще для них после создания своего API&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="/tag/php/"&gt;PHP&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;ul&gt;
&lt;li&gt;&lt;em&gt;Сегменты системы:&lt;/em&gt; Мои данные хранятся на моем сегменте, но
запись о Вашем комментарии хранится на Вашем сегменте.&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Глобальное кольцо:&lt;/em&gt; Принцип работы схож с DNS, Вам необходимо
знать куда Вы хотите пойти и кто контролирует то место, куда Вы
собираетесь пойти.&lt;/li&gt;
&lt;li&gt;Логика на &lt;a href="/tag/php/"&gt;PHP&lt;/a&gt; устанавливает соединение с сегментом и
поддерживает целостность данных (10 строк кода с комментариями!)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Сегменты:&lt;/strong&gt;&lt;ul&gt;
&lt;li&gt;Срез основной базы данных&lt;/li&gt;
&lt;li&gt;Активная репликация по принципу мастер-мастер: имеет несколько
недостатков в &lt;a href="/tag/sql/"&gt;MySQL&lt;/a&gt; 4.1. Автоматическое
инкрементирование идентификационных номеров используется для
поддержания системы в режиме одновременной активности обоих серверов
в паре&lt;/li&gt;
&lt;li&gt;Привязывание новых учетных записей к сегментам системы происходит
случайным образом&lt;/li&gt;
&lt;li&gt;Миграция пользователей проводится время от времени для того, чтобы
избавиться от проблем, связанных с излишне активными пользователями.
Необходима сбалансированность в этом процессе, особенно в случаях с
большим количеством фотографий&amp;hellip; 192 тысячи фотографий, 700 тысяч
тэгов, может занять несколько минут. Миграция выполняется вручную.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Нажатие на &lt;strong&gt;Favorite&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;Получается информация об учетной записи владельца из кэша для
того, чтобы узнать к какому сегменту он привязан (допустим на
shard-5)&lt;/li&gt;
&lt;li&gt;Получается информация о моей учетной записи из кэша, более
конкретно - мой сегмент (например shard-13)&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;Запросы на чтение и запись от каждого пользователя ограничиваются
    рамками одного сегмента. Задержки репликации исчезают из поля зрения
    пользователей.&lt;/li&gt;
&lt;li&gt;Каждый сервер в рамках одного сегмента в обычном состоянии нагружен
    ровно на половину. Выключите половину серверов в каждом сегменте и
    система продолжит функционировать без изменений. Это значит, что
    один сервер внутри сегмента может взять на себя всю нагрузку
    второго, в то время как второй сервер может по каким либо причинам
    быть отключен от системы, например для проведения технических работ.
    Обновление оборудования производится очень просто: отключается
    половина сегмента, она же обновляется, подключается обратно, процесс
    повторяется для оставшейся половины.&lt;/li&gt;
&lt;li&gt;Периоды пиковой нагрузки также нарушают правило 50% нагрузки. В
    такие моменты система получает 6-7 тысяч запросов в секунду, в то
    время как на данный момент система может работать на
    пятидесятипроцентном уровне нагрузки только при четырех тысячах
    запросов в секунду.&lt;/li&gt;
&lt;li&gt;В среднем при загрузке одной страницы выполняется 27-35
    SQL-запросов. Списки избранных фотографий обрабатываются в реальном
    времени, ровно как и доступ через API к базе данных. Все требования
    к нагрузке в реальном времени выполняются без каких-либо
    недостатков.&lt;/li&gt;
&lt;li&gt;Более 36 тысяч запросов в секунду может выполняться не выходя за
    рамки возможностей системы, даже при резком росте трафика.&lt;/li&gt;
&lt;li&gt;Каждый сегмент содержит данные о более чем 400 тысячах
    пользователей.&lt;/li&gt;
&lt;li&gt;Многие данные хранятся в двух местах одновременно. Например,
    комментарий является частью между комментатором и автором
    комментируемого контента. Где его хранить? Как насчет обоих мест?
    Транзакции используются для предотвращения рассинхронизации данных:
    открывается первая транзакция, выполняется запись, открывается
    вторая транзакция, выполняется запись, подтверждается первая
    транзакция если все нормально, после чего вторая подтверждается
    только в случае если первая прошла успешно.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Поиск&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Используется два варианта поиска: поиск в рамках сегмента,
поддерживающий до 35 тысяч запросов в секунду, а также проприетарный
веб-поиск от Yahoo!&lt;/li&gt;
&lt;li&gt;В 90% случаев используется система от Yahoo!, за исключением
поиска по тэгу фотографий одного пользователя и массовых изменений
тэгов.&lt;/li&gt;
&lt;li&gt;Эту систему стоит рассматривать как аналог Lucene.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Оборудование&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;EMT64 под управлением RHEL 4 с 16 Gb оперативной памяти.&lt;/li&gt;
&lt;li&gt;6 жестких дисков с 15000rpm, объединены в RAID-10.&lt;/li&gt;
&lt;li&gt;Размер для пользовательских метаданных достигает 12 терабайт (это
не включает фотографии, для них цифры существенно больше).&lt;/li&gt;
&lt;li&gt;Используются 2U корпуса.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Резервное копирование данных&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;ibbackup выполняется регулярно посредством cron daemon'а, на
каждом сегменте настроен на разное время.&lt;/li&gt;
&lt;li&gt;Каждую ночь делается снимок со всего кластера баз данных.&lt;/li&gt;
&lt;li&gt;Запись или удаление нескольких больших файлов с резервными копиями
одновременно на реплицирующую систему хранения может сильно
сократить производительность системы вцелом на последующие несколько
часов из-за процесса репликации. Выполнение этого на активно
работающей системе хранения фотографий было бы не самой лучшей
идеей.&lt;/li&gt;
&lt;li&gt;Содержание нескольких резервных копий всех Ваших данных требует
существенных материальных затрат, но оно того стоит. Особенно это
актуально для тех ситуаций, когда Вы понимаете, что что-то пошло не
так только спустя несколько дней после того как это случилось, в
таких случаях неплохо иметь, например, резервные копии 1, 3, 10 и
30-дневной давности.&lt;/li&gt;
&lt;li&gt;Фотографии хранятся в системе хранения данных. После загрузки
изображения система выдает различные его размеры, на чем ее работа
заканчивается. Метаданные и ссылки на файловые системы, где
расположены фотографии, хранятся в базе данных.&lt;/li&gt;
&lt;li&gt;Агрегация данных проходит очень быстро, так как она ограничена
пределами сегмента.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;max_connections = 400&lt;/code&gt; соединений на каждый сегмент, неплохой запас.
Значение для кэша потоков установлено равным 45, так как не бывает
ситуаций когда более 45 пользователей одновременно выполняют
какие-либо действия с одним конкретным сегментом.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Тэги&lt;/h4&gt;
&lt;ul&gt;
&lt;li&gt;Тэги плохо вписываются в традиционную нормализованную схему
реляционной базы данных. Денормализация или активное кэширование -
единственные способы сгенерировать облако меток для сотен миллионов
тэгов в течении миллисекунд.&lt;/li&gt;
&lt;li&gt;Некоторые данные обрабатываются отдельными вычислительными
кластерами, которые сохраняют результаты своей работы в MySQL, так
как иначе вычисление сложных отношений заняло бы все процессорное
время основных серверов баз данных.&lt;/li&gt;
&lt;/ul&gt;
&lt;h4&gt;Направления для развития&lt;/h4&gt;
&lt;p&gt;Ускорение работы с помощью создания
организационного плана для непрерывной работы всей системы на уровне
нескольких датацентров, таким образом чтобы все датацентры имели
возможность получать запросы на общий уровень данных (как сами БД,
так и memcache и прочее) все вместе одновременно. Если все части
системы постоянно активны - время простоя оборудования будет сведено
к минимуму.&lt;/p&gt;
&lt;h3 id="podvodim-itogi"&gt;Подводим итоги&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;Старайтесь думать о своем приложении как о чем-то большем, чем просто
    веб-приложении, тогда у Вас возможно появятся поддержка различных
    API, RSS и Atom ленты и многие другие возможности.&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;Забудьте о всех небольших эффективных вещах, предварительная
    оптимизация является корнем всего зла в примерно 97% всех случаев.&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;li&gt;Как близко параметр находится к максимуму и каковы тенденции?&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/sql/"&gt;MySQL&lt;/a&gt; (дисковый ввод/вывод?)&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/squid/"&gt;Squid&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;/li&gt;
&lt;li&gt;Старайтесь учесть особенности использования Вашего приложения.&lt;ul&gt;
&lt;li&gt;Возможен ли резкий рост нагрузки, связанный с каким-либо событием?
Например: какое-либо бедствие, или может быть новость?&lt;/li&gt;
&lt;li&gt;Flickr получает на 20-40% больше новых фотографий в первый рабочий
день нового года, чем в любой пик в предыдущем году.&lt;/li&gt;
&lt;li&gt;По воскресеньям нагрузка в среднем на 40-50% выше, чем в любой
другой день недели.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Учтите возможность экспоненциального роста. Больше пользователей
    означает больше контента, больше контента означает больше
    соединений, больше соединений означает более активное использование.&lt;/li&gt;
&lt;li&gt;Планируйте возможные варианты управления работой системы в периоды
    пиковых нагрузок.&lt;/li&gt;
&lt;/ul&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Fri, 08 Feb 2008 22:41:00 +0300</pubDate><guid>tag:www.insight-it.ru,2008-02-08:highload/2008/arkhitektura-flickr/</guid><category>Apache</category><category>Cvsup</category><category>flickr</category><category>Ganglia</category><category>Java</category><category>Linux</category><category>Memcached</category><category>MySQL</category><category>online</category><category>Perl</category><category>PHP</category><category>RedHat</category><category>shard</category><category>Smarty</category><category>Squid</category><category>Subcon</category><category>SystemImager</category><category>архитектура</category><category>архитектура Flickr</category><category>интернет</category><category>кластер</category><category>Масштабируемость</category><category>сервер</category></item><item><title>Общаемся с базой данных</title><link>https://www.insight-it.ru//php/2008/obshhaemsya-s-bazojj-dannykh/</link><description>&lt;p&gt;На этот раз хочется обсудить такой одновременно важный и несложный
момент в реализации работы любого интернет-проекта, как координации
работы Ваших скриптов с СУБД.&lt;/p&gt;
&lt;p&gt;Если подойти к этому вопросу "в лоб", то код станет очень неудобен как
для понимания, так и для использования: код станет переполнен различными
функциями соединения с БД, отправки запросов, преобразования результатов
запросов в массивы PHP, подсчета строк, которые затронул запрос, а также
многие и многие другие.&lt;/p&gt;
&lt;p&gt;Для желающих минимизировать подобного рода издержки в процессе написания
кода, хочу предложить один из, на мой взгляд, самых эффективных способов
решения этой проблемы.&lt;/p&gt;
&lt;!--more--&gt;
&lt;p&gt;Этим способом будет являться написание класса, реализующего интерфейс
между СУБД и PHP-скриптами. Для начала стоит определиться с
ассортиментом функций, которые будет призван выполнять наш класс:&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;, не ограничивающаяся одним SELECT,
    должны быть предоставлены методы обработки результатов любых видов
    запросов (или хотябы большинства).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Вполне очевидным является тот факт, что методы этого класса будут
использоваться практически повсеместно в большинстве проектов.
Вследствии чего становится нецелесообразным создание объекта нашего
класса и передача его по всем функциям и методам всех скриптов, в таких
случае намного предпочтительнее делать владельцем методов и переменных
сам класс, а не экземпляр класса, с помощью ключевого слова &lt;strong&gt;static&lt;/strong&gt;.
Это позволит пользоваться услугами нашего класса из любого места кода.
Приступим-с собственно к кодингу, начать стоит с заготовки пустого
класса:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SQL&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;В зависимости от предпочитаемой Вами СУБД набор конкретных функций,
используемых в реализации нашего класса, будет вариироваться. В
большинстве случаев предпочитаю пользоваться PostgreSQL, на это причин у
меня несколько, но это тема для отдельного разговора. Благодаря этому
факту приводимый в качестве примера код будет использовать функции для
работы именно с этой СУБД. Для поклонников же других этот систем вопрос
в подавляющем большинстве случаев заключается лишь в замене этих функций
на аналогичные из других модулей PHP, например для популярной и
широкораспространенной MySQL достаточно будет всеголишь пройтись
автозаменой &lt;strong&gt;pg_ =&amp;gt; mysql_&lt;/strong&gt; и слегка подредактировать параметры
некоторых функций.&lt;/p&gt;
&lt;p&gt;Перейдем к реализации установления соединения с СУБД, не стоит ожидать
увидеть здесь ничего необычного:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;// установка соединения&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="nx"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;pg_pconnect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"host=localhost dbname=pgsql user=pgsql password=MyPassword"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="c1"&gt;// не забываем менять указанные данные для авторизации на правильные&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Сайт не работает по техническим причинам.&lt;/span&gt;
&lt;span class="s2"&gt;Просим прощения за доставленные неудобства."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;   &lt;span class="c1"&gt;// ни в коем случае не выводим более информативных сообщений об ошибке, чем это&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;А вот с отправкой и обработкой результатов запросов ситуация далеко не
так однозначна. Помимо простой передачи самого текста запроса в СУБД,
необходимо правильно определить тип запроса и в соответствии с этим
обработать результат. Можно конечно попытаться сделать это автоматически
на основе вытаскивания первого слова из текста запроса, но мне всетаки
кажется более предпочтительным определение "вручную" желаемого вида
представление результата. Выполнение произвольных запросов может
выглядеть, например, следующим образом:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$bool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// произвольный запрос&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;//echo $str."&lt;/span&gt;
&lt;span class="s2"&gt;"; // очень удобно на стадии разработки в процессе поиска ошибок&lt;/span&gt;
&lt;span class="s2"&gt;  &lt;/span&gt;&lt;span class="si"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;=@pg_query(self::&lt;/span&gt;&lt;span class="si"&gt;$connection&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="si"&gt;$str&lt;/span&gt;&lt;span class="s2"&gt;); // @ - для сокрытия теоретически возможных ошибок&lt;/span&gt;
&lt;span class="s2"&gt;  // or die('Query failed: '.pg_last_error());&lt;/span&gt;
&lt;span class="s2"&gt;  // не забываем убирать в комментарий в финальном варианте проекта&lt;/span&gt;
&lt;span class="s2"&gt;  // или совсем удалять&lt;/span&gt;
&lt;span class="s2"&gt;  if(&lt;/span&gt;&lt;span class="si"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;)  // Если получен результат, отличный от false&lt;/span&gt;
&lt;span class="s2"&gt;  {&lt;/span&gt;
&lt;span class="s2"&gt;    if(&lt;/span&gt;&lt;span class="si"&gt;$bool&lt;/span&gt;&lt;span class="s2"&gt;)  // Если выбран результат в виде boolean&lt;/span&gt;
&lt;span class="s2"&gt;    {&lt;/span&gt;
&lt;span class="s2"&gt;      return true;&lt;/span&gt;
&lt;span class="s2"&gt;    }&lt;/span&gt;
&lt;span class="s2"&gt;    else  // Если выбран результат в виде массива&lt;/span&gt;
&lt;span class="s2"&gt;    {&lt;/span&gt;
&lt;span class="s2"&gt;      &lt;/span&gt;&lt;span class="si"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;=pg_num_rows(&lt;/span&gt;&lt;span class="si"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;);  // для создания универсального формата массива&lt;/span&gt;
&lt;span class="s2"&gt;      if(&lt;/span&gt;&lt;span class="si"&gt;$n&lt;/span&gt;&lt;span class="s2"&gt;==1)return pg_fetch_array(&lt;/span&gt;&lt;span class="si"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;,0,PGSQL_ASSOC);&lt;/span&gt;
&lt;span class="s2"&gt;      else  // даже когда результат содержит только одну строку&lt;/span&gt;
&lt;span class="s2"&gt;      {&lt;/span&gt;
&lt;span class="s2"&gt;        &lt;/span&gt;&lt;span class="si"&gt;$j&lt;/span&gt;&lt;span class="s2"&gt;=pg_num_rows(&lt;/span&gt;&lt;span class="si"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;);&lt;/span&gt;
&lt;span class="s2"&gt;        &lt;/span&gt;&lt;span class="si"&gt;$list&lt;/span&gt;&lt;span class="s2"&gt;=array();&lt;/span&gt;
&lt;span class="s2"&gt;        for(&lt;/span&gt;&lt;span class="si"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;=0;&lt;/span&gt;&lt;span class="si"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;&amp;lt;&lt;/span&gt;&lt;span class="si"&gt;$j&lt;/span&gt;&lt;span class="s2"&gt;;&lt;/span&gt;&lt;span class="si"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;++)&lt;/span&gt;
&lt;span class="s2"&gt;        &lt;/span&gt;&lt;span class="si"&gt;$list&lt;/span&gt;&lt;span class="s2"&gt;[]=pg_fetch_array(&lt;/span&gt;&lt;span class="si"&gt;$result&lt;/span&gt;&lt;span class="s2"&gt;,&lt;/span&gt;&lt;span class="si"&gt;$i&lt;/span&gt;&lt;span class="s2"&gt;,PGSQL_ASSOC);&lt;/span&gt;
&lt;span class="s2"&gt;        return &lt;/span&gt;&lt;span class="si"&gt;$list&lt;/span&gt;&lt;span class="s2"&gt;;&lt;/span&gt;
&lt;span class="s2"&gt;      }&lt;/span&gt;
&lt;span class="s2"&gt;    }&lt;/span&gt;
&lt;span class="s2"&gt;  }else return false;&lt;/span&gt;
&lt;span class="s2"&gt;}&lt;/span&gt;
&lt;span class="s2"&gt;?&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Помимо базовой отправки запросов, в некоторых случаях имеет смысл
написать несколько методов, отправляющих частоиспользуемые запросы, что
в некоторых случаях позволяет сократить объем и уменьшить
нагроможденность кода. Хоть я и предпочитаю не пользоваться такими
вещами, но привести пример такого рода метода все же стоит:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;selectAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// пример метода отправки чаcтоиспользуемых запросов&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"select * from "&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;";"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Если чувствуете необходимость в подобных функциях, можно написать
огромное количество, все ограничивается лишь Вашим воображением и
знаниями SQL.&lt;/p&gt;
&lt;p&gt;Что ж, осталось лишь собрать весь код в единый листинг:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="cp"&gt;&amp;lt;?php&lt;/span&gt;
&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;SQL&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;private&lt;/span&gt; &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// соединение с СУБД&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;connect&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;  &lt;span class="c1"&gt;// установка соединения&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="nx"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;pg_pconnect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"host=localhost dbname=pgsql user=pgsql password=MyPassword"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
    &lt;span class="c1"&gt;// не забываем менять указанные данные для авторизации на правильные&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;!&lt;/span&gt;&lt;span class="nb"&gt;isset&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;echo&lt;/span&gt; &lt;span class="s2"&gt;"Сайт не работает по техническим причинам.&amp;lt;br /&amp;gt;Просим прощения за доставленные неудобства."&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="k"&gt;exit&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// ни в коем случае не выводим более информативных сообщений об ошибке, чем это&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$bool&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// произвольный запрос&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="c1"&gt;//echo $str."&amp;lt;br&amp;gt;"; // очень удобно на стадии разработки в процессе поиска ошибок&lt;/span&gt;
    &lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="o"&gt;=@&lt;/span&gt;&lt;span class="nb"&gt;pg_query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="nv"&gt;$connection&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$str&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// @ - для сокрытия теоретически возможных ошибок&lt;/span&gt;
    &lt;span class="c1"&gt;// or die('Query failed: '.pg_last_error());&lt;/span&gt;
    &lt;span class="c1"&gt;// не забываем убирать в комментарий в финальном варианте проекта&lt;/span&gt;
    &lt;span class="c1"&gt;// или совсем удалять&lt;/span&gt;
    &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// Если получен результат, отличный от false&lt;/span&gt;
    &lt;span class="p"&gt;{&lt;/span&gt;
      &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$bool&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;  &lt;span class="c1"&gt;// Если выбран результат в виде boolean&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;true&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="k"&gt;else&lt;/span&gt;  &lt;span class="c1"&gt;// Если выбран результат в виде массива&lt;/span&gt;
      &lt;span class="p"&gt;{&lt;/span&gt;
        &lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;pg_num_rows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;  &lt;span class="c1"&gt;// для создания универсального формата массива&lt;/span&gt;
        &lt;span class="k"&gt;if&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$n&lt;/span&gt;&lt;span class="o"&gt;==&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nb"&gt;pg_fetch_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;PGSQL_ASSOC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
        &lt;span class="k"&gt;else&lt;/span&gt;  &lt;span class="c1"&gt;// даже когда результат содержит только одну строку&lt;/span&gt;
        &lt;span class="p"&gt;{&lt;/span&gt;
          &lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;pg_num_rows&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="nv"&gt;$list&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;array&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
          &lt;span class="k"&gt;for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;&amp;lt;&lt;/span&gt;&lt;span class="nv"&gt;$j&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="o"&gt;++&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
          &lt;span class="nv"&gt;$list&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="nb"&gt;pg_fetch_array&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nv"&gt;$i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="nx"&gt;PGSQL_ASSOC&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
          &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nv"&gt;$list&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
        &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="p"&gt;}&lt;/span&gt;&lt;span class="k"&gt;else&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;false&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;

  &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;static&lt;/span&gt; &lt;span class="k"&gt;function&lt;/span&gt; &lt;span class="nf"&gt;selectAll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="c1"&gt;// пример метода отправки чаcтоиспользуемых запросов&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;self&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="na"&gt;query&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"select * from "&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nv"&gt;$table&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="s2"&gt;";"&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="cp"&gt;?&amp;gt;&lt;/span&gt;&lt;span class="x"&gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;```&lt;/p&gt;
&lt;p&gt;Вот так вот оно и выглядит в простейшем варианте, дорабатывать под
собственные нужды код можно до бесконечности естественно, но в
большинстве случаев даже такой реализации вполне должно хватать.&lt;/p&gt;
&lt;p&gt;Эта статья является частью &lt;a href="https://www.insight-it.ru/dzhentelmenskij-nabor-php-programmista/"&gt;серии статей "Джентельменский набор PHP программиста"&lt;/a&gt;, если Вам
понравилась эта статья то очень вероятно, что Вам придутся по душе и
остальные статьи.&lt;/p&gt;
&lt;p&gt;Не забываем &lt;a href="/feed/"&gt;подписываться на RSS блога&lt;/a&gt;!&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Wed, 16 Jan 2008 22:04:00 +0300</pubDate><guid>tag:www.insight-it.ru,2008-01-16:php/2008/obshhaemsya-s-bazojj-dannykh/</guid><category>MySQL</category><category>PHP</category><category>PostgreSQL</category><category>SQL</category><category>БД</category><category>интерфейс</category><category>кодинг</category><category>ООП</category><category>СУБД</category><category>технология</category><category>хранение данных</category></item></channel></rss>