Игорь Олемской — практические заметки по системному администрированию Linux CentOS

Архив тега ‘производительность’

Sysbench — тестируем производительность MySQL и платформы (перепечатка)

Комментариев нет

Sysbench — утилита для тестирования производительности MySQL (и других СУБД), а также параметров операционной системы. Подобный инструмент незаменим для предварительного тестирования эффективности системы с (потенциально) высокой нагрузкой. Sysbench позволяет оценить производительность сервера СУБД и операционной системы в различных условиях при различной нагрузке.


Особенности sysbench

Из преимуществ этого продукта следует отметить его простоту, гибкость, а также:

  • Кроссплатформенность
  • Мультипоточность
  • Набор тестов для параметров уровня ОС (память, файловая система, процессор и т.п.)

Другими словами эта утилита нужна для решения следующих задач:

  • Тестирование параметры ОС (даже без установки СУБД) для предварительной их оценки и последующей настройке
  • Проверка производительности СУБД с различной конфигурацией и нагрузкой


Установка

Эта популярная утилита присутствует в пакетах многих дистрибутивов, поэтому:

sudo apt-get install sysbench

Или собираем из исходников (скачать можно тут):

./configure
make
make install

После этого утилита готова к работе.


Обзор функциональности

Синтаксис вызова утилиты:

sysbench --test=имя-теста [опции] команда

Команды, которые можно использовать в тестах:

  • prepare — подготовка теста (создание таблиц, вставка данных и т.п.) если актуально
  • run — выполнение теста
  • cleanup — очистка данных (после этапа подготовки)
  • help — выводит дополнительные параметры теста

Параметр “–test” задает имя теста, который следует выполнять. Sysbench включает в себя несколько тестов:

cpu

Этот тест проверит производительность процессоров, используя вычисления с 64-разрядными числами. Например:

sysbench --test=cpu --cpu-max-prime=20000 run

memory

Этот тест служит для измерения производительности последовательных операций чтения/записи в оперативную память.

fileio

Этот тест используется для симуляции разнообразной нагрузки на файловую подсистему. При подготовке теста создается определенное количество файлов (указанного размера). Затем, при выполнении теста, над этими файлами происходят операции чтения/записи в несколько потоков.

sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw prepare
sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw run
sysbench --num-threads=16 --test=fileio --file-total-size=3G --file-test-mode=rndrw cleanup

threads

Служит для проверки работы в условиях большого количества конкурирующих потоков. Тест заключается в создании нескольких потоков и нескольких мутексов. Далее каждый поток начинает генерировать запросы, которые блокируют мутекс, исполняют процессорные задачи (для симуляции реальной работы) и разблокируют мутекс.

sysbench --num-threads=64 --test=threads --thread-yields=100 --thread-locks=2 run

oltp (Online transaction processing)

Этот тест служит для оценки производительности СУБД, о нем подробнее дальше:


OLTP тестирование — производительность MySQL

Этот тест проводится в несколько этапов. На этапе prepare

sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=10000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp prepare

Эта операция создаст innoDB таблицу на 10000 записей. По умолчанию таблица создается в базе данных sbtest (не забудьте создать эту БД либо указать другую).

Далее выполняются тесты:

sysbench --num-threads=8 --max-requests=500 --oltp-table-size=10000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp run

Эта команда выполнит тест с 8 клиентами (максимальное количество запросов — 500) на таблице, которая была создана на предыдущем этапе. После окончания теста не забудьте выполнить команду cleanup. После выполнения Вы увидите подробные результаты тестирования. Далее — живой пример.

Пример

Посмотрим на производительность innoDB таблицы с разными значениями конфигурационных параметров (проведем эксперимент со сбросом лога). Для начала подготовим innoDB таблицу (50 тыс. записей):

sysbench --test=oltp --mysql-table-engine=innodb --oltp-table-size=50000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp prepare

.

Включим сброс лога на диск после каждой транзакции (используем стандартный метод сброса лога):

innodb_flush_log_at_trx_commit = 1
innodb_flush_method=fdatasync

Выполним тест:

