<?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/apache/feed/index.xml" rel="self"></atom:link><lastBuildDate>Tue, 21 Feb 2012 16:29:00 +0400</lastBuildDate><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>Архитектура 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>Архитектура DISQUS</title><link>https://www.insight-it.ru//highload/2011/arkhitektura-disqus/</link><description>&lt;p&gt;&lt;img alt="DISQUS" class="left" src="https://www.insight-it.ru/images/disqus.jpg" title="DISQUS"/&gt;
&lt;a href="https://www.insight-it.ru/goto/a754581e/" rel="nofollow" target="_blank" title="https://disqus.com"&gt;DISQUS&lt;/a&gt; - самая популярная система
комментирования и одновременно самое большое в мире Django-приложение.
Она установлена более чем на полумиллионе сайтов и блогов, в том числе и
очень крупных, таких как Engadget, CNN, MTV, IGN. Основной особенностью
в её реализации является тот факт, что DISQUS не является тем сайтом,
который хотят увидеть пользователи, он лишь предоставляет механизмы
комментирования, авторизации и интеграции с социальными сетями. Пики
нагрузки возникают одновременно c появлением какой-то шумихи в
Интернете, что достаточно непредсказуемо. Как же им удается справляться
с этой ситуацией?&lt;!--more--&gt;&lt;/p&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/python/"&gt;Python&lt;/a&gt; - язык программирования&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/django/"&gt;Django&lt;/a&gt; - основной framework&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/apache/"&gt;Apache 2.2&lt;/a&gt; +&amp;nbsp;&lt;a href="/tag/wsgi/"&gt;mod_wsgi&lt;/a&gt; - веб-сервер&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/postgresql/"&gt;PostgreSQL&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/haproxy/"&gt;HAProxy&lt;/a&gt; - балансировка нагрузки&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/slony/"&gt;Slony&lt;/a&gt; - репликация данных&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/heartbeat/"&gt;heartbeat&lt;/a&gt; - обеспечение
    доступности&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="statistika"&gt;Статистика&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;До 17 тысяч запросов в секунду&lt;/li&gt;
&lt;li&gt;500 000 сайтов&lt;/li&gt;
&lt;li&gt;15 миллионов зарегистрированных пользователей&lt;/li&gt;
&lt;li&gt;75 миллионов комментариев&lt;/li&gt;
&lt;li&gt;250 миллионов посетителей (на август 2010г.)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="osnovnye-trudnosti"&gt;Основные трудности&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Непредсказуемость нагрузки (основными причинами шумихи в Интернете
    являются катастрофы и выходки знаменитостей)&lt;/li&gt;
&lt;li&gt;Обсуждения никогда не теряют актуальность (нельзя держать в кэше все
    дискуссии с 2008 года)&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;p&gt;&lt;img alt="Архитектура DISQUS" class="responsive-img" src="https://www.insight-it.ru/images/disqus_architecture.jpeg" title="Архитектура DISQUS"/&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Оборудование&lt;/strong&gt;, в сумме около 100 серверов:&lt;ul&gt;
&lt;li&gt;30% веб-серверов (Apache + &lt;code&gt;mod_wsgi&lt;/code&gt;)&lt;/li&gt;
&lt;li&gt;10% серверов баз данных (PostgreSQL)&lt;/li&gt;
&lt;li&gt;25% кэш-серверов (memcached)&lt;/li&gt;
&lt;li&gt;20% балансировка нагрузки и обеспечение доступности (HAProxy +
    heartbeat)&lt;/li&gt;
&lt;li&gt;15% прочие сервера (Python скрипты)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Балансировка нагрузки&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;HAProxy:&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;ul&gt;
&lt;li&gt;Используется Slony-I&lt;/li&gt;
&lt;li&gt;Основана на триггерах&lt;/li&gt;
&lt;li&gt;Master/Slave для обеспечения большего объема операций чтения&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Высокая доступность&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;heartbeat&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;ul&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;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;Механизм роутеров в Django позволяет достаточно легко
    реализовать данный функционал&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;em&gt;Горизонтальное:&lt;/em&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;/ul&gt;
&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;Логирование медленных запросов (автоматизировано с помощью
    syslog-ng + pgFouine + cron)&lt;/li&gt;
&lt;li&gt;Использование пулов соединений (Django не умеет этого,
    используется pgbouncer, позволяет экономить на ресурсоемких
    операциях установления и прекращения соединений)&lt;/li&gt;
&lt;li&gt;Оптимизация QuerySet'ов:&lt;ul&gt;
&lt;li&gt;Не используется чистый SQL&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;Использование update(), так как save() не является
    thread-safe&lt;/li&gt;
&lt;li&gt;Отлично работают для таких вещей, как счетчики&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;Транзакции:&lt;ul&gt;
&lt;li&gt;TransactionMiddleware поначалу использовалось, но со
    временем стало обузой&lt;/li&gt;
&lt;li&gt;В &lt;code&gt;postgrrsql_psycopg2&lt;/code&gt; есть опция autocommit:&lt;ul&gt;
&lt;li&gt;Это означает что каждый запрос выполняется в отдельной
    транзакции&lt;/li&gt;
