Про ефективність однопотокової та багатопотокової баз даних


58

H2 - це база даних з однією ниткою з хорошою репутацією щодо продуктивності. Інші бази даних є багатопотоковими.

Моє запитання: коли багатопотокова база даних стає цікавішою, ніж база даних з одним потоком? Скільки користувачів? Скільки процесів? Що таке спусковий гачок? Хтось має досвід поділитися?

Підсумок

  • Звичайним вузьким місцем є доступ до диска
  • SSD-файли швидкі, але крихкі (процедура відмови обов'язкова)
  • Один довгий запит у системі однієї нитки блокує всі інші
  • Налаштування багатопотокової системи може бути складним
  • Багатопотокові бази даних вигідні навіть для одноядерних систем

Наскільки я можу сказати, нитка означає "нитку чи процес" для цього питання - наприклад, postgres не є багатопотоковою, але питання не намагається порівнювати (H2, postgres) проти (Oracle, SQL Server тощо)
Jack Дуглас

Відповіді:


31

Ось моя думка:

Зазвичай вузьким місцем (або найповільнішою частиною) системи БД є диск. Процесор спрацьовує лише під час арифметичних операцій, обробки або будь-якого іншого завдання, яке виконує процесор. При належній архітектурі багатопотоковість може допомогти компенсувати навантаження запиту на центральний процесор, а не читання / запис повільного диска. Бувають випадки, коли швидше обчислити значення за допомогою циклів процесора, а не створити обчислену колонку (яка раніше була збережена на диску) та прочитати цю колонку з диска.

У деяких RDBMS є тимчасова БД (tempdb), яка використовується всіма БД у цьому екземплярі для сортування, хешування, тимчасових змінних тощо ... Багатопотокове чи розбиття цих файлів tempdb може бути використане для поліпшення пропускної здатності tempdb , тим самим покращуючи загальну продуктивність сервера.

Використовуючи багатопотоковість (паралелізм), набір результатів запиту можна розділити на обробку на різні ядра сервера, а не використовувати одне ядро. Ця функція не завжди покращує продуктивність, але є випадки, коли вона є, а значить, функція доступна.

Нитки, доступні БД, використовуються для багатьох цілей: для читання / запису на диск, підключень користувачів, фонових завдань, блокування / фіксації, мережевого вводу-виводу тощо тощо. Залежно від архітектури ОС потоки подаються в центральний процесор і є вдалося за допомогою очікувань та черг. Якщо процесор може скоротити ці потоки досить швидко, то час очікування буде низьким. Багатопотокова БД буде швидшою, ніж однопотокова БД, оскільки в однопотоковій БД буде накладні витрати на переробку лише одного потоку, а не мати інші доступні протектори.

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


Дякуємо за розуміння. Я чую, як люди хвалять твердотільні накопичувачі. Я думаю, що інвестувати в них - це, мабуть, найкраще, що потрібно зробити, переконавшись, що запити добре написані, і додаток є досить паралельним.
Jérôme Verstrynge

@ Стан - Я думаю, що multithreadedв цьому контексті мається на увазі щось інше , тобто всі транзакції серіалізовані так, як згадує Лука у своїй відповіді.
Джек Дуглас,

@JVerstry ~ Ні, не дуже. Ідіть, читайте думки Джеффа Етвуда про SSD-диски ... вони мають високий рівень відмов. Найкраще це правильно індексувати дані та мати добре написані запити.
jcolebrand

@jcolebrand Добре, він, схоже, захищає їх за швидкість лише за допомогою сильної системи резервного копіювання, коли вони не вдається
Jérôme Verstrynge

2
@Jverstry ~ Так, і якщо ви розумієте цю концепцію, і з нею все гаразд, і не заперечуйте відновити все виробниче середовище (або чекати автоматичного відмови, а потім відновити в якийсь момент найближчого майбутнього), то продовжуйте це, вони все ще зроблять все швидше, так.
jcolebrand

47

Якщо є одне, що я можу сказати про MySQL, це те, що InnoDB, його транзакційний (сумісний з ACID) механізм зберігання, дійсно є багатопоточним. Однак він настільки багатопоточний, як ВИ КОНФІГУРУЄТЬСЯ !!! Навіть прямо "поза коробкою" InnoDB чудово працює в одному середовищі процесора, враховуючи його настройки за замовчуванням. Щоб скористатися можливостями багатопотокової роботи InnoDB, потрібно пам'ятати, щоб активувати безліч варіантів.

innodb_thread_concurrency встановлює верхню межу кількості одночасних потоків, які InnoDB може відкрити. Найкраще для цього встановити кругле число (2 X Кількість процесорів) + Кількість дисків. ОНОВЛЕННЯ : Як я дізнався з перших вуст на конференції Percona NYC, вам слід встановити це значення 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 відповідає сумісності з кислотами та працює дуже добре, використовуючи MultiVersion Concurrency Control . Операції повинні мати можливість рівня ізоляції (повторення, що повторюється, за замовчуванням), що перешкоджає блокуванню доступу інших до даних.

Що стосується багатоядерних систем, InnoDB пройшов довгий шлях. Раніше InnoDB не міг працювати в багатоядерному середовищі. Я пам'ятаю, що потрібно запускати кілька екземплярів mysql на одному сервері, щоб отримати декілька ядер для розподілу декількох процесів mysqld по процесорам. Це більше не потрібно, завдяки Percona та пізніше MySQL (так, Oracle, кажучи, що все ще робить мене кляпом), оскільки вони розробили InnoDB в більш зрілий механізм зберігання даних, який може отримати доступ до ядер простоти без особливої ​​настройки. Поточний примірник InnoDB сьогодні може добре працювати на одному ядерному сервері.


11

Як тільки у вас є кілька одночасних користувачів або процесів, або навіть єдиний процес з багатопотоковим доступом до бази даних, наявність бази даних, яка підтримує нитку, стане потенційно цікавою.

H2 є безпечним для потоків, але серіалізує всі запити до бази даних, що може стати потенційною проблемою продуктивності в сценарії великого навантаження. Чи справді це стосується конкретного проекту, залежить від комбінації ваших вимог щодо продуктивності, кількості потоків / користувачів / процесів, що звертаються до бази даних, частоти запитів, виконаних цими потоками, та середньої та найгіршої ефективності вашої роботи запити.

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

Якщо ви зараз використовуєте H2 у своєму проекті, я б радив запустити профайлер проти вашої кодової бази за сценарієм завантаження (просто запустити x кількість потоків, які одночасно вражають ваш код, використовуючи типові типи використання). Це дасть вам фактичні показники щодо продуктивності та вузьких місць у вашій кодовій базі, а не просто теоретизує. Якщо це показує, що ваші запити витрачають великий відсоток свого часу, просто чекаючи доступу до бази даних, саме час перейти до потокової бази даних.


Чи H2 серіалізує всі запити - або лише DML?
Джек Дуглас

8

З того, що я можу сказати, "однонитка" - це трохи неправильне значення для H2. Справа в тому, що вона серіалізує всі транзакції (тобто робить їх по черзі).

Найважливішим питанням щодо того, це "добре" чи ні для вашої програми, не є "Скільки користувачів?" або навіть "Скільки процесів?", але "Скільки часу триватимуть мої транзакції?"

Якщо всі ваші транзакції є підсекундними, це може бути нормально, якщо на деякий процес потрібно кілька годин, це може бути непогано, оскільки всі інші очікувані транзакції будуть чекати їх завершення. Рішення про те, що це "добре" чи ні, буде залежати від ваших власних вимог щодо продуктивності - тобто, наскільки довго прийнятним буде чекати, коли мої користувачі вдаряться до бази даних з транзакціями.

--EDIT

Здається, H2 насправді не серіалізує транзакції - лише DML. Іншими словами, безліч коротких оновлень у межах однієї тривалої транзакції не блокуватимуть інші оновлення . Однак, якщо ви не використовуєте експериментальну функцію MVCC , блокування таблиці означає, що це має подібний ефект на практиці. Існує також експериментальна "багатопотокова" функція, але вона не може бути використана одночасно з MVCC


5

Цитуючи шматочки та фрагменти з сайту PostgreSQL ... Зверніть увагу, що я абсолютно не маю уявлення про достоїнства цих аргументів - вони просто не вміщуються в коментарі.

З питань поширених запитань розробника ("Чому теми не використовуються ..."):

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

Наразі нитки не використовуються замість декількох процесів для копіювання, оскільки: (...)

  • Помилка в одному бекенде може пошкодити інші перешкоди, якщо вони є потоками в рамках одного процесу
  • Покращення швидкості за допомогою потоків невеликі порівняно з рештою часу запуску бекенда.
  • Обмін виконуваними відображеннями, доступними лише для читання, та використання спільних_буферів означає, що процеси, як нитки, дуже ефективні в пам'яті
  • Регулярне створення та знищення процесів допомагає захистити від фрагментації пам'яті, що може бути важко керувати в тривалих процесах

Зі списку Todo ("Особливості, які ми не хочемо"):

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

Усі мітки, що працюють як нитки в одному процесі (не потрібно)

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

Отже, знову ж таки ... Я абсолютно не маю уявлення про достоїнства сказаного. Це було просто занадто довго, щоб вмістити коментар.


-3

Багатопотокова база даних принесе вам користь лише тоді, коли у вас буде більше 1 паралельного запиту, що надходить до бази даних. Це залежить від кількості ваших користувачів. Якщо у вас одночасно працює над десятьма користувачами, швидше за все, вони збираються одночасно створити більше одного запиту в базі даних.

Більше того, багатопотокова база даних може отримати користь лише тоді, коли на процесорі є багатоядерний. Якщо є одне ядро, багатопотокова база даних повинна чергувати завдання та виконувати їх послідовно на одному ядрі. Коли є багатоядерне, кожне ядро ​​може запускати один потік паралельно. Таким чином, кращі показники.

Чи відповідає це на ваш запит?


7
Багатопотокові бази даних вигідні навіть для одноядерних систем. Це заважає одному довготривалому запиту блокувати весь доступ до бази даних, плюс у вас може бути кілька потоків, які очікують на дисковому або мережевому введення-виводу, в той час як інший потік активно аналізує запити, обробляє попередньо встановлені дані тощо

Один користувач може використовувати одну програму, яка паралельно виконує деякі операції. Ця програма, швидше за все, піде на користь, якщо база даних також має багатопотокові / багатопроцесорні можливості.
joanolo
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.