- PVSM.RU - https://www.pvsm.ru -

Redmine на MySQL с RocksDB быстрее, чем с InnoDB, от 20% до 3 раз

Мы собрали форк MySQL от Facebook с движком RocksDB вместо InnoDB и потестировали его с реальными приложениями: Drupal, WordPress, Redmine.

Это офигенная штука. При низкой нагрузке выигрыш маленький, десятки процентов. Зато при высокой нагрузке выигрыш в разы. Когда RocksDB добавят в стабильный релиз в MariaDB, я уверен, что в течение полугода половина народа перейдет с InnoDB на RocksDB. Особенно, небольшие сайты на cloud/VPS и выделенных серверах.

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

Я собрал в статью результаты тестирования реальных сценариев Redmine, добавил анализ результатов и выводы. Redmine на MySQL с RocksDB оказался быстрее, чем с InnoDB — от 20% при минимальной нагрузке до 3 раз при максимальной. Позже подготовлю материалы по Drupal и другим PHP-приложениям.

Вы сможете проверить работу MyRocks и самостоятельно — в конце статьи есть ссылки на инсталляторы и виртуальные машины с LAMP/LEMP/Ruby стеками, собранные с MyRocks вместо MySQL.

Redmine на MySQL с RocksDB быстрее, чем с InnoDB, от 20% до 3 раз - 1

Введение

Facebook на базе своего хранилища RocksDB [1] создал storage engine для MySQL — MyRocks [2]. Работающая реализация MyRocks в виде MySQL 5.6 с патчами от Facebook передана в open source и размещается на GitHub — https://github.com/facebook/mysql-5.6 [3]. MyRocks является альтернативой InnoDB и дает несколько преимуществ:

  • Снижение объема записи
  • Лучшая компрессия
  • Уменьшения случайных чтений

Все это в сумме существенно повышает скорость транзакций на HDD и уменьшают изнашиваемость SSD, а также ускоряют репликацию.

MariaDB и Percona уже ведут работы по интеграции MyRocks в свои форки MySQL: Facebook MyRocks at MariaDB [4], Announcing MyRocks in Percona Server for MySQL [5]. MariaDB объявила, что MyRocks будет доступен в release candidate 10.2 этой зимой. На Jetware в число альтернатив MySQL добавлена [6] оригинальная реализация MyRocks от Facebook на базе MySQL 5.6.

Тестирование производительности на синтетических тестах показывает впечатляющие результаты. В зависимости от типа устройства хранения, выигрыш по скорости составляет от 20% до 10x. Результаты тестирования LinkBench можно посмотреть в публикации Yoshinori Matsunobu MyRocks: A space- and write-optimized MySQL database [7] и в блоге [8] Mark Callaghan, например, MyRocks: use less IO on writes to have more IO for reads [9]. Эти тесты во многом ориентируются на большие объемы баз данных (десятки и сотни гигабайт) и мощные машины.

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

Первым мы тестируем Redmine. Мы знаем как он устроен, активно используем его в разработке и поэтому тестирование имеет для нас также практическую ценность — если результат окажется хорошим, мы переходим на MyRocks.

Условия тестирования

Программное обеспечения

Мы используем Redmine 3.3.1 с Ruby 2.3.1, в конфигурации по умолчанию, без дополнительных плагинов.

В качестве серверов баз данных используем:

Все бинарники собраны одним компилятором GCC 4.9.3, с рекомендуемыми параметрами сборки и оптимизации.

Операционная система — Ubuntu 14.04 x86_64, Linux kernel 3.13.0. Файловая система — ext4.

Наборы данных

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

  1. Малый набор
    • 30 пользователей
    • 3 проекта и 10 подпроектов второго уровня, в каждом проекте по 10 пользователей
    • 1000 задач с 10 комментариями каждая
  2. Большой набор
    • 1000 пользователей
    • 10 проектов первого, 100 подпроектов второго и 10 подпроектов третьего уровня, в каждом проекте по 10 пользователей
    • 10000 задач с 10 комментариями каждая
  3. Гигантский набор
    • 10000 пользователей
    • 100 проектов первого, 1000 подпроектов второго и 100 подпроектов третьего уровня, в каждом проекте по 10 пользователей
    • 100000 задач с 10 комментариями каждая