&lt;li&gt;Обработка каждого пользовательского HTTP-запроса не
    начинает новую транзакцию&lt;/li&gt;
&lt;li&gt;Но все же транзакции из нескольких операций записи в
    СУБД нужны (сохранение нескольких объектов одновременно
    и полный откат в случае ошибки)&lt;/li&gt;
&lt;li&gt;В итоге все HTTP-запросы по-умолчанию начинаются в
    режиме autocommit, но в случае необходимости
    переключаются в транзакционный режим&lt;/li&gt;
&lt;/ul&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;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;strong&gt;Кэширование&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;Используется memcached&lt;/li&gt;
&lt;li&gt;Новый pylibmcна основе libmemcached в качестве клиента (проекты
    django-pylibmc и django-newcache)&lt;/li&gt;
&lt;li&gt;Настраиваемые алгоритмы поведения клиента&lt;/li&gt;
&lt;li&gt;Используется &lt;code&gt;_auto_reject_hosts&lt;/code&gt; и &lt;code&gt;_retry_timeout&lt;/code&gt; для
    предотвращения повторных подключений к вышедшим из строя
    кэш-серверам&lt;/li&gt;
&lt;li&gt;Алгоритм размещения ключей: консистентное хэширование на основе
    libketama&lt;/li&gt;
&lt;li&gt;Существует проблема, когда одно очень часто используемое
    значение в кэше инвалидируется:&lt;ul&gt;
&lt;li&gt;Множество клиентов одновременно пытаются получить новое
    значение из СУБД одновременно&lt;/li&gt;
&lt;li&gt;В большинстве случаев правильным решением было бы вернуть
    большинству устаревшие данные и позволить одному клиенту
    обновить кэш&lt;/li&gt;
&lt;li&gt;django-newcache и MintCache умеют это делать&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;ul&gt;
&lt;li&gt;Информация о производительности запросов к БД, внешних вызовов и
    рендеринге шаблонов записывается через собственный middleware&lt;/li&gt;
&lt;li&gt;Сбор и отображение с помощью Ganglia&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;/li&gt;
&lt;li&gt;Позволяет запускать новые возможности постепенно, лишь для части
    аудитории&lt;/li&gt;
&lt;li&gt;Позволяет постоянно использовать основную ветку кода&lt;/li&gt;
&lt;li&gt;Аналогичная система используется и в &lt;a href="/tag/facebook/"&gt;Facebook&lt;/a&gt;&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;Месячная аудитория / количество разработчиков = 40 миллионов&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;Установить и настроить PostgreSQL&lt;/li&gt;
&lt;li&gt;Скачать исходный код из &lt;a href="/tag/git/"&gt;git&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;С помощью pip и virtualenv установить зависимости&lt;/li&gt;
&lt;li&gt;Изменить настройки в settings.py&lt;/li&gt;
&lt;li&gt;Выполнить автоматическое создание структуры данных
    средствами Django&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;ul&gt;
&lt;li&gt;Ежедневное развертывание с помощью &lt;a href="/tag/fabric/"&gt;Fabric&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="/tag/hudson/"&gt;Hudson&lt;/a&gt; обеспечивает регулярно осуществляет и
    тестирует сборки&lt;/li&gt;
&lt;li&gt;Интегрирован &lt;a href="/tag/selenium/"&gt;Selenium&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Быстрое тестирование с помощью &lt;a href="/tag/pyflakes/"&gt;Pyflakes&lt;/a&gt; и
    post-commit hooks&lt;/li&gt;
&lt;li&gt;70 тысяч строк Python кода, 73% покрытие тестами, прогон всех
    тестов занимает 20 минут&lt;/li&gt;
&lt;li&gt;Собственная система исполнения тестов с поддержкой XML,
    Selenium, подсчета количества запросов, тестирования
    Master/Slave базы данных и интеграцией с очередью&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Отслеживание проблем и задач&lt;/strong&gt;:&lt;ul&gt;
&lt;li&gt;Переключились с Trac на Redmine (из-за поддержки под-задач)&lt;/li&gt;
&lt;li&gt;Отправка исключений на e-mail - плохая идея&lt;/li&gt;
&lt;li&gt;Раньше использовали django-db-log, но теперь опубликовали свою
    систему сбора ошибок и логов под названием
    &lt;a href="https://www.insight-it.ru/goto/2e33ac0/" rel="nofollow" target="_blank" title="https://github.com/dcramer/django-sentry"&gt;Sentry&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="delaem-vyvody"&gt;Делаем выводы&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;Язык программирования, каким бы он ни был, не является проблемой&lt;/li&gt;
&lt;li&gt;Django в целом очень хорош (но приходится все же использовать набор
    собственных патчей)&lt;/li&gt;
&lt;li&gt;Даже при использовании низкопроизводительного framework можно
    построить масштабируемую систему&lt;/li&gt;
&lt;li&gt;Вертикальное партиционирование позволяет пожертвовать
    производительностью в пользу масштабируемости&lt;/li&gt;
&lt;li&gt;Даже небольшой командой разработчиков можно добиться высоких
    результатов, если не пренебрегать автоматизацией тестирования&lt;/li&gt;
