Есть следующая задача.
Необходимо обеспечить кластеризацию пользовательских данных по нескольким БД-серверам.
Сейчас планируется использовать только MySQL без средств кластеризации.
Также необходимо балансировать нагрузку на сервера системы.
Более подробно — что такое пользовательские данные.
Есть таблицы вида
create table TABLENAME (
id int(11) autoincrement not null,
user_id int(11) not null
...
);
В которые и заносятся данные пользователей.
Назначение — распределенная CMS (данные раскидываются по разным серверам БД).
При балансировке нагрузки может возникнуть ситуация, когда данные одного пользователя хранятся на разных серверах.
Отследить по каким серверам раскиданы пользовательские данные — не проблема.
Проблему я вижу в другом —
Допустим мы знаем, что у пользователя есть данные из таблицы TABLENAME с некоторым ID.
Как эффективно определять на каком конкретно сервере хранятся данные?
Первые варианты. которые приходят в голову:
Пробегаться по всем серверам — но это ужасно не эффективно.
Хранить где-либо тройки значений (SERVERNUM, TABLENAME, ID). Но это вводит слишком большую избыточность. Плюс возникает необходимость некоторого центрального сервера, что хотелось бы избежать.
Какие могут быть вариантые решения?
П.С. Использование MySQL без средств кластеризации — позиция начальства.
П.П.С. Будет ли оправдано в данном случае использование PostrgreSQL.
Здравствуйте, Бабошин Андрей, Вы писали:
БА>При балансировке нагрузки может возникнуть ситуация, когда данные одного пользователя хранятся на разных серверах. БА>Отследить по каким серверам раскиданы пользовательские данные — не проблема. БА>Проблему я вижу в другом — БА>Допустим мы знаем, что у пользователя есть данные из таблицы TABLENAME с некоторым ID. БА>Как эффективно определять на каком конкретно сервере хранятся данные? БА>Первые варианты. которые приходят в голову:
БА>
БА>Пробегаться по всем серверам — но это ужасно не эффективно. БА>Хранить где-либо тройки значений (SERVERNUM, TABLENAME, ID). Но это вводит слишком большую избыточность. Плюс возникает необходимость некоторого центрального сервера, что хотелось бы избежать. БА>
БА>Какие могут быть вариантые решения?
Если возможно, то не раскидывать данные одного пользователя по разным серверам.
БА>П.С. Использование MySQL без средств кластеризации — позиция начальства. БА>П.П.С. Будет ли оправдано в данном случае использование PostrgreSQL.
Насколько понял порблема не в БД, а в методах хранения данных.
Здравствуйте, Бабошин Андрей, Вы писали:
БА>Какие могут быть вариантые решения?
Добавить информацию о сервере в ID, а при балансировке обновлять ID в связанных таблицах. Не слишком эффективно, но вполне может сработать.
БА>П.С. Использование MySQL без средств кластеризации — позиция начальства.
Чем аргументирует?
БА>П.П.С. Будет ли оправдано в данном случае использование PostrgreSQL.
Не думаю что это имеет значение.
Здравствуйте, Miroff, Вы писали:
M>Здравствуйте, Бабошин Андрей, Вы писали:
БА>>Какие могут быть вариантые решения?
M>Добавить информацию о сервере в ID, а при балансировке обновлять ID в связанных таблицах. Не слишком эффективно, но вполне может сработать.
Спасибо, надо будем подумать в этом направлении.
БА>>П.С. Использование MySQL без средств кластеризации — позиция начальства. M>Чем аргументирует?
Привычкой.
---------------------------
Я тут еще такой вариант придумал:
Можно использовать мультиагентный подход.
На каждый сервер БД сажаем по агенту.
Вводим реестр серверов БД, чтобы каждый сервер знал о других БД серверах.
Агенты будут общаться через SOAP/WSDL.
Каждый агент будет иметь следующие сервисы:
Выполнить запрос клиента.
Если данные находятся на текущем сервере – выполняет.
Если нет – смотрит знает ли он на каком конкретно сервере находятся данные, если знает – перенаправляет запрос.
Если же нет информации о нахождении информации – опрашиваем все сервера подряд.
Отдать список троек (сущность/таблица, ИД, пользователь) по запросу другого сервера.
Проверить существование у себя тройки (сущность/таблица, ИД, пользователь).
Также необходимо предусмотреть возможность инициативного оповещения одним агентов других при добавлении в него записей.
Здравствуйте, Бабошин Андрей, Вы писали:
БА>Я тут еще такой вариант придумал:
<skiped>
Боюсь, что в конечном итоге разделение одного сервера БД между всеми агентами окажется процентов так на 20 побыстрее
Для чего вам нужна кластеризация? Она действительно обоснована? Речь идет только о скорости или об отказоустойчивости тоже?
Самое простое решение — разделить данные серверам на основе диапазонов идентификаторов клиентов. Скажем — для всех клиентов с 1 до 100 000 -го — srv1, для всех от 100 001 до 200 000 — srv2 и т.п. Только в код эту привязку не зашивайте Однако важно следить, чтобы все данные одного клиента были на одном сервере, иначе только хуже будет.
Здравствуйте, mrozov, Вы писали:
M>Для чего вам нужна кластеризация? Она действительно обоснована? Речь идет только о скорости или об отказоустойчивости тоже?
Для балансировки нагрузки + для отказоустойчивости.
M>Самое простое решение — разделить данные серверам на основе диапазонов идентификаторов клиентов. Скажем — для всех клиентов с 1 до 100 000 -го — srv1, для всех от 100 001 до 200 000 — srv2 и т.п. Только в код эту привязку не зашивайте Однако важно следить, чтобы все данные одного клиента были на одном сервере, иначе только хуже будет.
Я об этом думал, но нельзя гарантировать, что не будет ситуации когда у клиентов с 1 по 100 000 информации будет X, а у клиентов с 100 001 по 200 000 — 100*X.
Здравствуйте, Бабошин Андрей, Вы писали:
БА>Допустим мы знаем, что у пользователя есть данные из таблицы TABLENAME с некоторым ID. БА>Как эффективно определять на каком конкретно сервере хранятся данные?
Это сделать достаточно просто — нужно вычислить хэш от значения первичного ключа, то есть ID, и он однозначно укажет номер узла распределенной БД (сервера). Но нужно учитывать, что для построения хорошей хэш-функции желательно заранее знать максимальное число узлов, то есть ограничивется масштабируемость.
А вообще поищи в сети материалы по архитектуре Teradata — ты движешься в этом направлении. Только вот потянете ли грамотную реализацию — большой вопрос, требующий анализа.
Здравствуйте, Бабошин Андрей, Вы писали:
БА>Здравствуйте, mrozov, Вы писали:
M>>Для чего вам нужна кластеризация? Она действительно обоснована? Речь идет только о скорости или об отказоустойчивости тоже? БА>Для балансировки нагрузки + для отказоустойчивости.
Это две абсолютно разные задачи. Не просто не пересекающиеся — но и активно мешающие друг-другу. На коленке такие системы не пишутся. Отказоустойчивость предполагает репликацию данных на другие сервера, что бьет по производительности и вносит дополнительные проблемы.
БА>Я об этом думал, но нельзя гарантировать, что не будет ситуации когда у клиентов с 1 по 100 000 информации будет X, а у клиентов с 100 001 по 200 000 — 100*X.
А вы что, еще и равномерно хотите балансировать ?? Ню-ню. Вы сознаете, что необходимость забирать данные клиентов с нескольких серверов вместо одного убьет производительность на корню? Проектирование систем для работы с распределенной БД остается весьма сложным делом, даже если вы используете коммерческие субд, таких решений нужно избегать практически любой ценой. А вы еще и системный уровень хотите сами сделать?
Тогда единственная разумная рекомендация — почитайте что-нибудь из теории или продвинутой практики репликации БД. Как резать данные, как избегать конфликтов, как строить распределенные транзакции и т.п. скорее всего, вы либо просто откажетесь от этой идеи, либо серьезно смягчите требования.