У нас есть очень крупная база данных уровня предприятия. Как часть нашей бизнес-модели, каждый веб-пользователь каждый месяц посещает наши веб-серверы в одно и то же время, что, в свою очередь, приводит к появлению у нас проблем с SQL. Трафик очень тяжелый и продолжает увеличиваться с ростом компании. Оптимизация sql proc была выполнена, а оборудование уже масштабировано до очень высокого уровня.
Сейчас мы стремимся защитить базу данных, чтобы мы могли справиться с ростом компании и будущими нагрузками.
Мы решили, какие именно данные следует защитить. Это часть нашей базы данных, которая широко используется.
Тем не менее, мой вопрос касается неосколенных данных, которые являются общими / универсальными. Примером таких данных может быть, например, таблица инвентаризации или, возможно, таблица Employee, таблица пользователей и т. Д.
Я вижу два варианта обработки этих общих / универсальных данных:
1) дизайн 1 - Поместить общие / универсальные данные во внешнюю базу данных. Все записи будут происходить здесь. Эти данные затем будут реплицированы на каждый сегмент, что позволит каждому фрагменту читать эти данные и выполнять внутреннее соединение с этими данными в процессах t-sql.
2) дизайн 2 - дать каждому осколку собственную копию всех общих / универсальных данных. Пусть каждый шард записывает локально в эти таблицы и использует репликацию слиянием sql для обновления / синхронизации этих данных на всех других шардах.
заботы о дизайне # 1
1) Транзакционные проблемы: если у вас возникла ситуация, когда вы должны записать или обновить данные в сегменте, а затем, например, записать / обновить общую / универсальную таблицу в 1 сохраненном протоколе, вы больше не сможете сделать это легко. Данные теперь существуют в отдельных экземплярах SQL и базах данных. Возможно, вам придется задействовать MS DTS, чтобы посмотреть, сможете ли вы объединить эти записи в транзакцию, поскольку они находятся в отдельной базе данных. Производительность является проблемой здесь, и возможные перезаписи могут быть задействованы для процедур, которые записывают в зашифрованные и общие данные.
2) потеря ссылочной целостности. Невозможно сделать перекрестную ссылочную целостность базы данных.
3) Запись больших областей системы, чтобы она могла записывать общие данные в новую универсальную базу данных, но считывать общие данные из сегментов.
4). увеличенные поездки базы данных. Как и № 1 выше, когда вы сталкиваетесь с ситуацией, в которой вы должны обновить данные с разделением на сегменты и общие данные, вы собираетесь выполнить несколько циклов, чтобы выполнить это, поскольку данные теперь находятся в отдельных базах данных. Некоторая задержка в сети здесь, но я не беспокоюсь об этой проблеме так сильно, как выше 3.
заботы о дизайне № 2
В дизайне № 2 каждый шард получает свой собственный экземпляр всех общих / универсальных данных. Это означает, что весь код, который присоединяется или обновляет общие данные, продолжает работать / работать так же, как и сегодня. От команды разработчиков требуется очень мало перекодирования / переписывания. Однако этот дизайн полностью зависит от репликации слиянием, чтобы синхронизировать данные между всеми сегментами. dbas высококвалифицированны и очень обеспокоены тем, что репликация слиянием может не справиться с этим, и в случае сбоя репликации слиянием, что восстановление после этого сбоя не велико и может очень негативно повлиять на нас.
Мне любопытно знать, если кто-то пошел с вариантом дизайна # 2. Мне также любопытно узнать, пропускаю ли я третий или четвертый вариант дизайна, который я не вижу.
заранее спасибо.
источник
Ответы:
Ваш вопрос сосредоточен на этом:
Когда вы выполняете сегментирование, и у вас есть данные, которые должны видеть все фрагменты, вы должны классифицировать эти данные с помощью нескольких атрибутов:
Это часто меняется? В ваших примерах вы указали Инвентарь, Сотрудник и Пользователь. Обычно инвентарь меняется очень быстро, но записи сотрудников изменяются только периодически (скажем, несколько сотен обновлений в день).
Какую задержку может выдержать каждый осколок?Даже несмотря на то, что инвентарь может постоянно меняться, вы можете допустить большую задержку (минуты или даже часы) на таком столе. Если вы продаете уникальные предметы с очень ограниченным количеством, которое вы никогда не сможете пополнить (подумайте об оригинальных произведениях искусства), то вы вообще не осколите эти данные - вы только запросите исходную базу данных. Тем не менее, в большинстве интернет-магазинов вы не распродаете каждый товар ежедневно и в любом случае собираетесь быстро пополнять запасы, так что вам не нужно подсчитывать запасы с точностью до миллисекунды. Фактически, в большинстве случаев вам нужен только флаг In-Stock, равный 0 или 1, и центральный процесс обновляет этот флаг. Таким образом, вам не нужно нажимать каждый удар вверх / вниз по счетчику предметов на каждый осколок. Данные сотрудника или пользователя, с другой стороны,
Будете ли вы присоединяться от зарезервированных столов к неосколоченным? В идеале ответ здесь - нет, вы должны сделать два отдельных запроса, чтобы получить данные, а затем присоединить их на стороне приложения. Это становится намного сложнее с точки зрения приложения, но дает вам возможность получать самые свежие данные из каждого источника.
Это оригинальные данные или скопированы?Еще один способ подумать над этим вопросом: что вам нужно сделать резервную копию и как часто? Как правило, в среде с большими объемами сегментирования вы хотите, чтобы резервные копии были максимально быстрыми и минимальными. (В конце концов, вам нужно защитить каждый узел, и вы хотите, чтобы все сегменты переключались на DR в один и тот же момент времени - не иметь одни сегменты с более новыми данными, чем другие.) Это означает, что сегментированные данные и не защищенные данные должны находиться в совершенно разных базах данных - даже если они находятся на одном сервере. Мне может потребоваться постоянное резервное копирование журналов транзакций моих зашифрованных (исходных) данных, но мне вообще может не потребоваться резервное копирование не зашифрованных данных. Возможно, мне будет проще просто обновить таблицу «Сотрудники» или «Пользователи» из единственного источника правды, а не создавать резервные копии на каждом осколке. Если все мои данные находятся в одной базе данных,
Теперь о ваших проблемах:
«Транзакционные проблемы ... вы больше не сможете сделать это легко». Правильный. В сценариях с тенями выбрасывайте концепцию транзакции в окно. Это также ухудшается - для сегментированных данных вы можете иметь один сегмент в оперативном режиме, а другой - временно в случае сбоя или перезапуска экземпляра кластера. Вам необходимо планировать отказ любой части системы в любое время.
«Невозможно сделать перекрестную ссылочную целостность базы данных». Правильный. Когда вы разбиваете одну таблицу на несколько серверов, вы надеваете большие штаны и говорите серверу базы данных, что вы беретесь за сложные задачи, такие как резервное копирование на определенный момент времени, взаимосвязи между таблицами и объединение данных из несколько источников. Теперь это касается вас и вашего кода.
«Перекодировать большие области системы, чтобы она могла записывать общие данные в новую универсальную базу данных, но считывать общие данные из сегментов». Исправьте и здесь. Нет простой кнопки для этого, но как только вы встроите это в приложение, вы сможете масштабироваться как сумасшедший. Я бы сказал, что более простой способ сделать это - разделить соединения приложения по чтению .
"увеличенные поездки в базу данных." - Да, если вы разбиваете данные на несколько серверов, приложению придется больше выходить в сеть. Ключ также заключается в реализации кеширования, чтобы некоторые из этих данных могли храниться в более дешевых и высокопроизводительных системах без блокировок. Самый быстрый запрос - тот, который вы никогда не делаете.
Я также изложил больше плюсов и минусов в разделении мультитенантных баз данных , таких как настройка производительности для отдельных сегментов, различные стратегии резервного копирования / восстановления для каждого сегмента и проблемы развертывания схемы.
источник
На высоком уровне типичный способ разделения (или горизонтального разбиения) данных - это разделение транзакционных таблиц и репликация таблиц основного уровня. Как и большинство технологических решений, это, конечно, решает один набор проблем и создает совершенно новый набор проблем ... но мы все к этому уже привыкли, не так ли? ;-)
Однако я хотел бы задать вопрос, является ли SQLServer вашим лучшим решением для этого. Рабочая нагрузка больше похожа на OLTP или больше похожа на DW / BI?
Ура, Дейв Сиск
источник
Возможен третий вариант. Используя реляционное разбиение (вместо разбиения черного ящика), вы должны иметь возможность разделять и распространять всю базу данных. Поскольку она построена на основе традиционной реляционной модели данных, база данных знает, какие данные хранятся на каких серверах и, следовательно, где их найти, поэтому все ваши данные можно считать «общими / универсальными». Проверьте dbShards как возможность сделать весь процесс шардинга проще.
источник