&lt;li&gt;Большое значение имеет возможность вовремя отслеживать и оперативно
    реагировать на сбои&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="istochnik-informatsii"&gt;Источник информации&lt;/h2&gt;
&lt;p&gt;Данная статья написана на основе выступления Jason Yan и David Cramer на
DjangoConf 2010. В презентации можно найти примеры кода, ссылки на
упоминаемые проекты и дополнительные материалы:&lt;/p&gt;
&lt;div class="video-container no-controls"&gt;
&lt;iframe allowfullscreen="" frameborder="0" height="355" marginheight="0" marginwidth="0" scrolling="no" src="//www.slideshare.net/slideshow/embed_code/key/21F2PzBmYATx2Y" width="425"&gt; &lt;/iframe&gt;
&lt;/div&gt;
&lt;p&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;. Вчера, кстати, прикрутил DISQUS к
Insight IT, приглашаю постоянных читателей и всех остальных
потестировать :)&lt;/em&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Wed, 02 Mar 2011 03:37:00 +0300</pubDate><guid>tag:www.insight-it.ru,2011-03-02:highload/2011/arkhitektura-disqus/</guid><category>Apache</category><category>DISQUS</category><category>django</category><category>Fabric</category><category>Ganglia</category><category>Git</category><category>HAProxy</category><category>heartbeat</category><category>Hudson</category><category>Linux</category><category>Memcached</category><category>pgbouncer</category><category>pgFouine</category><category>PostgreSQL</category><category>Pyflakes</category><category>Python</category><category>Selenium</category><category>Slony</category><category>syslog-ng</category><category>WSGI</category><category>Архитектура DISQUS</category><category>Масштабируемость</category></item><item><title>Новое поколение MapReduce в Apache Hadoop</title><link>https://www.insight-it.ru//storage/2011/novoe-pokolenie-mapreduce-v-apache-hadoop/</link><description>&lt;p&gt;В большом бизнесе использование нескольких больших кластеров с
финансовой точки зрения более&amp;nbsp;эффективно, чем много маленьких. Чем
больше машин в кластере, тем большими наборами данных он может
оперировать, больше задач могут выполняться одновременно. Реализация
&lt;a href="/tag/mapreduce/"&gt;MapReduce&lt;/a&gt; в &lt;a href="/tag/apache/"&gt;Apache&lt;/a&gt;
&lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt; столкнулась с потолком масштабируемости на уровне
около 4000 машин в кластере. Разрабатывается следующее поколение Apaсhe
Hadoop MapReduce, &amp;nbsp;в котором появится общий планировщик ресурсов и
отдельный мастер для каждой отдельной задач, управляющий выполнением
программного кода. Так как простой оборудования по техническим причинам
обходится дорого на таком масштабе, высокий уровень доступности
проектируется с самого начала, ровно как и безопасность и
многозадачность, необходимые для поддержки одновременного использования
большого кластера многими пользователями. Новая архитектура также будет
более инновационной, гибкой и эффективной с точки зрения использования
вычислительных ресурсов.&lt;/p&gt;
&lt;!--more--&gt;
&lt;h2 id="predistoriia"&gt;Предистория&lt;/h2&gt;
&lt;p&gt;Текущая реализация Hadoop MapReduce устаревает на глазах. Основываясь на
текущих тенденциях в размерах кластеров и нагрузок на них, JobTracker
требует кардинальных доработок, чтобы исправить его дефекты в области
масштабируемости, потребления памяти, многопоточности, надежности и
производительности. С точки зрения работы с Hadoop при каждом обновлении
кластера (даже если это просто багфикс), абсолютно все компоненты
кластера, так и приложений, которые на нем работают, должны быть
обновлены одновременно. Это так же очень неудобно, так как каждый раз
необходимо тестировать все приложения на совместимость с новой версией.&lt;/p&gt;
&lt;h2 id="trebovaniia"&gt;Требования&lt;/h2&gt;
&lt;p&gt;Прежде чем кардинально что-то менять в Hadoop mapreduce, необходимо
понять какие же основные требования предъявляются к вычислительным
кластерам на практике. Наиболее значительными требованиями к Hadoop
следующего поколения являются:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Надежность&lt;/li&gt;
&lt;li&gt;Доступность&lt;/li&gt;
&lt;li&gt;Масштабируемость - кластеры из как минимум 10 тысяч машин, 200 тысяч
    вычислительных ядер и даже больше&lt;/li&gt;
&lt;li&gt;Обратная и прямая совместимость - возможность быть уверенным, что
    приложение будет работать на новой версии так же, как оно работало
    на старой&lt;/li&gt;
