2008-09-24 2 views
28

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

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

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

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

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

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

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

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

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

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

+0

Это довольно старый пост, и ваш опыт с Gluster, вероятно, сейчас не слишком уместен, но вы в конечном итоге пытаетесь выполнить sqlite над glusterFS? – jberryman 2011-09-09 21:37:42

+0

Для людей, рассматривающих исследования по такой архитектуре, я рекомендую посмотреть на openord actordb; каждый актер представляет собой силос sqlite, а силосы распределяются и реплицируются с использованием протокола raft - http://www.actordb.com/ – 2016-07-20 13:39:43

ответ

25

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

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

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

6

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

+0

Изменения схемы могут быть развернуты динамически. Совместимые изменения схемы (например, добавление столбца) могут быть развернуты одним пользователем за раз в неделю, прежде чем новый код приложения, использующий эту функцию, будет включен. Несовместимые изменения могут быть развернуты по мере открытия каждого файла базы данных. Нет простоев. – 2008-09-24 18:49:02

+1

Это не проблема для Fogbugz, где каждый клиент имеет собственную базу данных SQL Server ... – 2008-09-28 17:00:25

3

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

1

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

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

4

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

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

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

1

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

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

2

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

4

http://freshmeat.net/projects/sphivedb

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

Смежные вопросы