Подтвердить что ты не робот

InnoDB Bottleneck: расслабляющая ACID для повышения производительности

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

Тест: время, необходимое для увеличения одной и той же строки в таблице InnoDB 3000 раз, где строка индексируется по ее первичному ключу, а обновляемый столбец не является частью какого-либо индекса. Я выполняю эти 3000 обновлений, используя 20 одновременных клиентов, работающих на удаленном компьютере, каждый со своим отдельным подключением к БД.

Мне интересно узнать, почему разные модели хранилищ, которые я тестировал, InnoDB, MyISAM и MEMORY, имеют профили, которые они выполняют. Я также надеюсь понять, почему InnoDB так плохо оценивает сравнение.

InnoDB (20 одновременных клиентов): Каждое обновление занимает 0.175 с. Все обновления выполняются после 6.68 с.

MyISAM (20 одновременных клиентов): Каждое обновление занимает 0,003 секунды. Все обновления выполняются после 0.85s.

Память (20 одновременных клиентов): Каждое обновление занимает 0.0019s. Все обновления выполняются после 0.80s.

Полагая, что concurrency может вызвать такое поведение, я также сравнивал один клиент, выполняющий 100 обновлений последовательно.

InnoDB: Каждое обновление занимает 0.0026s.

MyISAM: Каждое обновление занимает 0,0006 с.

ПАМЯТЬ: Каждое обновление занимает 0,0005 с.

Фактическая машина представляет собой экземпляр RDS Amazon (http://aws.amazon.com/rds/) с основными конфигурациями по умолчанию.

Я предполагаю, что ответ будет состоять из следующих строк: InnoDB fsyncs после каждого обновления (поскольку каждое обновление является ACID-совместимой транзакцией), тогда как MyISAM не работает, поскольку он даже не поддерживает транзакцию. MyISAM, вероятно, выполняет все обновления в памяти и регулярно сбрасывается на диск, а именно, как его скорость приближается к движку хранения MEMORY. Если это так, есть ли способ использовать InnoDB для поддержки транзакций, но, возможно, ослабьте некоторые ограничения (через конфигурации), чтобы записи выполнялись быстрее за счет некоторой долговечности?

Кроме того, какие-либо предложения о том, как улучшить производительность InnoDB по мере увеличения числа клиентов? Он явно масштабируется хуже, чем другие механизмы хранения.

Обновление

Я нашел https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performance, что именно то, что я искал. Настройка innodb-flush-log-at-trx-commit = 2 позволяет нам ослаблять ограничения ACID (сброс на диск происходит один раз в секунду) для случая сбоя питания или сбоя сервера. Это дает нам аналогичное поведение для MyISAM, но мы по-прежнему используем функции транзакций, доступные в InnoDB.

Выполняя те же тесты, мы видим 10-кратное улучшение производительности записи.

InnoDB (20 одновременных клиентов): Каждое обновление занимает 0,017 с. Все обновления выполняются после 0.98s.

Любые другие предложения?

4b9b3361

Ответ 1

Я нашел https://blogs.oracle.com/MySQL/entry/comparing_innodb_to_myisam_performance, что именно то, что я искал. Настройка innodb-flush-log-at-trx-commit = 2 позволяет нам ослаблять ограничения ACID (сброс на диск происходит один раз в секунду) для случая сбоя питания или сбоя сервера. Это дает нам аналогичное поведение для MyISAM, но мы по-прежнему используем функции транзакций, доступные в InnoDB.

Выполняя те же тесты, мы видим 10-кратное улучшение производительности записи.

InnoDB (20 одновременных клиентов): каждое обновление занимает 0,017 с. Все обновления выполняются после 0.98s.

Ответ 2

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