&lt;li&gt;Контроль над обновлениями&lt;/li&gt;
&lt;li&gt;Предсказуемые задержки&lt;/li&gt;
&lt;li&gt;Эффективное использование ресурсов&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Среди менее значительных требований:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Поддержка альтернативных парадигм разработки (помимо MapReduce)&lt;/li&gt;
&lt;li&gt;Поддержка сервисов с коротким жизненным циклом&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Если учесть перечисленные выше требования, то становится очевидно, что
инфраструктура обработки данных в Hadoop должна быть кардинальным
образом изменена. В сообществе Hadoop люди в целом приходят к общему
мнению, что текущая архитектура MapReduce не способна решить текущие
задачи, которые перед ней ставится, и что требуется кардинальный
рефакторинг кодовой базы.&lt;/p&gt;
&lt;h2 id="mapreduce-sleduiushchego-pokoleniia"&gt;MapReduce следующего поколения&lt;/h2&gt;
&lt;p&gt;Фундаментальной идеей смены архитектуры является разделение двух
основных функций JobTracker'а на два отдельных части:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;управление ресурсами;&lt;/li&gt;
&lt;li&gt;планирования и мониторинга задач.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;В итоге появляется несколько новых ролей:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;ResourceManager&lt;/strong&gt; управляет глобальным распределением
    вычислительных ресурсов между приложениями;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;ApplicationMaster&lt;/strong&gt; управляет планированием и координацией внутри
    приложения;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;NodeManager&lt;/strong&gt; управляет процессами в рамках одной машины.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;ApplicationMaster представляет собой библиотеку, с помощью которой можно
получить у ResourceManager квоту на вычислительные ресурсы и работать с
NodeManager(ами) для выполнения и мониторинга задач.&lt;/p&gt;
&lt;p&gt;ResourceManager поддерживает иерархическим очереди приложений, которым
может гарантированно выделяться некоторый процент ресурсов кластера. Его
функционал ограничивается планированием, никакого мониторинга и
отслеживания задач не происходит, а также нет никаких гарантий
перезапуска задач, провалившихся из-за проблем с оборудованием или
кодом. Планирование основывается на требованиях, которые выставляет
приложение с помощью ряда запросов ресурсов (среди них: запросы на
вычислительные ресурсы, память, дисковое пространство, сетевой доступ и
т.п.). Обратите внимание, что это значительное изменение по сравнению с
текущей моделью слотов фиксированного размера, которая является одной из
основных причин неэффективного использования ресурсов кластера на данный
момент.&lt;/p&gt;
&lt;p&gt;NodeManager - это агент, который работает на каждой машине и несет
ответственность за запуск контейнеров приложений, мониторинг
используемых ими ресурсов (плюс отчет планировщику).&lt;/p&gt;
&lt;p&gt;По одному ApplicationMaster запускается для каждого приложения, они
ответственны за запрос необходимых ресурсов у планировщика, запуск
задач, отслеживание статусов, мониторинг прогресса и обработку сбоев.&lt;/p&gt;
&lt;h2 id="arkhitektura"&gt;Архитектура&lt;/h2&gt;
&lt;p&gt;&lt;img alt="Следующее поколение MapReduce" class="responsive-img" src="https://www.insight-it.ru/images/mapreduce-nextgen.jpg" title="Следующее поколение MapReduce"/&gt;&lt;/p&gt;
&lt;h2 id="uluchsheniia-po-sravneniiu-s-tekushchei-realizatsiei-mapreduce"&gt;Улучшения по сравнению с текущей реализацией MapReduce&lt;/h2&gt;
&lt;h3 id="masshtabiruemost"&gt;Масштабируемость&lt;/h3&gt;
&lt;p&gt;Разделение управления ресурсами и прикладными задачами позволяет
горизонтально расширять кластер более просто и эффективно. JobTracker
проводит значительную часть времени пытаясь управлять жизненным циклом
каждого приложения, что часто может приводить к различным
происшествиям - переход к отдельному менеджеру для каждого приложения
является значительным шагом вперед.&lt;/p&gt;
&lt;p&gt;Масштабируемость особенно важна в свете текущих трендов в оборудовании -
на данный момент Hadoop может быть развернут на кластере из 4000 машин.
Но 4000 средних машин 2009го года (т.е. по 8 ядер, 16Гб памяти, 4Тб
дискового пространства) только вдвое менее &amp;nbsp;ресурсоемки, чем 4000 машин
2011го года (16 ядер, 48гб памяти, 24Тб дискового пространства). Помимо
этого с точки зрения операционных издержек было выгоднее работать в еще
больших кластере от 6000 машин и выше.&lt;/p&gt;
&lt;h3 id="dostupnost"&gt;Доступность&lt;/h3&gt;
&lt;ul&gt;
&lt;li&gt;ResourceManager использует&amp;nbsp;&lt;a href="https://www.insight-it.ru/goto/e7095d3/" rel="nofollow" target="_blank" title="http://hadoop.apache.org/zookeeper/"&gt;Apache ZooKeeper&lt;/a&gt; для обработки сбоев.
    Когда ResourceManager перестает работать, аналогичный процесс может
    быстро запуститься на другой машине благодаря тому, что состояние
    кластера было сохранено в ZooKeeper. При таком сценарии все
    запланированные и выполняющиеся приложения максимум лишь
    перезапустятся.&lt;/li&gt;
&lt;li&gt;ApplicationMaster - поддерживается создание точек восстановления на
    уровне приложений. ApplicationMaster может восстановить работу из
    состояния, сохраненного в HDFS, в случае сбоя.&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="sovmestimost-protokola"&gt;Совместимость протокола&lt;/h3&gt;