sysbench --num-threads=8 --max-requests=1000 --oltp-table-size=50000 --mysql-user=root --mysql-password=root --db-driver=mysql --test=oltp run

И увидим следующие результаты:

OLTP test statistics:
    queries performed:
        read:                            14000
        write:                           5000
        other:                           2000
        total:                           21000
    transactions:                        1000   (263.49 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 19000  (5006.24 per sec.)
    other operations:                    2000   (526.97 per sec.)

Test execution summary:
    total time:                          3.7953s
    total number of events:              1000
    total time taken by event execution: 30.2361
    per-request statistics:
         min:                                  4.80ms
         avg:                                 30.24ms
         max:                                 53.01ms
         approx.  95 percentile:              33.07ms
Threads fairness:
    events (avg/stddev):           125.0000/0.00
    execution time (avg/stddev):   3.7795/0.01

Убедимя, что пропускная способность операций чтения/записи около 5 тыс в секунду. Теперь изменим параметры сброса лога:

innodb_flush_log_at_trx_commit = 0
innodb_flush_method=O_DIRECT

и проверим результаты:

OLTP test statistics:
    queries performed:
        read:                            14000
        write:                           5000
        other:                           2000
        total:                           21000
    transactions:                        1000   (485.37 per sec.)
    deadlocks:                           0      (0.00 per sec.)
    read/write requests:                 19000  (9222.00 per sec.)
    other operations:                    2000   (970.74 per sec.)

Test execution summary:
    total time:                          2.0603s
    total number of events:              1000
    total time taken by event execution: 16.4255
    per-request statistics:
         min:                                  2.69ms
         avg:                                 16.43ms
         max:                                235.49ms
         approx.  95 percentile:              42.15ms
Threads fairness:
    events (avg/stddev):           125.0000/6.16
    execution time (avg/stddev):   2.0532/0.00

Убеждаемся, что во втором случае пропускная способность СУБД вдвое выше, чем в первом (о параметрах подробнее в статье Оптимальная настройка Mysql сервера).


Альтернативные утилиты

Кроме Sysbench, есть еще ряд инструментов, на который следует обратить внимание:


Ссылки

Официальный сайт Sysbench

Google Bookmarks Digg I.ua Ru-marks Ruspace Zakladok.net Reddit delicious Technorati Yahoo My Web News2.ru БобрДобр.ru Memori.ru rucity.com
Related posts:
  1. Mongo DB — документо-ориентированная база данных и MySQL
  2. check-unused-keys — проверка неиспользуемых индексов в MySQL
  3. Maatkit — расширенные возможности MySQL

Mongo DB — документо-ориентированная база данных и MySQL (перепечатка)

Один комментарий

screenshot-home-mongodb-10gen-confluence-chromium

Одним из основных принципов разработки масштабируемых и эффективных приложений является выбор подходящих технологий для решения той или иной задачи. Многие современные РСУБД представляют из себя решения универсальные, но во многих случаях в них просто нет необходимости.

Одним из альтернативных решений для хранения и обработки данных является СУБД Mongo DB (”humongous” — огромный, невероятный).

Что такое Mongo DB?

Mongo DB — высокопроизводительная документо-ориентированная база данных. Особенности этой СУБД:

  • Документное хранилище, не требующее создания схем (таблиц)
  • Запросы в стиле JSON (очень удобно)
  • Широкий набор (атомарных) операций над данными (условный поиск, сложная вставка/обновление и т.п.)
  • Разные типы данных (поддержка массивов)
  • Поддержка индексов (B-Tree)
  • Автовосстановление, шардинг и репликация в коробке
  • Профилирование, хранение больших объектов, административный интерфейс, серверные функции, Map/Reduce и многое другое

Mongo DB и MySQL

Многое из вышеперечисленного есть и в решениях более знакомых, таких, как MySQL. Давайте сравнивать:

  MongoDB MySQL
Модель данных Документная Реляционная
Типы string, int, double, boolean, date, bytearray, object, array Типы MysQL
Большие объекты Да Да
Репликация Master-slave Master-slave
Хранилище наборов данных Коллекции Таблицы
Метод запросов объектный язык запросов SQL
Дополнительные индексы Да Да
Атомарность Документ Расширенная
Манипулирование наборами данных на сервере Map/Reduce, серверный javascript SQL
Платформа C++ C
Контроль конкурентности (Concurrency Control) Update in Place MVCC

Итак преимущества Mongo:

  • Объектный язык запросов (который намного легче SQL, что является важным преимуществом для большинства задач, не требующих сложных выборок)
  • Поддержка Map/Reduce для распределенных операций над данным
  • Документы, не требующие определения схемы. Одно из самых важных преимуществ. Преимущество заключается в том, что у Вас нет нужды хранить пустые ячейки данных в каждом документе.
  • Поддержка сложных массивов. Каждый элемент массива может представлять из себя объект
  • Поддержка шардинга на уровне платформы

Производительность

Для тестирования возьмем таблицу в MySQL (messages) с простой структурой (таблица личных сообщений пользователей одного из моих проектов). Количество записей в ней — около 200 тыс. Все данные скопированны в mongo с соотв. индексами.

Для тестирования будем использовать следующий скрипт:

<?php
$m = new Mongo();
$col = $m->messages->threads;

$s = microtime(true);
for ( $i = 0; $i < 5000; $i++ )
        $cursor = $col->find( array('user_id' => $i) );

$t = microtime(true) - $s;

echo "Mongo: " .  $t . "\n\n";

mysql_connect('localhost');
mysql_select_db('messages');

$s = microtime(true);
for ( $i = 0; $i < 5000; $i++ )
        mysql_query('SELECT id FROM messages WHERE mailed_by = ' . $i);
$t = microtime(true) - $s;
echo 'MySQL: ' . $t . "\n\n";

Как видно из скрипта, мы сделали по 5000 выборок из обеих СУБД. Поля, по которым проходила выборка являются индексными. Ниже приведены результаты второго запуска скрипта (в первый раз значения были гораздо большими, т.к. таблицы не были подтянуты в память):

Mongo: 0.010502815246582
MySQL: 0.27930092811584

Как видим MySQL справился с однотипной задачей на порядок медленее. Для тестирования были использованы стандартные конфигурации обоих платформ, поэтому настройка может внести изменения в эти результаты.

Когда выбирать Mongo DB, а когда MySQL?

Mongo представляет из себя очень функциональное решение, тем не менее обладает рядом ограничений. Например, возможность сделать JOIN (а нужен ли он?). Также язык запросов Mongo конечно устапает SQL в гибкосте и возможностях. Но нужна ли Вам эта гибкость в Ваших задачах? Одним словом, Mongo подходит почти под любой класс задач, не требующих сложных выборок.

Что же касается MySQL (или родственных продуктов), то он остается решением для задач требующих нетривиальных выборок (например, статистические или аналитически запросы).

Личное впечатление

После первого знакомства с Mongo DB, этот продукт оставил очень хорошее впечатление и заставил вернуться к нему еще раз. Помимо прочих преимуществ:

  • Очень легкий и интуитивно понятный
  • Простая установка, все заработало с первого раза
  • Отличная документация, хорошее сообщество
  • Множество клиентских разработок, в т.ч. под PHP

При детальном рассмотрении, выяснилось, что сам продукт обладает очень обширным функционалом (например, полнотекстовый поиск). Кажущийся простым на поверхности, MongoDB представляет из себя очень мощную платформу для работы с данными.

Совсем недавно мы переписали несколько фукнциональных частей проекта на Mongo. В процессе работы проблем почти не возникало, за исключением некоторых:

  • Mongo строго типизирован и не приводит типы автоматически (такой возможности впринципе нет, учитывая отсуствие каких-либо метаданных о коллекциях и документах). Поэтому в динамически типизированном PHP приходится приводить данные к нужным типам (например, когда они приходят из формы).
  • Не хватило возможностей для работы с массивами, что немного сбило с толку. С одной стороны — вложенные массивы — очень удобная вещь, с другой стороны — нет таких штук, как их фильтрация или сортировка. Надеюсь все это будет вскоре, хотя сейчас есть возможность реализовать это с помощью серверных функций.

Интересно узнать мнение и опыт читателей, кто использовал или знаком с MongoDB.

Google Bookmarks Digg I.ua Ru-marks Ruspace Zakladok.net Reddit delicious Technorati Yahoo My Web News2.ru БобрДобр.ru Memori.ru rucity.com
Related posts:
  1. Sysbench — тестируем производительность MySQL и платформы
  2. Maatkit — расширенные возможности MySQL
  3. check-unused-keys — проверка неиспользуемых индексов в MySQL

Connect.ua — история роста (перепечатка)

Комментариев нет

connectua_logo

Connect.ua — это первый украинский социальный сервис. За два года проект вырос в достаточно крупный, а следовательно имеет свою собственную историю масштабирования и роста.

Во время роста мы перепробовали большое количество технологий и подходов, которыми я и хочу поделиться в этой статье.

Наши показатели и цифры

Некоторые цифры проекта
  • 720 тыс. пользователей
  • 2 миллиона фотографий
  • 400 тысяч видео роликов
  • 20 миллионов личных сообщений
  • 50 миллионов оценок в ЖЖОТ
  • 25 миллионов событий в ленте новостей
  • 40 миллионов отправленных “Подмигнуть”
Технические показатели
  • 500 запросов в секунду на MySQL
  • 300 активных соединений на фронте + 200 активных соединений на медиа серверах (HTTP)
  • 1.5 тысячи запросов в секунду на каждом из бекендов
  • 8 миллионов запросов к бекендам в день
  • 7 Тб медиа (видео + аудио + фото)
  • 3 сервера баз данных
  • 4 бекенд сервера
  • 1 фротенд
  • 4 медиа сервера
  • 2 сервера транскодирования
  • 20 Гб памяти под Memcached

Технологии

Технологий используется огромное множество, причем динамика использования новых технологий очень высокая. За год на проекте появилось множество улучшений, связанных с новыми техническими решениями.

  • MySQL
  • Sphinxsearch
  • Memcached
  • MemcacheDB
  • PHP
  • PHP-FPM
  • Eaccelerator
  • Nginx
  • Imagemagick
  • FFmpeg
  • Mencoder
  • Flvtools
  • Varnish
  • GFS
  • Munin
  • Nagios
  • Xhprof
  • Minify (библиотека сжатия статики)
  • Linux shell :)