Большинство реальных случаев использования Redmine приходятся на размеры между Малым и Большим. Объемы уровня Гигантского бывают значительно реже.

Объем занятого пространства

Redmine на MySQL с RocksDB быстрее, чем с InnoDB, от 20% до 3 раз - 2

Исходные данные [17]

Столбцы показывают объемы занятого пространства для разных баз данных и разных наборов данных (меньше — лучше)

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

  • Процессор: 4-core Xeon E31220 3.10GHz
  • Память: 16 Gb RAM, DDR3 1333
  • HDD: RAID mirror, 2 x Western Digital RE4 1 Tb

Виртуальная машина

Мы имитируем работу Redmine в условиях, близких работе у облачного провайдера или на офисном сервере. Для этого мы выделяем не весь физический сервер, а размещаем его в виртуальной машине с гораздо меньшим количеством ресурсов и имитируем различную нагрузку на дисковую систему со стороны соседей. В качестве платформы виртуализации используется Xen 4.6, в dom0 — Linux kernel 3.16.7. Устройство хранения разбивается с помощью LVM, обычное linear, без thin provision и снэпшотов. Том размещается посередине HDD.

Использовались три конфигурации виртуальных машин:

  1. 1 Gb RAM, 4 CPU, HDD 16 Gb
  2. 2 Gb RAM, 4 CPU, HDD 16 Gb
  3. 8 Gb RAM, 4 CPU, HDD 16 Gb

Тестируемые операции

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

  • Создание задачи

    Создание задачи в проекте одним участником проекта, назначение ее на другого участника проекта и добавление в нее 10 комментариев от лица других участников проекта.

  • Обработка 10 задач

    Получение пользователем 10 назначенных на него задач, переведение их всех в In Progress, и затем поочередное переведение задачи в Resolved и назначение ее на создателя задачи.

Тесты проводятся на 1, 2 и 4 параллельных процессах Redmine.

Сторонняя нагрузка на диск

Нагрузка создается с помощью утилиты fio, которая читает и пишет 50/50 случайные блоки в оставшуюся часть диска. Мы имитировали несколько уровней нагрузки на диск, которые характерны для типовых случаев работы виртуальных машин — у провайдеров публичных облаков и VPS [18], или при запуске на собственном сервере нескольких виртуальных машин под VMWare, Hyper-V, KVM или XenServer.

Для имитации неполной загрузки мы запускаем fio с ограничением IOPS с помощью ключа --rate_iops и замеряем утилизацию диска. При 100% однопоточной нагрузке это около 80 IOPS. Утилизация 25% создается нагрузкой 14 IOPS. Большая нагрузка имитируется увеличением числа потоков ключем --iodepth.

В зависимости от количества соседних виртуальных машин, характера их работы и пиков нагрузки, загруженность диска может серьезно отличаться как у облачных провайдеров и VPS [18], так и на собственном сервере. Поэтому мы проводили тестирование при отсутствии сторонней нагрузки, при незначительной однопоточной нагрузке (14 IOPS, 25%), так и при и полных сторонних нагрузках в 1, 2 и 4 потока.

Измеряемые значения

Мы измеряем полное время выполнения каждой операции Redmine на большом числе операций и сравниваем среднее время выполнения. Первые 10% результатов игнорируются — на них мы разогреваем систему. Последние 10% результатов игнорируются для того, чтобы исключить хвостовое искажение из-за разного времени завершения параллельных процессов.

Измерения проводятся в разных комбинациях условий:

  • для разных конфигураций виртуальных машин и разных наборов данных
  • для разного числа параллельных процессов Redmine (основная нагрузка) и разных сторонних нагрузок на диск

Время выполнения замеряется для всех трех баз — MyRocks MySQL, MySQL и MariaDB. Мы также вычисляем разницу в скорости MyRocks MySQL по отношению к MySQL и MariaDB. Собранные данные представлены в виде графиков.

Результаты тестирования

Малый набор данных и малая виртуальная машина

  • Виртуальная машина: 1 Gb RAM, 4 CPU, HDD 16 Gb
  • Набор данных: 30 пользователей, 13 проектов и подпроектов, 1000 задач

Графики времени выполнения операций

1) создание задачи; 2) обработка 10 задач