&lt;p&gt;Это позволит различным версиям клиентов и серверов Hadoop общаться между
собой. Помимо решения многих существующих проблем с обновлением, в
будующих релизах появится возможность последовательного обновления кода
без простоя системы в целом - очень большое достижения с точки зрения
системного администрирования.&lt;/p&gt;
&lt;h3 id="innovatsionnost-i-gibkost"&gt;Инновационность и гибкость&lt;/h3&gt;
&lt;p&gt;Основным плюсом предложенной архитектуры является тот факт, что
MapReduce по сути становится просто пользовательской библиотекой.
Вычислительная же система (ResourceManager и NodeManager) становятся
полностью независимыми от специфики MapReduce.&lt;/p&gt;
&lt;p&gt;Клиенты получат возможность одновременного использования разных версий
MapReduce в одном и том же кластере. Это становится тривиальным, так как
отдельная копия ApplicationMaster'а запускается для каждого приложения.
Это дает гибкость в исправлении багов, улучшений и новых возможностей,
так как полное обновление кластер перестает быть обязательной
процедурой. Это позволяет клиентам обновлять их приложения до новых
версий MapReduce вне зависимости от обновлений кластера.&lt;/p&gt;
&lt;h3 id="effektivnost-ispolzovaniia-vychislitelnykh-resursov"&gt;Эффективность использования вычислительных ресурсов&lt;/h3&gt;
&lt;p&gt;ResourceManager использует общую концепцию для управления ресурсами и
планирования по отношению к каждому конкретному приложению. Каждая
машина в кластере на концептуальном уровне рассматривается просто как
набор ресурсов: память, процессор, ввод-вывод и др. Все машины
взаимозаменяемы и приложение может быть назначено на любую из них,
основываясь на доступных и запрашиваемых ресурсах. При этом приложения
работают в контейнерах, изолированно от других приложений, что дает
сильную поддержку многозадачности.&lt;/p&gt;
&lt;p&gt;Таким образом эта схема избавляет от текущего механизма map и reduce
слотов в Hadoop, который негативно влияет на эффективную утилизацию
вычислительных ресурсов.&lt;/p&gt;
&lt;h3 id="podderzhka-drugikh-paradigm-programmirovaniia-pomimo-mapreduce"&gt;Поддержка других парадигм программирования помимо MapReduce&lt;/h3&gt;
&lt;p&gt;В предложенной архитектуре используется общий механизм вычислений, не
привязанный конкретно к MapReduce, что позволит использовать и другие
парадигмы. Имеется возможность реализовать собственный
ApplicationMaster, способный запрашивать ресурсы у ResourceManager и
использовать их в соответствии с задачей, при этом сохраняются общие
принципы изоляции и гарантированного наличия полученных ресурсов. Среди
потенциально поддерживаемых парадигм можно назвать MapReduce, MPI,
Мaster-Worker, итеративные модели. Все они могут одновременно работать
на одном и том же кластере. Это особенно актуально для приложений
(например К-средний или Page Rank), где &lt;a href="https://www.insight-it.ru/python/2011/piccolo-postroenie-raspredelennykh-sistem-v-11-raz-bystree-hadoop/"&gt;другие подходы более чем на порядок эффективнее&lt;/a&gt; MapReduce.&lt;/p&gt;
&lt;h2 id="vyvody_1"&gt;Выводы&lt;/h2&gt;
&lt;p&gt;Apache Hadoop, и в частности Hadoop MapReduce - очень успешный
opensource проект по обработке больших объемов данных. Предложенный
Yahoo путь его переработки направлен на исправление недостатков
архитектуры текущей реализации, при этом повышая доступность,
эффективность использования ресурсов и предоставляя поддержку других
парадигм распределенных вычислений.&lt;/p&gt;
&lt;p&gt;Осталось дело за малым - собственно реализовать задуманное! :)&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;&lt;a href="https://www.insight-it.ru/goto/336fc03c/" rel="nofollow" target="_blank" title="http://developer.yahoo.com/blogs/hadoop/posts/2011/02/mapreduce-nextgen/"&gt;Источник информации&lt;/a&gt;&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;em&gt;&lt;a href="/feed/"&gt;Подписаться на RSS можно здесь.&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;</description><dc:creator xmlns:dc="http://purl.org/dc/elements/1.1/">Иван Блинков</dc:creator><pubDate>Sat, 19 Feb 2011 21:23:00 +0300</pubDate><guid>tag:www.insight-it.ru,2011-02-19:storage/2011/novoe-pokolenie-mapreduce-v-apache-hadoop/</guid><category>Apache</category><category>Apache Hadoop</category><category>Hadoop</category><category>архитектура</category><category>кластер</category><category>кластеризация</category><category>кластерные вычисления</category><category>Масштабируемость</category><category>разработка</category><category>технологии</category></item><item><title>Архитектура Вконтакте</title><link>https://www.insight-it.ru//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>Hadoop возвращается</title><link>https://www.insight-it.ru//storage/2008/hadoop-vozvrashhaetsya/</link><description>&lt;p&gt;Если Вы являетесь постоянным читателем моего блога, то вполне вероятно,
что Вы помните мой &lt;a href="https://www.insight-it.ru/storage/2008/hadoop/"&gt;старый пост&lt;/a&gt; об этом
замечательном проекте от &lt;a href="https://www.insight-it.ru/goto/e3b03afc/" rel="nofollow" target="_blank" title="http://apache.org"&gt;Apache Foundation&lt;/a&gt;. С тех
пор он развивался невероятными темпами и очень многое успело измениться,
об этом я и хотел бы сегодня поделиться своими впечатлениями. В
дополнение к этому планируется небольшая инструкция по развертыванию
Hadoop на кластере из большого количества машин, который послужит
неплохим развитием темы, начатой в посте &lt;a href="https://www.insight-it.ru/storage/2008/hadoop-dlya-razrabotchika/"&gt;"Hadoop для разработчика"&lt;/a&gt;.
&lt;!--more--&gt;&lt;/p&gt;
&lt;h3 id="chto-novogo"&gt;Что нового?&lt;/h3&gt;
&lt;p&gt;Для начала вкратце напомню что их себя представляет данный продукт,
всего в нем три компонента:&lt;/p&gt;
&lt;dl&gt;
&lt;dt&gt;&lt;strong&gt;HDFS&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;кластерная файловая система.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;MapReduce framework&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;программная основа для построения приложений, работающих по
одноименной модели.&lt;/dd&gt;
&lt;dt&gt;&lt;strong&gt;HBase&lt;/strong&gt;&lt;/dt&gt;
&lt;dd&gt;нереляционная база данных.&lt;/dd&gt;
&lt;/dl&gt;
&lt;p&gt;Повторно повторяться смысла не вижу, все уже давно &lt;a href="https://www.insight-it.ru/storage/2008/hadoop/"&gt;разложено по полочкам&lt;/a&gt;. Так что сразу перейдем к глобальным
изменениям в проекте, произошедшим с написания вышеупомянутого поста, то
есть с февраля. Сразу хочу сказать, что подробно пересказывать &lt;a href="https://www.insight-it.ru/goto/81620ac0/" rel="nofollow" target="_blank" title="http://svn.apache.org/repos/asf/hadoop/core/trunk/CHANGES.txt"&gt;release notes&lt;/a&gt; у
меня нет никакого желания, если Вам интересны все подробности о каждом
bugfix'е или изменении в API, то имеет смысл почитать их в оригинале.&lt;/p&gt;
&lt;p&gt;Наиболее значительным событием в развитии Apache Hadoop было, пожалуй,
отделение &lt;a href="/tag/hbase/"&gt;HBase&lt;/a&gt; в отдельный проект. Какие же это повлекло
последствия? С точки зрения простого смертного наиболее заметен тот
факт, что HBase пропал из основного архива или репозитория Hadoop и его
теперь нужно качать отдельно :) На самом же деле такое обособление лишь
ускорило ее развитие, совсем недавно HBase отпраздновала свой релиз
версии 0.2.0, включающий в себя массу нововведений и исправленных
проблем, например язык запросов HQL был полностью заменен на jirb/jython
shell, а также было добавлено кэширование данных в памяти. Помимо этого
сильно изменилось API, очень рекомендую заглянуть в
&lt;a href="https://www.insight-it.ru/goto/f059ad5e/" rel="nofollow" target="_blank" title="http://hadoop.apache.org/hbase/docs/current/api/index.html"&gt;javadoc&lt;/a&gt;
проекта, если Вас это интересует.&lt;/p&gt;
&lt;p&gt;На уровне файловой системы наиболее значительным изменением стало
добавление еще одного типа узлов - &lt;strong&gt;Secondary NameNode&lt;/strong&gt;. Это
нововведение является первым шагом на пути к устранению узких мест в
системе (так называемых single points of failure). Название этого типа
узлов говорит само за себя: они подстраховывают основной &lt;em&gt;NameNode&lt;/em&gt; на
случай непредвиденных сбоев. Они создают резервную копию образа
метаданных файловой системы и лога транзакций (то есть всех операций с
файлами и директориями в HDFS) и периодически ее обновляют. Полноценного
автоматического восстановления системы они в случае сбоя на сервере с
&lt;em&gt;NameNode&lt;/em&gt; они на данный момент не обеспечивают, но сохранность данных
на случай, скажем, разрушившегося RAID обеспечить могут.&lt;/p&gt;
&lt;p&gt;MapReduce framework тоже несомненно развивается и дорабатывается, но
каких-либо особо выдающихся изменений в нем не произошло: появляются
дополнительные возможности, исправляются ошибки, снимаются те или иные
ограничения. В общем все идет своим чередом.&lt;/p&gt;
&lt;h3 id="podnimaem-klaster"&gt;Поднимаем кластер&lt;/h3&gt;
&lt;div class="card blue lighten-4"&gt;
&lt;div class="card-content"&gt;
&lt;h5&gt;ВНИМАНИЕ!&lt;/h5&gt;
&lt;p&gt;Перед продолжением чтения этого раздела, настоятельно рекомендуется
прочитать &lt;a href="https://www.insight-it.ru/storage/2008/hadoop-dlya-razrabotchika/"&gt;статью о запуске псевдо-кластера из одного компьютера&lt;/a&gt;.
&lt;/p&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;Для начала нам понадобится некоторое количество компьютеров (хотя если у
Вас серьезные намерения, то лучше все же гордо называть их серверами, а
для "побаловаться" сойдут и обычные рабочие станции с
&lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt;). Конкретное количество на самом деле роли не
играет, продолжать можно как с 2 серверами, так и с 20 тысячами (по
крайней мере теоретически). Хотя пару рекомендаций все же могу дать: при
использовании в "боевых" условиях стоит стараться избегать физического
совмещения мастер-узлов компонентов системы (&lt;em&gt;NameNode, JobTracker,
HMaster&lt;/em&gt;) с "рядовыми" серверами, таким образом желательно начинать с,
как минимум, 5-7 серверов.&lt;/p&gt;
&lt;p&gt;Удостоверившись, что на всем оборудовании установлен какой-нибудь
дистрибутив &lt;a href="/tag/linux/"&gt;Linux&lt;/a&gt; или &lt;a href="/tag/unix/"&gt;Unix&lt;/a&gt; (любители особо
поизвращаться могут попытать счастья с "окнами" в совокупности с Cygwin)
и 5 или 6 версия JRE/JDK (желательно от Sun), можно приступать к
настройке каждого узла по тому же принципу, что и для псевдо-кластера
(да-да, предупреждение в начале раздела было написано не для мебели).
Кстати не забудьте, что &lt;a href="/tag/hbase/"&gt;HBasе&lt;/a&gt; теперь нужно скачивать
отдельно. О небольших присутствующих особенностях я расскажу чуть позже,
а пока дам маленький совет, который позволит несколько облегчить это
непростое дело.&lt;/p&gt;
&lt;p&gt;Вручную выполнять одни и те же операции на паре десятков/сотен/тысяч
серверов мало того что долго, но и чрезвычайно утомительно. Уже на
втором-третьем сервере начнет появляться желание каким-либо образом
автоматизировать процесс установки. Конечно же можно воспользоваться
специализированным программным обеспечением, скажем
&lt;a href="https://www.insight-it.ru/goto/65d64e55/" rel="nofollow" target="_blank" title="http://www.theether.org/gexec/"&gt;gexec&lt;/a&gt;, но есть и более простой способ:
существенно упростить жизнь может простой скрипт на bash в 5 строчек:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; x in &lt;span class="sb"&gt;`&lt;/span&gt;cat ~/nodes&lt;span class="sb"&gt;`&lt;/span&gt;
&lt;span class="k"&gt;do&lt;/span&gt;
ssh hadoop@&lt;span class="nv"&gt;$x&lt;/span&gt; &lt;span class="nv"&gt;$1&lt;/span&gt;
&lt;span class="k"&gt;done&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;В файле &lt;code&gt;~/nodes&lt;/code&gt; должен располагаться список IP-адресов всех
серверов, тогда получив первым параметром произвольную консольную
команду скрипт выполнит ее на каждом сервере. С его помощью можно
существенно сократить время, требуемое на выполнение всех необходимых
действий для запуска кластера.&lt;/p&gt;
&lt;p&gt;После небольшого лирического отступления вернемся собственно к
&lt;a href="/tag/hadoop/"&gt;Hadoop&lt;/a&gt;. Как Вы уже, надеюсь, знаете, система использует
&lt;strong&gt;ssh&lt;/strong&gt; для управления всеми компонентами системы, причем очень
желателен беспарольный доступ между всеми узлами. Для этого необходимо
собрать в один файл все публичные ключи &lt;code&gt;~/.ssh/id_rsa.pub&lt;/code&gt; на
каждом из узлов (по одному на строчку) и разместить его под именем
&lt;code&gt;~/.ssh/authorized_keys&lt;/code&gt; тоже на каждом из узлов. Кстати для
упоминавшегося выше скрипта беспарольный доступ тоже очень желателен.&lt;/p&gt;
&lt;p&gt;Следующим этапом нужно подготовить конфигурационные файлы, они должны
быть идентичными на всех узлах, так что заполнив их все на одном из
узлов нужно скопировать их по всем остальным серверам (очень удобно
делать это с помощью &lt;strong&gt;rsync&lt;/strong&gt;). Теперь пройдемся по необходимым
изменениям в каждом из них:&lt;/p&gt;
&lt;h4&gt;hadoop-site.xml&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;fs.default.name&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;hdfs://namenode:54310&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;
    The name of the default file system.  A URI whose
    scheme and authority determine the FileSystem implementation.  The
    uri's scheme determines the config property (fs.SCHEME.impl) naming
    the FileSystem implementation class.  The uri's authority is used to
    determine the host, port, etc. for a filesystem.
  &lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;mapred.job.tracker&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;jobtracker:54311&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;
    The host and port that the MapReduce job tracker runs
    at.  If "local", then jobs are run in-process as a single map
    and reduce task.
  &lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Каждый сервер должен знать где расположен &lt;em&gt;NameNode&lt;/em&gt;, по-этому он
  явно указывается в полном пути к файловой системе, практически
  аналогичная ситуация и с &lt;em&gt;JobTracker&lt;/em&gt;. Вместо namenode и jobtracker
  необходимо указать их IP-адреса или доменные имена (или в крайнем
  случае - имя в &lt;code&gt;/etc/hosts&lt;/code&gt;)&lt;/p&gt;
