Підходи до шардингу MySQL?


88

Який найкращий підхід для Sharding таблиць MySQL. Підходи, які я можу придумати, такі:

  1. Затінення рівня додатка?
  2. Шардінг на рівні проксі MySQL?
  3. Центральний сервер пошуку для шардингу?

Чи знаєте ви про якісь цікаві проекти чи інструменти в цій галузі?

Відповіді:


116

Найкращий підхід для шардінгу таблиць MySQL - не робити цього, якщо це зовсім не уникнути.

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

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

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

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

Ви робите це лише тоді, коли вам потрібно осколок.


У момент, коли ви осколки, ви платите за це різними способами:

Більша частина вашого SQL більше не є декларативною.

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

У шардованому середовищі ви, мабуть, приєднуєтесь до таблиці на вузлі A проти даних на вузлі B, або у вас є таблиця, більша за вузол, на вузлах A і B і приєднуєте дані з неї до даних, що знаходяться на вузлах B і C. Ви починаєте писати резолюції об'єднання на базі додатків на основі хешу вручну, щоб вирішити це (або ви заново винаходите кластер MySQL), тобто ви отримуєте багато SQL, який більше не є декларативним, але виражає функціональність SQL процедурним способом (наприклад, ви використовуєте оператори SELECT у циклах).

У вас виникає велика затримка мережі.

Зазвичай запит SQL може бути вирішений локально, і оптимізатор знає про витрати, пов'язані з доступом до локального диска, і вирішує запит таким чином, щоб мінімізувати витрати на це.

У шардованому середовищі запити вирішуються або шляхом запуску доступу до ключа та значення через мережу до кількох вузлів (сподіваємось, із пакетним доступом до ключів, а не окремими пошуками ключів за туди і назад), або шляхом переміщення частин WHEREречення далі до вузлів, де вони можуть бути застосованим (що називається "зниженням стану"), або тим і іншим.

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

Ви втрачаєте багато виразної сили SQL.

Гаразд, це, мабуть, менш важливо, але обмеження зовнішнього ключа та інші механізми SQL для цілісності даних не здатні охопити декілька осколків.

MySQL не має API, який дозволяє асинхронні запити, що працюють.

Коли дані одного типу містяться на кількох вузлах (наприклад, дані користувачів на вузлах A, B і C), часто потрібно вирішувати горизонтальні запити щодо всіх цих вузлів ("Знайти всі облікові записи користувачів, які не були ввійшли в систему протягом 90 днів або більше"). Час доступу до даних лінійно зростає із числом вузлів, якщо паралельно не можна запитувати декілька вузлів і результати агрегувати в міру надходження ("Зменшити карту").

Передумовою цього є API асинхронного зв'язку, який не існує для MySQL у належній робочій формі. Альтернативою є велика кількість розгалужень та зв’язків у дитячих процесах, які відвідують світ смоктання на сезонному абонементі.


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

Питання полягає ще більше в тому, чи ви хочете здійснити автоматичне оббивання (наприклад, визначаючи, який рядок входить до якого вузла, хешуючи первинні ключі), чи ви хочете функціонально розділити вручну ("Таблиці, пов’язані з історією користувача xyz, переходять до цього master, тоді як таблиці, пов'язані з abc та def, переходять до цього master ").

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

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

Функціональне шардінг має ту перевагу, що його порівняно легко зробити для існуючої кодової бази з низкою змін, які не надто великі. http://Booking.com робив це неодноразово протягом останніх років, і це добре працювало для них.


Сказавши все це, дивлячись на ваше запитання, я впевнений, що ви ставите неправильні запитання, або я абсолютно неправильно розумію вашу заяву про проблему.


2
Це хороша відповідь. Але я хочу зазначити, що шардінг дійсно потрібен лише для великих обсягів програм, і, швидше за все, вони приносять певний дохід. Сторонній додаток для шардингу вирішить усі ваші проблеми, пов’язані з об’єднаннями, транзакціями між різними сегментами тощо. І якщо ви отримаєте хорошу, вона збереже цілісність „реляційної” бази даних. Інші програми, ви маєте рацію, просто перетворять вашу базу даних у пару ключ-значення і таким чином переможуть ціль SQL.
chantheman

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

1
Вам слід перевірити dbShards. Він масштабується краще, ніж лінійно, відповідно до кількості доданих "осколків". Вам знадобиться дуже мало, якщо такі є, змін на стороні програми, і так, ви, програма не знаєте різниці. Він просто надсилає та отримує транзакції так само, як і з ODBC або JDBC. dbShards також дозволяє підказки для shard, якщо ви хочете отримати більше контролю над транзакцією. Ви можете сказати dbShards, з якого саме осколка ви хочете читати чи писати.
chantheman

1
Ну добре, @Gigala, витрачати час на написання чітко визначеної відповіді на зразок цієї, незалежно від широти, теж не потрібно, але я радий, що це було зроблено, оскільки ця відповідь виявилася для мене корисною. Будь ласка, не перешкоджайте користувачам не "думати нестандартно", відповідаючи.
mewm

