О производительности однопоточных и многопоточных баз данных


58

H2 является однопоточной базой данных с хорошей репутацией в отношении производительности. Другие базы данных являются многопоточными.

Мой вопрос: когда многопоточная база данных становится более интересной, чем однопоточная база данных? Сколько пользователей? Сколько процессов? Что такое триггер? У кого-нибудь есть опыт, которым можно поделиться?

Резюме

  • Обычное узкое место - доступ к диску
  • SSD быстрые, но хрупкие (процедура отказа обязательна)
  • Один длинный запрос в однопоточной системе заблокирует все остальные
  • Конфигурировать многопоточную систему может быть сложно
  • Многопоточные базы данных полезны даже в одноядерных системах

Насколько я могу судить, под «потоком» подразумевается «нить или процесс» - например, postgres не является многопоточным, но вопрос не пытается сравнить (H2, postgres) с (Oracle, SQL Server и т. Д.)
Джек Дуглас

Ответы:


31

Вот мое мнение:

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

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

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

Потоки, доступные для БД, используются для многих целей: чтение / запись на диск, пользовательские подключения, фоновые задания, блокировка / блокировка, сетевой ввод-вывод и т. Д. В зависимости от архитектуры ОС потоки преимущественно загружаются в ЦП и удалось использовать ожидания и очереди. Если процессор может довольно быстро обрезать эти потоки, тогда время ожидания будет низким. Многопоточная БД будет работать быстрее, чем однопоточная БД, так как в однопоточной БД будут накладные расходы на утилизацию только одного потока, а не на то, чтобы другие протекторы были легко доступны.

Масштабируемость также становится проблемой, так как для управления и выполнения масштабированной системы БД потребуется больше потоков.


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

@Stan - я думаю, что multithreadedв этом контексте означает что-то другое , то есть, что все транзакции сериализуются, как упоминает Люк в своем ответе.
Джек Дуглас

@JVerstry ~ Нет, не совсем. Иди почитай мысли Джеффа Этвуда о твердотельных накопителях ... у них высокий процент отказов. Лучшее, что можно сделать, - правильно индексировать данные и иметь хорошо написанные запросы.
Jcolebrand

@jcolebrand Хорошо, он , кажется, защищают их скорость только с сильной резервной системы , когда они терпят неудачу
Джером Verstrynge

2
@Jverstry ~ Да, и если вы понимаете эту концепцию и согласны с ней, и не возражаете против перестройки всей производственной среды (или ожидания автоматического переключения при сбое, а затем перестройки в какой-то момент в ближайшем будущем), тогда пойти на это, они сделают вещи еще быстрее, да.
Jcolebrand

47

Если я могу сказать одну вещь о MySQL, так это то, что InnoDB, его транзакционный (ACID-совместимый) механизм хранения, действительно многопоточный. Тем не менее, он такой же многопоточный, как и вы! Даже прямо "из коробки" InnoDB отлично работает в среде с одним процессором, учитывая его настройки по умолчанию. Чтобы воспользоваться возможностями многопоточности InnoDB, вы должны не забыть активировать множество опций.

innodb_thread_concurrency устанавливает верхнюю границу количества параллельных потоков, которые InnoDB может держать открытыми. Лучшее число раундов для этого - (2 X Количество процессоров) + Количество дисков. ОБНОВЛЕНИЕ : Как я узнал из первых рук на конференции Percona NYC Conference, вы должны установить это значение в 0, чтобы предупредить InnoDB Storage Engine, чтобы найти лучшее число потоков для среды, в которой он работает.

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

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

innodb_thread_sleep_delay устанавливает количество миллисекунд, в течение которых поток InnoDB может бездействовать до повторного входа в очередь InnoDB. По умолчанию 10000 (10 секунд).

innodb_read_io_threads и innodb_write_io_threads (оба начиная с MySQL 5.1.38) выделяют указанное количество потоков для чтения и записи. По умолчанию 4 и максимум 64.

innodb_replication_delay налагает задержку потока на ведомое устройство, когда достигнута innodb_thread_concurrency.

innodb_read_ahead_threshold разрешает линейное чтение заданного количества экстентов (64 страницы [страница = 16K]) перед переключением на асинхронное чтение.

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

Большинство людей не знают об этих функциях и вполне удовлетворены тем, что InnoDB просто выполняет ACID-совместимые транзакции. Если вы настраиваете любой из этих вариантов, вы делаете это на свой страх и риск.

Я играл с несколькими экземплярами пула буферов MySQL 5.5 (162 ГБ в 9 экземплярах буферных пулов) и пытался таким образом автоматически разбивать данные в памяти. Некоторые эксперты говорят, что это должно дать вам повышение производительности на 50%. То, что я получил, было тонной блокировкой потоков, которая фактически заставила InnoDB сканировать. Я переключился на 1 буфер (162 ГБ), и все снова стало хорошо в мире. Я думаю, вам нужны эксперты Percona, чтобы установить это. Я буду завтра на конференции Percona MySQL в Нью-Йорке и спрошу об этом, если представится возможность.

В заключение, InnoDB теперь хорошо работает на многопроцессорном сервере, учитывая его настройки по умолчанию для многопоточных операций. Для их настройки требуется большая осторожность, терпение, отличная документация и отличный кофе (или Red Bull, Jolt и т. Д.).