&lt;h4&gt;masters&lt;/h4&gt;
&lt;p&gt;Вопреки логике, здесь указывается список всех &lt;em&gt;SecondaryNameNode&lt;/em&gt;.
Одного-двух серверов здесь будет вполне достаточно, самое главное не
указывать здесь адрес основного &lt;em&gt;NameNode&lt;/em&gt;, лучше всего подойдет
какой-нибудь другой мастер-сервер, может быть дополненный одним из
обычных узлов кластера. Выделять под это отдельный сервер смысла не
много, так как нагрузка на них минимальна.&lt;/p&gt;
&lt;h4&gt;slaves&lt;/h4&gt;
&lt;p&gt;Список всех рядовых серверов, по одному на строку (опять же: IP или доменное имя). На них будут запущенны &lt;em&gt;DataNode&lt;/em&gt; и &lt;em&gt;TaskTracker&lt;/em&gt;.&lt;/p&gt;
&lt;h4&gt;hbase-site.xml&lt;/h4&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nt"&gt;&amp;lt;property&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;hbase.master&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;value&amp;gt;&lt;/span&gt;localhost:60000&lt;span class="nt"&gt;&amp;lt;/value&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;description&amp;gt;&lt;/span&gt;
    the host and port that the HBase master runs at
  &lt;span class="nt"&gt;&amp;lt;/description&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/property&amp;gt;&lt;/span&gt;
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Первое изменение достаточно очевидно: &lt;em&gt;HRegionServer&lt;/em&gt; должны знать
где находится &lt;em&gt;HMaster&lt;/em&gt;, о чем им и сообщает первое свойство
(заменяем hmaster на соответствующий адрес). А вот второе свойство
является следствием "обособления" HBase от Hadoop, о котором шла
речь ранее. Теперь имеется возможность использовать их отдельно (с
локальной файловой системой вместо HDFS), а так как появился выбор
файловой системы - ее адрес необходимо указывать полностью. В данном
случае указан адрес HDFS (такой же как в &lt;strong&gt;hadoop-site.xml&lt;/strong&gt;).&lt;/p&gt;
&lt;h4&gt;regionservers&lt;/h4&gt;
&lt;p&gt;Вполне очевидный конфигурационный файл, по аналогии со &lt;strong&gt;slaves&lt;/strong&gt;,
заполняется списком адресов для запуска &lt;em&gt;HRegionServer&lt;/em&gt;. Часто
совпадает с упомянутым &lt;strong&gt;slaves&lt;/strong&gt;, обычно достаточно просто
скопировать.&lt;/p&gt;
&lt;h3 id="zapusk"&gt;Запуск&lt;/h3&gt;
&lt;p&gt;Удостоверившись, что с конфигурационными файлами все нормально и что они
на всех серверах совпадают, можно приступать собственно к запуску. Этот
процесс практически полностью совпадает с запуском на одном узле, хотя
обычно проще желать это тоже простеньким скриптом примерно такого вида:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="c"&gt;#!/bin/bash&lt;/span&gt;
ssh hadoop@namenode ~/hadoop/bin/start-dfs.sh
ssh hadoop@jobtracker ~/hadoop/bin/start-mapred.sh
ssh hadoop@hmaster ~/hbase/bin/start-hbase.sh
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;Если мы нигде не ошиблись и все сделано правильно, то кластер
благополучно запустится, что легко проследить выполнив на каждом узле
команду &lt;code&gt;jps&lt;/code&gt; и проверив соответствие запущенных компонентов
запланированному (читай: указанному в конфигурационных файлах).&lt;/p&gt;
&lt;p&gt;В целом процесс достаточно прост и не занимает много времени, если Вы
все же столкнулись с какими-либо проблемами в процессе - обращайтесь,
вполне возможно, что я смогу помочь. Удостовериться, что все нормально
можно абсолютно так же, как и для псевдо-кластера - с помощью MapReduce
задач, идущих в комплекте с Hadoop. Выглядеть это может, например, вот
так:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span class="nv"&gt;$ &lt;/span&gt;~/hadoop/bin/hadoop jar hadoop-*-examples.jar pi &lt;span class="m"&gt;4&lt;/span&gt; 10000
&lt;/pre&gt;&lt;/div&gt;
&lt;p&gt;По-хорошему надо было бы написать подобную инструкцию сразу после
первой, но почему-то как-то не сложилось...&lt;/p&gt;
&lt;h3 id="zakliuchenie"&gt;Заключение&lt;/h3&gt;
&lt;p&gt;На данный момент &lt;a href="/tag/hadoop/"&gt;Hadoop&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>Sun, 17 Aug 2008 23:15:00 +0400</pubDate><guid>tag:www.insight-it.ru,2008-08-17:storage/2008/hadoop-vozvrashhaetsya/</guid><category>Apache</category><category>Hadoop</category><category>HBase</category><category>HDFS</category><category>MapReduce</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>Архитектура 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>Архитектура 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></channel></rss>