Далее наш опыт, архитектура, решения, ошибки и выводы:

Мониторинг и статистика

Как только появляются первые признаки тормозов или отказов на сайте, первым делом устанавливайте систему статистики. Мы поставили Munin и очень довольны. Множество плагинов, практически для любых технических решений. Очень просто писать свои плагины на любом интерпретируемом языке (мы пишем на PHP).

Для мониторинга используем Nagios.

Система статистики не только помагает обнаруживать проблемы, но и прогнозировать расширение.

Оборудование

Мы используем подход горизонтального расширения, а не вертикального. Поэтому мы делаем выбор в сторону недорого оборудования. Что это дает:

  • Избавляет от SPOF (единых узлов падения)
  • Покупая дорогое и мощное оборудование, Вам нужно больше платить и за все остальное (коммутаторы, сеть, поддержка и т.п.)
  • Стоимость вертикального роста имеет экспоненциальный характер
  • В любом случае вертикальный рост ограничен

СУБД: не в MySQL проблема, проблема в эффективности

Для начала, мы отказались от использования классической схемы репликации “запись на мастер” + “чтение с реплики”. При асинхронной репликации время отставания реплики неконтролируемо, что очень усложняет логику приложения. На реплику идут только агрегатные запросы, которые не чувствительны к небольшим задержкам (лучшее видео и т.п.).