Redmine на MySQL с RocksDB быстрее, чем с InnoDB, от 20% до 3 раз - 3

Исходные данные [19]

Столбцы показывают время выполнения операции (меньше — лучше). Линии показывают во сколько раз сервер MySQL или MariaDB был медленнее сервера MyRocks MySQL.

Минимальная нагрузка — один процесс Redmine и отсутствует сторонняя нагрузка. Максимальная нагрузка — 4 процесса Redmine и 4 полных потока сторонней нагрузки на диск.

Мы видим, что время создания задачи для MyRocks при увеличении нагрузки до максимума меняется незначительно, и возрастает от 0.018 сек до 0.023 сек, на 23%. Для MySQL и MariaDB минимальное время создания задачи составляет 0.022 сек и возрастает в десять раз до 0.23 сек при максимальной нагрузке. При минимальной нагрузке MySQL и MariaDB оказываются медленнее на 24%, чем MyRocks; при максимальной нагрузке они оказываются медленнее в 9.5 раз.

Время обработки задач для MyRocks вырастает от 0.245 сек при минимальной нагрузке до 0.327 сек при максимальной, на 33%. Для MySQL и MariaDB минимальное время обработки задач возрастает примерно в 7 раз — с 0.283 сек при минимальной нагрузке до 2.245 сек при максимальной.

Объема оперативной памяти не хватает для эффективного кэширования чтения, и это очень сказывается на скорости InnoDB.

Большой набор данных и средняя виртуальная машина

  • Виртуальная машина: 2 Gb RAM, 4 CPU, HDD 16 Gb
  • Набор данных: 1000 пользователей, 120 проектов и подпроектов, 10000 задач

Графики времени выполнения операций

1) создание задачи; 2) обработка 10 задач

Redmine на MySQL с RocksDB быстрее, чем с InnoDB, от 20% до 3 раз - 4

Исходные данные [20]

Столбцы показывают время выполнения операции (меньше — лучше). Линии показывают во сколько раз сервер MySQL или MariaDB был медленнее сервера MyRocks MySQL.

Минимальная нагрузка — один процесс Redmine и отсутствует сторонняя нагрузка. Максимальная нагрузка — 4 процесса Redmine и 4 полных потока сторонней нагрузки на диск.

В данной конфигурации ресурсы виртуальной машины лучше соответствуют объему данных и нагрузке. Для MyRocks время создания задачи остается прежним — от 0.018 сек до 0.023 сек, вырастая на 23%. Для MySQL и MariaDB минимальное время становится чуть больше — 0.023 сек и вырастает только в два раза — до 0.056 сек при максимальной нагрузке. Они оказываются медленнее, чем MyRocks, на 30% при минимальной нагрузке, и в 2.3 раза при максимальной.

Для обработки задач ситуация похожая. Время выполнения у MyRocks при увеличении нагрузки слабо растет от 0.248 сек до 0.331 сек. Для MySQL и MariaDB минимальное время уже на 10% больше, чем для Малого набора данных и составляет 0.296 сек. При максимуме нагрузки время увеличивается почти в два раза — до 0.595 сек. MySQL и MariaDB оказываются медленнее, чем MyRocks, на 18% при минимальной нагрузке и на 80% при максимальной.

Гигантский набор данных и большая виртуальная машина

  • Виртуальная машина: 8 Gb RAM, 4 CPU, HDD 16 Gb
  • Набор данных: 10000 пользователей, 1200 проектов и подпроектов, 100000 задач

Графики времени выполнения операций

1) создание задачи; 2) обработка 10 задач

Redmine на MySQL с RocksDB быстрее, чем с InnoDB, от 20% до 3 раз - 5

Исходные данные [21]

Столбцы показывают время выполнения операции (меньше — лучше). Линии показывают во сколько раз сервер MySQL или MariaDB был медленнее сервера MyRocks MySQL.

Минимальная нагрузка — один процесс Redmine и отсутствует сторонняя нагрузка. Максимальная нагрузка — 4 процесса Redmine и 4 полных потока сторонней нагрузки на диск.

Десятикратное увеличение объема данных немного увеличило время создания задачи для всех баз: 0.020 сек для MyRocks, 0.026-0.029 для MySQL и MariaDB. Увеличение нагрузки замедляет MyRocks на 35% до 0.027 сек. Для MySQL и MariaDB рост нагрузки сказывается на скорости больше — при максимальной нагрузке время увеличивается в 3 раза — до 0.088 сек, и они оказываются медленнее, чем MyRocks, в 3.2 раза.

