- PVSM.RU - https://www.pvsm.ru -
Мы собрали форк 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.
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.
Перед выполнением тестов база данных наполняется сгенерированными заранее проектами, пользователями и задачами. Таких вариантов тоже три:
Большинство реальных случаев использования Redmine приходятся на размеры между Малым и Большим. Объемы уровня Гигантского бывают значительно реже.
Объем занятого пространства
Исходные данные [17]
Столбцы показывают объемы занятого пространства для разных баз данных и разных наборов данных (меньше — лучше)
Мы имитируем работу Redmine в условиях, близких работе у облачного провайдера или на офисном сервере. Для этого мы выделяем не весь физический сервер, а размещаем его в виртуальной машине с гораздо меньшим количеством ресурсов и имитируем различную нагрузку на дисковую систему со стороны соседей. В качестве платформы виртуализации используется Xen 4.6, в dom0 — Linux kernel 3.16.7. Устройство хранения разбивается с помощью LVM, обычное linear, без thin provision и снэпшотов. Том размещается посередине HDD.
Использовались три конфигурации виртуальных машин:
Мы проверяем скорость работы наиболее часто используемых в Redmine операций — создание задач, добавление комментариев к задачам, изменение статуса и ответственного лица задачи. Из этих операций мы создали два теста, два рабочих цикла задачи:
Создание задачи
Создание задачи в проекте одним участником проекта, назначение ее на другого участника проекта и добавление в нее 10 комментариев от лица других участников проекта.
Обработка 10 задач
Получение пользователем 10 назначенных на него задач, переведение их всех в In Progress, и затем поочередное переведение задачи в Resolved и назначение ее на создателя задачи.
Тесты проводятся на 1, 2 и 4 параллельных процессах Redmine.
Нагрузка создается с помощью утилиты fio
, которая читает и пишет 50/50 случайные блоки в оставшуюся часть диска. Мы имитировали несколько уровней нагрузки на диск, которые характерны для типовых случаев работы виртуальных машин — у провайдеров публичных облаков и
Для имитации неполной загрузки мы запускаем fio с ограничением IOPS с помощью ключа --rate_iops
и замеряем утилизацию диска. При 100% однопоточной нагрузке это около 80 IOPS. Утилизация 25% создается нагрузкой 14 IOPS. Большая нагрузка имитируется увеличением числа потоков ключем --iodepth
.
В зависимости от количества соседних виртуальных машин, характера их работы и пиков нагрузки, загруженность диска может серьезно отличаться как у облачных провайдеров и
Мы измеряем полное время выполнения каждой операции Redmine на большом числе операций и сравниваем среднее время выполнения. Первые 10% результатов игнорируются — на них мы разогреваем систему. Последние 10% результатов игнорируются для того, чтобы исключить хвостовое искажение из-за разного времени завершения параллельных процессов.
Измерения проводятся в разных комбинациях условий:
Время выполнения замеряется для всех трех баз — MyRocks MySQL, MySQL и MariaDB. Мы также вычисляем разницу в скорости MyRocks MySQL по отношению к MySQL и MariaDB. Собранные данные представлены в виде графиков.
Графики времени выполнения операций
1) создание задачи; 2) обработка 10 задач
Исходные данные [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.
Графики времени выполнения операций
1) создание задачи; 2) обработка 10 задач
Исходные данные [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% при максимальной.
Графики времени выполнения операций
1) создание задачи; 2) обработка 10 задач
Исходные данные [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, мы ожидали ускорения при выполнении транзакций. На синтетических тестах производительности разработчики получали 10-кратный прирост скорости в работе СУБД. Для приложений, таких как Redmine, время выполнения операции состоит из времени выполнения Ruby-скрипта и времени выполнения запроса в БД. Разумеется, замена storage engine на RocksDB никак не увеличит скорость работы Ruby, и эта составляющая остается неизменной. Но и с учетом этого прирост в скорости за счет ускорения БД оказался впечатляющим.
Здесь мы приводим краевые результаты тестирования для виртуальной машины 2 Gb и Большого набора данных, и для виртуальной машины 8 Gb и Гигантского набора данных. Мы не учитываем здесь тестирование на высокой нагрузке для виртуальной машины 1 Gb, так как это случай экстремальной нехватки ресурсов.
Графики времени выполнения операций
1) создание задачи; 2) обработка 10 задач
Столбцы показывают время выполнения операции (меньше — лучше)
Минимальная (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 и успешно в нем работаем.
В данном тесте мы проверили производительность 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
Нажмите здесь для печати.