12
  1. Заточення рівня програм: dbShards - це єдиний відомий мені продукт, який робить "шардування з урахуванням додатків". На веб-сайті є кілька хороших статей. Тільки за визначенням, шардування з урахуванням додатків буде більш ефективним. Якщо додаток точно знає, куди звертатися з транзакцією, не шукаючи її або перенаправляючи через проксі, це само по собі буде швидше. І швидкість часто є однією з головних проблем, якщо не єдиною проблемою, коли хтось шукає шардингу.

  2. Деякі люди "осколюють" за допомогою проксі, але на мої очі це перемагає мету шардування. Ви просто використовуєте інший сервер, щоб повідомити про свої транзакції, де знайти дані або де їх зберігати. Завдяки підозрілому додатку, ваш додаток знає, куди йти самостійно. Набагато ефективніше.

  3. Це те саме, що №2 насправді.


де dbShards використовується у виробництві де? також це не відкритий код.
sheki

Також підходи 2 і 3 можуть бути різними, якщо проксі шукає на основі хешу замість БД або сховища.
sheki

1
dbShards виробляється з різними клієнтами, але ні, це не відкритий код. Не думаю, що ви знайдете хороший продукт для шардингу з відкритим кодом. І так, ви праві, що хеш може бути використаний як пошук, але в такому випадку вам все одно доведеться зробити ще одну "зупинку", щоб отримати вашу транзакцію до бази даних. Ось чому шардінг з урахуванням додатків майже завжди буде швидшим.
chantheman

Але, як я вже сказав, якщо ви зможете отримати додаток для шардингу, яке підтримує цілісність стосунків, тоді ви будете в хорошій формі. Я згадую dbShards, тому що це єдине, про що я знаю. Оскільки це відбувається, це лінійно масштабує ваші швидкості запису та читання. Ви додаєте 4 "осколки" або розділяєте свій один сервер MySQL на 4, і він буде працювати в 4 рази швидше.
chantheman

7

Чи знаєте ви про якісь цікаві проекти чи інструменти в цій галузі?

Кілька нових проектів у цьому просторі:

  • citusdata.com
  • spockproxy.sourceforge.net
  • github.com/twitter/gizzard/

5

Осколок-запит - це рішення для шардінгу на основі OLAP для MySQL. Це дозволяє визначити комбінацію шардованих таблиць і неархівованих таблиць. Незатемнені таблиці (як таблиці підстановки) можуть вільно приєднуватися до шардованих таблиць, і шардовані таблиці можуть приєднуватися одна до одної, доки таблиці приєднуються клавішею осколка (жоден поперечний осколок або самоз'єднання, які перетинають межі осколка). Будучи рішенням OLAP, Shard-Query зазвичай має мінімальний час відгуку 100 мс або менше, навіть для простих запитів, тому він не буде працювати для OLTP. Shard-Query призначений для паралельного аналізу наборів великих даних.

Рішення для шардінгу OLTP існують і для MySQL. Закриті вихідні рішення включають ScaleDB , DBShards . Рішення OLTP з відкритим кодом включають JetPants , Cubrid або Flock / Gizzard (інфраструктура Twitter).


3

Рівень застосування, звичайно.

Найкращий підхід, який я коли-небудь червонів, я знайшов у цій книзі

Високопродуктивний MySQL http://www.amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064

Короткий опис: ви можете розділити свої дані на багато частин і зберегти ~ 50 частин на кожному сервері. Це допоможе вам уникнути другої за величиною проблеми шардингу - перебалансування. Просто перемістіть деякі з них на новий сервер, і все буде добре :)

Я настійно рекомендую вам придбати його та прочитати частину "масштабування mysql".


Рекомендованій вами книзі 8 років ... чи висвітлює вона шардінг, що відповідає сучасним технологіям?
рафіян

1
Він охоплює деякі основні підходи до масштабування mysql. AFAIK нічого не змінилося в масштабуванні mysql. Сьогодні широко використовуються ті самі методи шардінгу та реплікації на рівні програми.
Андрій Фролов

Я можу помилятися, але за останній тиждень я провів багато досліджень з цього питання, і схоже, що сам MySQL вніс багато змін за останні 8 років, особливо щодо розділення та кешування. Цього року вийшла нова версія: amazon.com/High-Performance-MySQL-Optimization-Replication/dp/... Я її не читав, але, думаю, вона охоплює нові доступні моделі реплікації.
NateDSaint

4
Книги .. чому б просто не пояснити це тут.
DDD

2

Станом на 2018 рік, схоже, існує власне рішення MySql. Насправді існує принаймні 2 - кластер InnoDB та кластер NDB (існує комерційна та спільна версія).

Оскільки більшість людей, які використовують версію спільноти MySql, більше знайомі з движком InnoDB, саме це слід вивчити як першочергове завдання. Він підтримує реплікацію та розділення / виділення з коробки та заснований на MySql Router для різних варіантів маршрутизації / балансування навантаження.

Синтаксис для створення таблиць потрібно змінити, наприклад:

    CREATE TABLE t1 (col1 INT, col2 CHAR(5), col3 DATETIME) PARTITION BY HASH ( YEAR(col3) );

(це лише один з чотирьох типів розділів )

Одне дуже важливе обмеження:

Зовнішні ключі InnoDB та розділи MySQL не сумісні. Розділені таблиці InnoDB не можуть мати посилання на зовнішні ключі, а також не можуть мати стовпців, на які посилаються зовнішні ключі. Таблиці InnoDB, які мають або на які посилаються зовнішні ключі, не можуть бути розділені.


Майте на увазі, що PARTITION BY HASH(YEAR...)скануватиме всі розділи, якщо у вас є діапазон дат. Гидота.
Рік Джеймс,
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.