Насколько хорошо PostgreSQL работает с большим количеством баз данных?


9

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

Итак, мы подумали о создании отдельной базы данных в Postgres для каждого клиента. Может ли это решение масштабироваться, скажем, до 10-20К баз данных? Как хорошо?

У кого-нибудь есть лучшее решение для этого?

Заранее спасибо.

Ответы:


10

На нижнем уровне, это в основном сводится к "вы можете абсолютно сказать, что у вас нет общих данных?" В отличие от mysql, база данных является абсолютной границей в postgresql. Вы не можете, SELECT zip_code FROM common.city_zip WHERE city=...если вы идете с отдельными базами данных (по крайней мере, не без dblink).

Если у вас есть какие-либо общие данные, «схема» postgresql похожа на то, что mysql называет «базой данных» . Вы можете CREATE SCHEMA clienta; CREATE TABLE clienta.customer (...);. Вы бы создать схему для каждого клиента, что пользователь клиента будет иметь свою схему первый в своем пути поиска и разрешения будут предоставляться таким образом , чтобы пользователь - клиент А был бы иметь доступ к clientaи publicсхемам (и их таблица).

Ваша проблема заключается в том, что на верхнем уровне # клиентов каждая таблица хранится в виде файла, поэтому независимо от того, используете ли вы одну базу данных для каждого клиента, одну схему для каждого клиента или используете что-то вроде ${client}_customerимен таблиц, вы будете Скорее всего, вы столкнетесь с ограничениями файловых дескрипторов для 10 000 клиентов, даже если у вас была только одна таблица на клиента (плюс один файловый дескриптор на соединение). Конечно, вы можете настроить максимальное количество файловых дескрипторов ядра на лету, используя sysctl, но ограничение для каждого процесса (ulimit) потребует перезапуска postgresql, если вы установите его слишком низким в первый раз.

Альтернатива состоит в том, чтобы иметь «одну большую таблицу» со столбцом клиента, который идентифицирует, к какому клиенту принадлежит эта строка (в идеале, по имени пользователя, если у вас есть один пользователь на клиента, это облегчает работу под много) Не предоставляя клиентам никакого доступа к этой таблице, вы можете создавать клиентские представления (или использовать session_userдля идентификации текущего клиента). Обновления не могут быть сделаны непосредственно через представление, все же. Вам необходимо иметь определенные функции для вставки / обновления / удаления в таблице (один набор функций на клиента или другое использование session_user) с функциями, используемыми SECURITY DEFINERдля выполнения в качестве специального пользователя с разрешением вставлять / обновлять / удалять таблицы (примечание : session_userиспользуется потому что userиcurrent_user основаны на текущем контексте, и внутри функции SECURITY DEFINER это всегда будет пользователь, который определил функцию).

С точки зрения производительности, помимо проблемы fd, я, честно говоря, не знаю, что произойдет с 10000 базами данных в postgresql, в отличие от одной большой таблицы с данными на 10000 клиентов. Правильный дизайн индекса не должен допускать медленной обработки большой таблицы.

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


Привет, ДерфК. Я не могу использовать подход «один большой стол» по причине, которую вы указали. Даже если сегодня модели данных одинаковы для каждого пользователя, мы не можем гарантировать, что они всегда будут одинаковыми. Кроме того, я не знал об абсолютной границе базы данных в PSQL (поскольку у нас есть некоторые общие данные). Я думаю, что оставил схемы и подходы к именам таблиц. По вашему опыту, насколько сложно управлять таким количеством баз данных (даже на разных серверах)?
Карлос

@Eduardo Самая большая трудность, с которой я столкнулся, заключается в том, чтобы убедиться, что когда модель данных должна измениться для всех, это будет сделано. Когда-нибудь мы адаптируем что-то вроде системы Rails для управления изменениями в модели данных, до тех пор, пока у меня не появится скрипт, который проходит через клиентов и выполняет одну и ту же команду для каждой базы данных. Так как мы вообще не делаем общие данные, все остальное было довольно легко. Если вы используете одну базу данных с несколькими схемами, вы все равно можете pg_dump -nсоздавать дамп одной клиентской схемы за раз, используя (не забудьте также сбросить свою общую схему!), Чтобы psql -E\dn
вывести

@ Эдуардо не разрабатывает для функций, которые вы не имеете права. Если бы это было так, моя машина была бы подводной лодкой, которая могла бы отражать медведей и могла бы лететь на Луну. Существует множество надежных шаблонов проектирования баз данных, которые позволят вам начать с большой таблицы и добавлять дополнительные функции по мере необходимости. Главное - спросить себя, что вам нужно сегодня и что ваша оперативная команда сможет поддержать на основе прогнозов роста.
Иеремия Пешка

@DerfK, какой веб-стек вы используете сегодня?
Карлос

@ Иеремия, у тебя есть хорошая мысль. У вас есть опыт работы с мультитенантными приложениями?
Карлос

3

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

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

Если вы хотите продолжить работу над своим дизайном, вот мои основные проблемы:

  1. исчерпание открытых файловых дескрипторов ( ulimit -n) в вашей операционной системе
  2. настройка 10000+ баз данных для различных шаблонов запросов
  3. администрирование 10 000+ баз данных с различными проблемами безопасности (резервное копирование и потенциальное восстановление. Вы действительно хотите восстановить более 10 000 баз данных в случае сбоя сервера?)
  4. развертывание изменений в более чем 10000 баз данных

И насколько сложно было бы сделать резервную копию и восстановить данные клиента? Проще сделать это с помощью хранимых процедур или схем? Как вы заявили, в дизайне приложения для подключения к базе данных используется только один общий пользователь. Сначала подход с несколькими базами данных рассматривался с точки зрения управления, а не безопасности.
Карлос

Параметризованные хранимые процедуры не защищают ни от чего, кроме SQL-инъекций. Если одна из этих процедур делает SELECT * WHERE clientId = 3, у вас есть утечка безопасности.
Микероби
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.