В качестве архитектурного решения мы используем федерацию (вертикальное разделение СУБД по таблицам). Часть таблиц работает на одном сервере, часть на другом. Необходимость федерации появилась, когда некоторые особо большие таблицы препятствовали эффективной работе буфера MySQL.

Движки таблиц — InnoDB для всех таблиц, кроме случаев с полностью статическими таблицами (города, страны и т.п.) — для них MyISAM.

Для полнотекстового поиска используем Sphinx. Работает по схеме дельта индексации. Самая тяжелая часть — полная переиндексация, поэтому запускаем ее раз в неделю. Планируем внедрить объединения индексов (index merging).

Наиболее тяжелые функциональные части для СУБД — это личные сообщения и лента новостей. Ленту новостей недавно перевели на MemcacheDB. Стратегию выбрали масштабируемую, у каждого пользователя есть свой личный список событий, который обновляется, когда генерируется новое событие. Это позволит очень легко масштабировать этот функционал.

Что мы делали для оптимизации нагрузки
  • Кеширование (подробнее — ниже)
  • Тюнинг настроек сервера MySQL — никогда не используйте настройки по умолчанию
  • Оптимизировали (и все еще продолжаем) запросы. EXPLAIN + maatkit — это наш набор оптимизатора.
  • Тяжелые запросы зачастую можно упростить на порядки выкинув малозначимые части логики
  • Для особо тяжелых и не поддающихся ускорению запросов есть слейв
  • Денормализация + индексация — постоянные задачи

