Extreme Sharding: одна база данных SQLite на пользователя

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

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

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

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

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

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

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

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

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

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


person Seun Osewa    schedule 24.09.2008    source источник
comment
Это довольно старый пост, и ваш опыт работы с Gluster, вероятно, сейчас не слишком актуален, но вы попробовали sqlite вместо glusterFS?   -  person jberryman    schedule 10.09.2011
comment
Людям, желающим исследовать такую ​​архитектуру, я рекомендую посмотреть актерdb с открытым исходным кодом; каждый субъект является изолированным хранилищем sqlite, а разрозненные хранилища распределяются и реплицируются с использованием протокола raft - actordb.com   -  person Jerome WAGNER    schedule 20.07.2016


Ответы (8)


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

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

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

person heckj    schedule 24.09.2008
comment
Это отличный ответ. Дополнительным соображением является экономия на масштабе - наличие одинаковых данных, хранящихся вместе с одинаковыми данными, обеспечивает эффективное сжатие, гораздо более эффективное использование диска (о чем вы, возможно, упоминали в комментарии к кешу) и многое другое. - person SquareCog; 26.09.2008
comment
Я сталкиваюсь с чем-то похожим. Я использую Db4o, а Db4o в основном загружает всю базу данных в память для выполнения запросов. Поэтому я подумал, что было бы более эффективно иметь одну БД на пользователя и динамически загружать БД в память, а не загружать огромную БД один раз. Любые идеи по этому поводу - person jigzat; 25.01.2012

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

person John Sheehan    schedule 24.09.2008
comment
Изменения схемы можно развертывать динамически. Совместимые изменения схемы (например, добавление столбца) могут быть развернуты по одному пользователю за неделю в течение недели до того, как будет включен новый код приложения, использующий эту функцию. Несовместимые изменения могут вноситься при открытии каждого файла базы данных. Без простоев. - person Seun Osewa; 24.09.2008
comment
Похоже, это не было проблемой для Fogbugz, где у каждого клиента есть собственная база данных SQL Server ... - person Mike Woodhouse; 28.09.2008
comment
Не проблема, если миграция вашей схемы выполняется автоматически. Сложно сделать вручную; но тогда вы можете захотеть вручную обновить производственные базы данных, чтобы избежать соблазна. - person Dickon Reed; 13.10.2008

http://freshmeat.net/projects/sphivedb

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

person Community    schedule 24.05.2009

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

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

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

person Seun Osewa    schedule 25.09.2008

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

person Powerlord    schedule 24.09.2008
comment
Хороший вопрос. Есть отношения внутри базы данных каждого пользователя. Кроме того, SQLite позволяет выполнять соединения с таблицами из более чем одной базы данных путем «ПРИСОЕДИНЕНИЯ» одной базы данных к другой. - person Seun Osewa; 24.09.2008

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

person Community    schedule 30.10.2008

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

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

person Nick Johnson    schedule 24.09.2008

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

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

person Lasse V. Karlsen    schedule 28.09.2008