Найкращий підхід для шардінгу таблиць 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 робив це неодноразово протягом останніх років, і це добре працювало для них.
Сказавши все це, дивлячись на ваше запитання, я впевнений, що ви ставите неправильні запитання, або я абсолютно неправильно розумію вашу заяву про проблему.