Доброе утро, добрый вечер и спокойной ночи !!!

ОБНОВЛЕНИЕ 2011-05-27 20:11

Вернулся с конференции Percona MySQL в Нью-Йорке в четверг. Что за конференция. Многому научился, но получил ответ, который я рассмотрю в отношении InnoDB. Рональд Брэдфорд сообщил мне, что установка innodb_thread_concurrency в 0 позволит InnoDB самостоятельно определить наилучший вариант действий с параллелизмом потоков. Я буду экспериментировать с этим дальше в MySQL 5.5.

ОБНОВЛЕНИЕ 2011-06-01 11:20

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

Что касается многоядерных систем, InnoDB прошел большой путь. В прошлом InnoDB не мог хорошо работать в многоядерной среде. Я помню, что мне приходилось запускать несколько экземпляров mysql на одном сервере, чтобы заставить несколько ядер распределять несколько процессов mysqld по центральным процессорам. Это больше не нужно, благодаря Percona, а затем и MySQL (например, Oracle, который по-прежнему заставляет меня затыкать рот), поскольку они превратили InnoDB в более зрелый механизм хранения, который может легко получать доступ к ядрам без особой настройки. Текущий экземпляр InnoDB сегодня может хорошо работать в одноядерном сервере.


11

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

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

Например, если ваши требования к производительности должны иметь ответ в течение секунды, у вас есть не более 10 одновременно работающих пользователей, выполняющих один запрос, выполнение которого занимает 0,05 секунды, однопоточная база данных все равно позволит вам достичь этих целей (хотя многопоточный скорее всего, уже даст заметный прирост производительности). Однако, учитывая тот же сценарий с одним потенциальным запросом с наихудшей производительностью в полсекунды, сериализация доступа к базе данных больше не позволит вам достичь целей производительности.

Если вы в настоящее время используете H2 в своем проекте, я бы посоветовал вам запустить профилировщик для вашей кодовой базы в сценарии загрузки (просто запустите x потоков, попадающих в ваш код одновременно, используя некоторые типичные варианты использования). Это даст вам реальные показатели производительности и узких мест в вашей кодовой базе, а не просто теоретизирует. Если это показывает, что ваши запросы тратят большой процент времени на ожидание доступа к базе данных, пришло время перейти к многопоточной базе данных.


H2 сериализует все запросы - или только DML?
Джек Дуглас

8

Из того, что я могу сказать, «однопоточный» является немного неправильным для H2. Дело в том, что он сериализует все транзакции (т.е. делает их по одной за раз).

Важный вопрос относительно того, является ли это "хорошо" или нет для вашего приложения, не "Сколько пользователей?" или даже «Сколько процессов?», но «Сколько времени займут мои транзакции?»

Если все ваши транзакции менее одной секунды, это может быть хорошо, если для выполнения некоторых требуется несколько часов, это может быть не так, поскольку все другие ожидающие транзакции будут ожидать их завершения. Решение о том, будет ли это «хорошо» или нет, будет зависеть от ваших собственных требований к производительности, т. Е. Сколько времени допустимо для моих пользователей, попадающих в базу данных с транзакциями.

--РЕДАКТИРОВАТЬ

Кажется, что H2 не сериализует транзакции - просто DML. Другими словами, множество коротких обновлений в одной длинной транзакции не будут блокировать другие обновления . Однако, если вы не используете экспериментальную функцию MVCC , блокировка таблицы означает, что на практике это имеет аналогичный эффект. Существует также экспериментальная функция «multi_threaded», но ее нельзя использовать одновременно с MVCC.


5

Цитируя кусочки с сайта PostgreSQL ... Обратите внимание, что я абсолютно не представляю достоинства этих аргументов - они просто не помещаются в комментарии.

Из FAQ для разработчиков («Почему темы не используются ...»):

http://wiki.postgresql.org/wiki/Developer_FAQ#Why_don.27t_you_use_threads.2C_raw_devices.2C_async-I.2FO.2C_.3Cinsert_your_favorite_wizz-bang_feature_here.3E.3F

Потоки в настоящее время не используются вместо нескольких процессов для бэкэндов, потому что: (...)

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

Из списка Todo («Особенности, которые мы не хотим»):

http://wiki.postgresql.org/wiki/Todo#Features_We_Do_Not_Want

Все бэкэнды работают как потоки в одном процессе (не требуется)

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

Итак, еще раз ... Я абсолютно не имею представления о достоинствах вышеизложенного. Это было просто слишком долго, чтобы уместиться в комментарии.


-3

Многопоточная база данных принесет вам пользу только тогда, когда к базе данных поступает более 1 параллельного запроса. Это зависит от количества пользователей. Если над приложением одновременно работают более десяти пользователей, скорее всего, они будут выполнять более одного запроса к базе данных одновременно.

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

Это отвечает на ваш запрос?


7
Многопоточные базы данных полезны даже в одноядерных системах. Он предотвращает блокировку всех других запросов к одному длительному запросу, к тому же у вас может быть несколько потоков, ожидающих дискового или сетевого ввода-вывода, в то время как другой поток активно анализирует запросы, обрабатывает предварительно выбранные данные и т. Д.

Один пользователь может использовать одну программу, которая парализует некоторые операции. Эта программа, скорее всего, выиграет, если база данных также имеет возможности многопоточности / многопроцессорности.
Жоаноло
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.