Экстремальный шардинг:Одна база данных SQLite на пользователя

StackOverflow https://stackoverflow.com/questions/128919

Вопрос

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

Вместо того, чтобы использовать одну централизованную базу данных MySQL/InnoDB и затем разбивать ее на разделы, когда придет время, я решил создать отдельную базу данных SQLite для каждого активного пользователя:один активный пользователь на каждый «осколок».

Таким образом, резервное копирование базы данных будет таким же простым, как копирование файлов каждого пользователя. маленький файл базы данных в удаленное место один раз в день.

Масштабирование будет таким же простым, как добавление дополнительных жестких дисков для хранения новых файлов.

Когда приложение выходит за рамки одного сервера, я могу связать серверы вместе на уровне файловой системы с помощью GlusterFS и запустить приложение без изменений или настроить простую прокси-систему SQLite, которая позволит каждому серверу манипулировать файлами sqlite на соседних серверах.

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

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

ОБНОВЛЯТЬ Я решил использовать менее радикальное решение, которое пока работает нормально.Я использую фиксированное количество сегментов — если быть точным, 256 баз данных sqlite.Каждый пользователь назначается и привязывается к случайному фрагменту с помощью простой хеш-функции.

Большинству функций моего приложения требуется доступ только к одному или двум сегментам на каждый запрос, но есть одна, которая требует выполнения простого запроса от 10 до 100 различных сегментов из 256, в зависимости от пользователя.Тесты показывают, что это займет около 0,02 секунды или меньше, если все данные кэшируются в оперативной памяти.Думаю, я смогу с этим жить!

ОБНОВЛЕНИЕ 2.0 Я портировал приложение на MySQL/InnoDB и смог добиться примерно такой же производительности для обычных запросов, но для одного запроса, требующего обхода сегментов, innodb работает в 4–5 раз быстрее.По этой и другим причинам я отказываюсь от этой архитектуры, но надеюсь, что кто-нибудь где-нибудь найдет ей применение... спасибо.

Это было полезно?

Решение

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

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

Возможно, вам также придется следить за ресурсами файловой системы — SQLite великолепен, великолепен, быстр и т. д. — но вы получаете некоторые преимущества кэширования и записи при использовании «стандартной базы данных» (т. е.MySQL, PostgreSQL и т. д.) из-за их конструкции.В предложенном вами дизайне вы кое-что из этого упустите.

Другие советы

Для меня это звучит как кошмар обслуживания.Что произойдет, если схема изменится во всех этих БД?

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

Возможным решением этой проблемы является создание "миниосколки"состоящий примерно из 1024 баз данных SQLite, вмещающих до 100 пользователей каждый.Это будет более эффективно, чем подход «БД на пользователя», поскольку данные упаковываются более эффективно.И проще, чем подход с сервером базы данных Innodb, поскольку мы используем Sqlite.

Параллелизм также будет неплохим, но запросы будут менее элегантными (противность shard_id).Что вы думаете?

http://freshmeat.net/projects/sphivedb

SPHiveDB — сервер для базы данных sqlite.Он использует JSON-RPC через HTTP, чтобы предоставить сетевой интерфейс для использования базы данных SQLite.Он поддерживает объединение нескольких баз данных SQLite в один файл.Он также поддерживает использование нескольких файлов.Он предназначен для экстремальной схемы сегментирования — одна база данных SQLite на каждого пользователя.

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

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

Если ваши данные так легко сегментировать, почему бы просто не использовать стандартный механизм базы данных, а если вы масштабируетесь настолько, что БД становится узким местом, сегментируйте базу данных с разными пользователями в разных экземплярах?Эффект тот же, но вы не используете множество крошечных баз данных.

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

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

Не настолько, чтобы усложнить задачу, но достаточно, чтобы сделать ее нетривиальной.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top