При обработке задач время выполнения MyRocks увеличивается на 32%, от 0.255 до 0.33 сек. У MySQL и MariaDB время увеличивается в 4 раза — с 0.309 до 1.242 сек. И они отстают от MyRocks в 3.8 раз.

Объем данных уже вырос до таких размеров, что начинают сказываться задержки случайной записи при обновлении индексов InnoDB и разница в скорости между RocksDB и InnoDB при максимальных нагрузках снова выросла.

Анализ результатов

Объем памяти

Для работы Redmine объем 1 Gb является минимальным рекомендуемым. Для эффективного кэширования данных в page cache размер памяти уже недостаточен, поэтому скорость работы очень чуствительна к нагрузке на диск. Задержки возникают уже на SELECT-запросах, так как для них приходится считывать данные с диска. Меньший объем хранимых данных у RocksDB привел к более эффективному кэшированию чтения, чем для InnoDB. Поэтому даже при большой нагрузке скорость операций у MyRocks изменилась совсем незначительно.

При увеличении памяти до 2 Gb основные используемые данные уже вмещаются в page cache и серверу БД уже не нужно постоянно их считывать с диска. В этом случае диск является узким горлышком только при изменениях в базе. Транзакции записываются на диск без writeback cache и интенсивная дисковая нагрузка увеличивает время ожидания завершения записи.

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

Скорость RocksDB vs InnoDB

Исходя из принципа работы RocksDB, мы ожидали ускорения при выполнении транзакций. На синтетических тестах производительности разработчики получали 10-кратный прирост скорости в работе СУБД. Для приложений, таких как Redmine, время выполнения операции состоит из времени выполнения Ruby-скрипта и времени выполнения запроса в БД. Разумеется, замена storage engine на RocksDB никак не увеличит скорость работы Ruby, и эта составляющая остается неизменной. Но и с учетом этого прирост в скорости за счет ускорения БД оказался впечатляющим.

Здесь мы приводим краевые результаты тестирования для виртуальной машины 2 Gb и Большого набора данных, и для виртуальной машины 8 Gb и Гигантского набора данных. Мы не учитываем здесь тестирование на высокой нагрузке для виртуальной машины 1 Gb, так как это случай экстремальной нехватки ресурсов.

Графики времени выполнения операций

1) создание задачи; 2) обработка 10 задач

Redmine на MySQL с RocksDB быстрее, чем с InnoDB, от 20% до 3 раз - 6

Столбцы показывают время выполнения операции (меньше — лучше)

Минимальная (1 процесс Redmine без сторонней дисковой нагрузки) и максимальная нагрузка (4 процесса Redmine и 4 потока полной сторонней нагрузки на диск)

При низкой нагрузке Redmine на MyRocks оказался на 15%-25%, быстрее, чем на MySQL и MariaDB. Размер хранимых данных мало влияет на эту скорость и у RocksDB, и у InnoDB — увеличение числа задач Redmine в 10 раз увеличило время выполнения примерно на 10%.

При высокой нагрузке (увеличении числа параллельных процессов и повышении сторонней дисковой нагрузки) поведение полностью меняется. Отрыв MyRocks стал больше — от 2-кратного до почти 4-кратного. Размер хранимых данных также стал существенно влиять на скорость — 10-кратное увеличение числа задач Redmine заметно (в 1.5-2 раза) замедлило скорость выполнения на серверах с InnoDB, и менее заметно замедлило выполнение на RocksDB (0-15%).

Одновременное увеличение объема данных и высокая нагрузка замедлили работу Redmine с MyRocks в 1.5 раза, в то время как Redmine на MySQL и MariaDB стал медленнее в 4 раза.

Стабильность работы

При тестировании мы обнаружили нюанс поведения одного из SQL-запросов Redmine при поиске с учетом parent issues. Из-за него некоторые виды поиска оказывались медленнее в MyRocks. Но это небольшое упущение со стороны Redmine — parent_id не имел в таблице индекс. Также мы столкнулись с небольшим багом, приводящим к расходу CPU после некоторых конфликтных транзакций в MyRocks.

