Экстремальный Шардинг: Одна База Данных SQLite На Пользователя

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

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

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

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

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

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

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

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

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

обновление 2.0 я портировал приложение в MySQL / InnoDB и смог получить примерно такую же производительность для регулярных запросов, но для этого одного запроса, который требует ходьбы по осколкам, innodb в 4-5 раз быстрее. По этой и по другой причине я отказываюсь от этой архитектуры, но я надеюсь, что кто-то где-то найдет ей применение...спасибо.

8 ответов


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

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

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


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


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

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

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


http://freshmeat.net/projects/sphivedb

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


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


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


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

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


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

недостаточно, чтобы сделать это трудно, но достаточно, чтобы сделать его нетривиальным.