Чрезвычайный Sharding: одна база данных SQLite на пользователя - PullRequest
32 голосов
/ 24 сентября 2008

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

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

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

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

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

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

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

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

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

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

Ответы [ 8 ]

27 голосов
/ 24 сентября 2008

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

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

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

6 голосов
/ 24 сентября 2008

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

4 голосов
/ 24 мая 2009

http://freshmeat.net/projects/sphivedb

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

4 голосов
/ 25 сентября 2008

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

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

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

3 голосов
/ 24 сентября 2008

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

2 голосов
/ 30 октября 2008

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

1 голос
/ 28 сентября 2008

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

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

1 голос
/ 24 сентября 2008

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

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

...