Кеширование: кешируйте все и еще немножко

Кеширование — первое, что мы начали делать для оптимизации приложения. Memcached выбрали по нескольким причинам: простой и эффективный, поддержка распределенного кеширования, встроенный алгоритм консистентного хеширования (необходимо при добавлении новых серверов), поддержка сессий PHP.

Сейчас хитрейт доходит до 95%, показатели вынужденного вытеснения из памяти стремятся к нулю.

Стратегию кеширования используем довольно простую. Для списков кешируем только первичные ключи. Для тяжелых запросов используем дубликаты с разным временем жизни. Ввиду большого количества персональных выборок, пришлось реализовать собственный механизм пространств имен для того, чтобы иметь возможность обновлять несколько объектов одновременно.

Система кеширования носит двухслойных характер: кеш приложения => memcached.

Клиентская оптимизация

Клиентская оптимизация — это второе, что мы начали делать для оптимизации производительности. Клиентская оптимизация позволила увеличить скорость загрузки страниц в несколько раз. После базовой оптимизации клиентской части, удалось повысить показатель просмотров страниц в полтора раза. Кроме всего прочего клиентская оптимизация позволяет сэкономить канал.

Что мы делали:

  • Gzip всего
  • Склеивание и сжатие статики
  • Вынос статики на другой домен
  • Установка необходимых заголовков для кеширования на клиентах

Сейчас наиболее медленное место в клиентской части — это система управления банерными показами.

Медиа

Наиболее ресурсоемкой частью проекта является то, что относится к медиа. Поэтому все медиа ресурсы изолированы от основной части системы. В качестве стратегии роста используем разделение по серверам. Каждый сервер работает независимо от других, что делает всю систему устойчивой к сбоям.

PHP

С PHP было меньше всего проблем. Единственным шагом, который привел к ощутимому росту скорости работы, стала установка eAccelerator’a. Большинство изменений в коде были связаны с архитектурными изменениями.

Для профилирования используем XhProf — хорошо подходит для работы в продуктивных условиях.

Что мы планируем

  • Переводить часть логики с MySQL на key=value базы данных
  • Внедрить систему очередей сообщений
  • Оптимизировать клиентскую часть дальше
  • Искать затычки и исправлять их :)

В качестве итога

После проделанной работы мы пришли к нескольким простым правилами, которыми пользуемся и сейчас:

  • Если решение работает у кого-то, это еще не значит, что оно будет работать для Вас
  • Во многих случаях приходиться экспериментировать. Нужно позаботиться о том, чтобы небольшие изменения в системе не вызывали огромных трудностей
  • Думайте о росте заранее, но не решайте не существующих проблем
  • Многие технологии умеют гораздо больше, чем кажется — гораздо больше
  • Творчество Ваш самый необходимый инструмент
  • Не делайте того, о чем ничего не знаете :)

Надеюсь будет полезно!

Google Bookmarks Digg I.ua Ru-marks Ruspace Zakladok.net Reddit delicious Technorati Yahoo My Web News2.ru БобрДобр.ru Memori.ru rucity.com

No related posts.

Google analytics — отслеживание скорости загрузки страниц (перепечатка)

Один комментарий

google-analytics-logo

