Подходит шардинг MySQL? - PullRequest
       9

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

84 голосов
/ 04 апреля 2011

Каков наилучший подход для Sharding MySQL таблиц. Подходы, которые я могу придумать:

  1. Уровень применения шардинга?
  2. Sharding на уровне прокси MySQL?
  3. Центральный сервер поиска для шардинга?

Вам известны какие-нибудь интересные проекты или инструменты в этой области?

Ответы [ 6 ]

106 голосов
/ 11 апреля 2011

Лучший подход для ограждения таблиц MySQL - не делать этого, если это совершенно не неизбежно.

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

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

Случай записи: а) частота записи постоянно перегружает диски этого сервера или б)происходит слишком много операций записи, поэтому репликация постоянно отстает в этой иерархии репликации.

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

Только тогда, когда у вас есть , чтобы сделать это осколком.


Моментвы осколок, вы платите за это несколькими способами:

Большая часть вашего SQL больше не декларируетсяrative.

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

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

большая задержка в сети.

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

В изолированной среде запросы разрешаются либодоступ к значению ключа unning по сети к нескольким узлам (возможно, с помощью пакетного доступа к ключу, а не отдельных обращений к ключу за цикл) или путем передачи частей предложения WHERE вперед к узлам, где они могут быть применены (это называется 'условие pushdown '), или и то, и другое.

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

Вы теряете много выразительногосила SQL.

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

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

Когда данные одного типа находятся на нескольких узлах (например, пользовательские данные на узлах A, B и C), горизонтальные запросы часто необходимо разрешать для всех этих узлов ("Найтивсе учетные записи пользователей, которые не входили в систему в течение 90 дней и более ").Время доступа к данным растет линейно с количеством узлов, если только несколько узлов не могут быть запрошены параллельно, а результаты агрегированы по мере их поступления («Map-Reduce»).

Предварительным условием для этого является API асинхронной связи, который не существует для MySQL в хорошем рабочем состоянии.Альтернатива - много разветвлений и соединений в дочерних процессах, которые посещают мир suck на сезонном проходе.


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

Вопрос больше в том, хотите ли вы автоматически разделять (определять, какая строкапереходит в какой узел, например, путем хеширования первичных ключей) или если вы хотите выполнить функциональное разделение вручную («Таблицы, связанные с пользовательской историей xyz, переходят к этому мастеру, а таблицы abc и def - к этому мастеру»).

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

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

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


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

10 голосов
/ 04 апреля 2011
  1. Sharding уровня приложения: dbShards - единственный продукт, о котором я знаю, который использует "sharding осведомлен о приложении".На сайте есть несколько хороших статей.По определению, шардинг с учетом приложений будет более эффективным.Если приложение точно знает, куда идти с транзакцией без необходимости искать ее или перенаправлять через прокси, это само по себе будет быстрее.А скорость часто является одной из главных, если не единственной проблемой, когда кто-то смотрит на шардинг.

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

  3. Это на самом деле то же самое, что и № 2.

7 голосов
/ 29 июня 2012

Вам известны какие-нибудь интересные проекты или инструменты в этой области?

Несколько новых проектов в этом пространстве:

  • citusdata.com
  • spockproxy.sourceforge.net
  • github.com / твиттер / Желудок /
4 голосов
/ 17 июня 2013

Shard-Query - это решение для шардинга на основе OLAP для MySQL.Позволяет определить комбинацию неэкранированных и неэкранированных таблиц.Неэкранированные таблицы (например, таблицы поиска) можно свободно присоединять к сегментированным таблицам, а сегментированные таблицы можно объединять друг с другом до тех пор, пока к таблицам присоединяется ключ сегмента (нет перекрестных сегментов или самостоятельных соединений, пересекающих границы сегментов).Будучи решением OLAP, Shard-Query обычно имеет минимальное время ответа 100 мс или меньше, даже для простых запросов, поэтому он не будет работать для OLTP.Shard-Query предназначен для параллельного анализа больших наборов данных.

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

3 голосов
/ 14 апреля 2011

Уровень применения курса.

Лучший подход, который я когда-либо делал, я нашел в этой книге

Высокая производительность MySQL http://www.amazon.com/High-Performance-MySQL-Jeremy-Zawodny/dp/0596003064

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

Я настоятельно рекомендую вам купить его и прочитать часть "mysql scaling".

1 голос
/ 29 октября 2018

По состоянию на 2018 год, похоже, существует решение, родное для MySql. На самом деле существует как минимум 2 - InnoDB Cluster и NDB Cluster (есть коммерческая и общественная версия).

Поскольку большинство людей, использующих MySql Community Edition, больше знакомы с движком InnoDB, это то, что следует изучить в качестве первоочередной задачи. Он поддерживает репликацию и разбиение / разделение из коробки и использует MySql Router для различных вариантов маршрутизации / распределения нагрузки.

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

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

(это только один из четырех типов разбиения )

Одно очень важное ограничение:

Внешние ключи InnoDB и разделы MySQL несовместимы. Секционированные таблицы InnoDB не могут иметь ссылки на внешние ключи и столбцы, на которые ссылаются внешние ключи. Таблицы InnoDB, которые имеют внешние ссылки или на которые ссылаются внешние ключи, не могут быть разделены.

...