Пошаговый подход MySQL?

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

  • Охват уровня приложения
  • Остановка на уровне прокси-сервера MySQL?
  • Сервер централизованного поиска для окантовки?

Знаете ли вы о каких-либо интересных проектах или инструментах в этой области?

Ответ 1

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

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

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

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

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

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


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

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

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

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

У вас много задержек в сети.

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

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

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

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

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

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

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

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


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

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

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

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

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


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

Ответ 2

  • Охват уровня приложения: dbShards - единственный продукт, который я знаю о том, что это "привязка к приложениям". На веб-сайте есть несколько хороших статей. Просто по определению, осязание на уровне приложений будет более эффективным. Если приложение точно знает, куда идти с транзакцией, не просматривая его или не перенаправляя прокси-сервер, он будет быстрее. И скорость часто является одной из основных проблем, если не единственная проблема, когда кто-то смотрит в осколки.

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

  • Это то же самое, что и # 2.

Ответ 3

Знаете ли вы о каких-либо интересных проектах или инструментах в этой области?

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

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

Ответ 4

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

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

Ответ 5

Уровень применения конечно.

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

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

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

Я настоятельно рекомендую вам купить его и прочитать раздел "Масштабирование MySQL".

Ответ 6

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

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

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

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

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

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

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

Ответ 7

Предположим, у меня есть таблица, которая состоит из трех столбцов from_req_id, to_req_id, date (предположим, что система отправила запрос на добавление в друзья), поэтому у меня ниже вопросы 1-на какой столбец я должен выбрать ключ шарда, если нагрузка равна для запроса на обе колонки

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