Google analytics имеет расширенные возможности, которые далеко не ограничиваются подсчетом количества просмотров страниц Web сайтов. В GA есть возможность собирать статистику пользовательских событий. На основе этой статистики можно собирать практически любую информацию о пользователях и их действиях.

Рассмотрим, как использовать Google Analytics, чтобы отслеживать скорость загрузки страниц Вашего Web сайта у пользователей.

Event Tracking

В GA есть раздел Event Tracking, который и позволяет отслеживать статистику пользовательских событий. Для использования этой возможности Вы должны установить новую версию скрипта статистики (ga.js).

Стандартный код счетчика выглядит так:


Для отправки пользовательских событий, нужно воспользоваться методом _trackEvent ():

pageTracker._trackEvent('category', 'action', 'label', value);
  • category — Категория события
  • action — Тип события
  • label — Название события (необязательно)
  • value — Значение события (необязательно, числовой параметр)

После этого, в разделе Content (Содержание) -> Event Tracking (Отслеживание событий) можно смотреть статистику, пользуясь удобным и мощным инструментом.

Скорость загрузки страниц

Для начала, необходимо установить переменную, которая будет содержать в себе значение скорости загрузки страницы. Пример на PHP:

define('TS_START', microtime(true));

# Тут много много кода - вся логика страницы
define('TS_SPEED', microtime(true) - TS_START);

После этого в константе TS_SPEED будет доступно время выполнения скрипта в долях секунды.

Далее в шаблоне страницы необходимо зарегистрировать событие при помощи _trackEvent ():

...
<? $uri = $_SERVER['REQUEST_URI']; $speed = (int)(TS_SPEED*1000); ?>
<script>
pageTracker._trackEvent('Response time (ms)', '', '', );
</script>
...

Несколько моментов:

  • _trackEvent () нужно вызывать после объявления счетчика (частая ошибка)
  • Последний аргумент должен быть только целым числом, поэтому мы умножили его на 1000 (будем отслеживать скорость загрузки в миллисекундах)
  • Первые три аргумента всегда должны быть строчками, иначе событие будет проигнорировано

После установки кода и спустя некоторое время в GA будет доступен отчет приблизительно такого вида:

ga-statistics

Небольшое пояснение: ввиду очень широкого спектра возможных применений, не обращайте внимания на названия столбцов, их следует понимать только функционально, а именно:

  • Всего событий — количество вызовов конкретного события (action)
  • Уникальных событий — количество уникальных вызовов конкретного события
  • Полезность события — сумма всех value данного события. В нашем случае это суммарное время генерации конкретной страницы
  • Среднее значение — среднее значение value данного события. В нашем случае это среднее время генерации конкретной страницы

Детальное описание Google Analytics Event Tracking (англ.).

А Вы пользуетесь Event Tracking в GA, в каких целях?

Google Bookmarks Digg I.ua Ru-marks Ruspace Zakladok.net Reddit delicious Technorati Yahoo My Web News2.ru БобрДобр.ru Memori.ru rucity.com
Related posts:
  1. Оптимизация клиентской части с Google Page Speed

Twitter.com — архитектура и масштабирование (перепечатка)

Комментариев нет

twitter-bird-logo

В этой статье поговорим об одном из самых шумных и растущих проектов — Twitter.com (далее — Твиттер).

Разработка и развитие этого проекта совпадает с классической схемой удачного стартапа. Стартовал проект с простенького прототипа, написаного на скоркую руку на платформе Ruby-on-Rails. После этого в проекте было сделано огромное количество изменений в архитектурном и техническом плане. Твиттер не раз сталкивался и преодолевал проблемы быстрого роста нагрузки.

Разработчики Твиттера делятся своим опытом.


Статистика

  • 600 запросов в секунду
  • 200-300 соединений в секунду, доходит до 800 в пики
  • MySQL обрабатывает 2,400 запросов в секунду
  • 180 Rails-инстанций
  • 1 сервер MySQL (8-ядер) с репликацией на 1 слейв. Слейв используется только для статистики и отчетов
  • 30+ процессов для обработки периодичных задач
  • 8 серверов Sun X4100
  • Rails генерирует страницы за 200 мс
  • 16 GB памяти для Memcached