Мы не сталкивались с другими проблемами. По словам разработчиков, Facebook использует MyRocks в production уже давно.

Вы можете использовать MyRocks уже сейчас или дождаться более широкого тестирования после появления MyRocks в MariaDB release candidate 10.2 или в Percona Server for MySQL. Пакет MyRocks доступен в репозитории Jetware как одна из альтернатив mysqld в конструкторах [22] стеков, например, PHP LAMP/LEMP), Ruby RAMP/REMP, или приложений, например, Redmine.

Несколько недель назад мы перевели свой внутренний Redmine-сервер на MyRocks и успешно в нем работаем.

Заключение

  1. Redmine с RocksDB оказался быстрее, чем с InnoDB — от 20% при минимальной нагрузке до 3 раз при максимальной.
  2. Увеличение объема данных и нагрузки, замедлившее Redmine с InnoDB в 4 раза, всего лишь в 1.5 раза замедлило Redmine с RocksDB.

P.S. Тестирование MyRocks с другими приложениями

В данном тесте мы проверили производительность MyRocks для приложения Redmine. В следующих тестах мы собираемся проверить производительность MyRocks с PHP-приложениями. Скорее всего, первым будет Drupal.

Статья на английском языке [23]

Автор: cvss

Источник [24]


Сайт-источник PVSM.RU: https://www.pvsm.ru

Путь до страницы источника: https://www.pvsm.ru/mysql/233943

Ссылки в тексте:

[1] RocksDB: http://rocksdb.org

[2] MyRocks: http://myrocks.io

[3] https://github.com/facebook/mysql-5.6: https://github.com/facebook/mysql-5.6

[4] Facebook MyRocks at MariaDB: https://mariadb.com/resources/blog/facebook-myrocks-mariadb

[5] Announcing MyRocks in Percona Server for MySQL: https://www.percona.com/blog/2016/10/24/announcing-myrocks-in-percona-server-for-mysql/

[6] добавлена: http://ru.jetware.org/names/myrocks-mysqld

[7] MyRocks: A space- and write-optimized MySQL database: https://code.facebook.com/posts/190251048047090/myrocks-a-space-and-write-optimized-mysql-database/

[8] блоге: http://smalldatum.blogspot.com

[9] MyRocks: use less IO on writes to have more IO for reads: http://smalldatum.blogspot.com/2016/11/myrocks-use-less-io-on-writes-to-have.html

[10] MyRocks MySQL 5.6.27.75: http://ru.jetware.org/packages/myrocks-mysqld-5.6.27.75-jet3-e34c228

[11] коммит bc17d30: https://github.com/facebook/mysql-5.6/tree/e34c228d28dd3da06d0f42b20df432545c779677

[12] show variables: http://ru.jetware.org/blog/redmine-performance-on-myrocks/file/myrocks-mysqld-5.6.show_variables.txt

[13] MySQL 5.6.31: http://ru.jetware.org/packages/mysqld-5.6.31

[14] show variables: http://ru.jetware.org/blog/redmine-performance-on-myrocks/file/mysqld-5.6.31.show_variables.txt

[15] MariaDB 10.1.16: http://ru.jetware.org/packages/mariadb-mysqld-10.1.16

[16] show variables: http://ru.jetware.org/blog/redmine-performance-on-myrocks/file/mariadb-mysqld-10.1.16.show_variables.txt

[17] Исходные данные: http://ru.jetware.org/blog/redmine-performance-on-myrocks/file/storage_size.yml

[18] VPS: https://www.reg.ru/?rlink=reflink-717

[19] Исходные данные: http://ru.jetware.org/blog/redmine-performance-on-myrocks/file/bench-1gb-4cpu-small.yml

[20] Исходные данные: http://ru.jetware.org/blog/redmine-performance-on-myrocks/file/bench-2gb-4cpu-large.yml

[21] Исходные данные: http://ru.jetware.org/blog/redmine-performance-on-myrocks/file/bench-8gb-4cpu-giant.yml

[22] конструкторах: http://ru.jetware.org/names/myrocks-mysqld/constructors

[23] Статья на английском языке: http://jetware.org/blog/redmine-performance-on-myrocks

[24] Источник: https://habrahabr.ru/post/319500/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best