Платформа и технологии

  • Ruby on Rails
  • Erlang
  • Mongrel
  • Munin
  • Nagios
  • Google Analytics
  • AWStats
  • Memcached

Архитектура и решения

Мониторинг

С самого начала на Твиттере небыло никаких инструментов для мониторинга и сбора статистики. При появлении первых проблем с производительностью первое, что они сделали — добавили такие инструменты. В качестве мониторинга был использован Nagios, в качестве инструмента по сбору статистики — Munin. Monit используется для отслеживания и “убивания” слишком “больших” процессов.

Кеширование

Кеширование всего, чего только можно:

  • Кешировать нужно максимум всего. В абсолютном большинстве случаев отдача из кеша намного быстрее, чем из СУБД.
  • Подогревание кеша. Например, получение статуса друга скрывает тяжелую логику (приватность, безопасность и другие моменты), что приводит к очень тяжелому запросу для выборки. Поэтому статус друга обновляется напрямую в кеше, практически никогда запрос не доходит до СУБД.
  • Объекты ActiveRecord очень большие, поэтому они не кешируются. Все данные кешируются в ассоциативном массиве, и достаются по мере надобности
  • 90% всех запросов — запросы к API. Поэтому у них нет кеширования фрагментов страниц на фронтсерверах, но они кешируют API запросы
Системы очередей/сообщений
  • Использование систем/очередей сообщений повсеместно. Главная функциональная роль твиттера — это быть мостом между разными форматами (SMS, Web, IM и т.п.)
  • Например, для обновления кеша друга используется сообщение, которое передает эту работу в фон, вместо того, чтобы делать это синхронно.
  • Перепробовали множество очередей, остановились на Starling (система распределенных очередей на Ruby)
Пользователи
  • Существуют пользователи, которые ходят по страницам сайта и добавляют всех в друзья. Некоторые добавляют по 9000 друзей за сутки. Убийственно для производительности системы.
  • Используются инструменты (собственной разработки) для обнаружение таких проблем
  • Таких пользователей не жалеют — их удаляют
Партиционирование
  • Планируют партиционироваться, но пока этого не делают
  • Схему для партиционирования выберут временнУю. Делить по пользователям (точнее по идентификаторам пользователей) не правильно, т.к. многие запросы имеют временный характер

Уроки и выводы

  • Обращайтесь за помощью к сообществам, не пытайтесь спрятать и решить все проблемы сами. Вам помогут!
  • План масштабирования следует держать наравне с бизнес планом.
  • Разрабатывайте инструменты сами. Твиттер перепробовал множество решений, которые “почти работали”, но в итоге для многих вещей разработчикам пришлось делать собственные инструменты.
  • Встраивайте ограничения для пользователей. Люди будут пытаться (специально или нет) провалить Вашу систему. Делайте инструменты для обнаружения подобных аномалий.
  • Не делайте сами лишних проблем для СУБД. Не вся логика нуждается в гигантских JOIN’ах и т.п.
  • Кешируйте данные
  • Думайте над возможностью партиционирования приложения с самого начала, тогда у Вас будет возможность масштабировать его просто
  • Как только Вы понимаете, что сайт стал медленным, включайте систему статистики/отчетов/графиков для выяснения причин, не угадывайте
  • Оптимизируйте БД: индексируйте, пользуйтесь EXPLAIN-ом, денормализируйте, избегайте тяжелых объединений (JOIN-ы), избегайте сканирования больших объемов данных (FULL TABLE SCAN и т.п.)
  • Тестируйте все
  • Используйте уведомления об ошибках и исключениях, чтобы вовремя на них реагировать
  • Не делайте глупостей. Загрузка трех тысяч друзей в память может убить сервер, хотя с четырмя все работает отлично
  • Большинство проблем с производительностью связано не с языком, а с архитектурой

Источники (англ.)

Google Bookmarks Digg I.ua Ru-marks Ruspace Zakladok.net Reddit delicious Technorati Yahoo My Web News2.ru БобрДобр.ru Memori.ru rucity.com
Related posts:
  1. Connect.ua — история роста