2016-04-09 21 views
0

Я в процессе обновления нашего клиент-серверного приложения ERP к многоуровневому. Мы хотим предложить нашим клиентам возможность иметь свои базы данных в облаке (размещенные на нашем сервере). Так, клиенты написаны на Delphi, сервер является сервером IOCP, написанным также в Delphi (из платформы mORMot), для dbs мы используем встроенный Firebird ,Несколько пулов подключений Firedac

Наши клиенты (скажем 200) могут иметь 25-30 баз данных Firebird (всего 5000-6000 баз данных), к которым обращаются 4-5 пользователей на каждого клиента. Это происходит не сразу. Один пользователь может работать в одном db, другие 2 пользователя могут работать в другом db, но все dbs должны быть доступны и онлайн. Итак, у меня может быть 800-1000 пользователей, работающих на скорости 700-900 дБ. Базы данных не большие, обычно 20-30 МБ каждый, но могут идти до 200 МБ.

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

Итак, мне нужно несколько пулов соединений - для каждой базы данных мне нужен пул, скажем, 2 соединения. Я прочитал о пуле соединений Firedac. Кажется, что TFDManager должен быть идеальным для меня. Я определяю несколько «ConnectionDef» с «Pooled = true» и может поддерживать несколько пулов соединений (каждое соединение длится до нескольких минут бездействия).

Вопросы:

  1. я должен создать все "ConnectionDef" сек до сервера начинает обслуживать запросы?

  2. Может ли TFDManager «обрабатывать» запросы (и тайм-аут подключения при неактивности), в то время как в другом потоке мне нужно создать новую базу данных, поэтому автоматически мне нужно создать новый пул соединений и начать отправлять запросы от новых созданная база данных. Практически я могу вызвать FDManager.AddConnectionDef (..), в то время как другие пулы используются?

ответ

2

AFAIK Firebird embedded не имеет никакого «соединения». Как указано в его названии, он встроен в один и тот же процесс, поэтому нет пула соединений. Пулы соединений необходимы, когда несколько клиентов подключаются/отключаются к одному и тому же БД по сети, тогда как здесь все встроено, и у вас будет прямой доступ к движку Firebird.

Таким образом, вы можете:

  • Определить один "connnection" за Firebird встроенной базы данных;
  • Защитите свой код SOA с помощью мьютекса (или критического раздела) на каждый БД. Фактически, сервер HTTP IOCP mORMot будет запускать входящие запросы из пула потоков, поэтому убедитесь, что весь доступ к БД безопасно сделан.
  • Убедитесь, что вы используете как минимум Firebird 2.5, так как встроенная версия считается потокобезопасной только с версии 2.5 (см. the release notes).
  • Вместо FireDAC рассмотрите возможность использования ZDBC/Zeos (в последней ветви 7.2/7.3), которая имеет приятные функции, а также native mORMot SynDB libraries.
+0

Согласитесь не согласиться - пулы соединений используются для облегчения приобретения ресурса, когда обычно создание/создание нового потребует времени и/или ресурсов. Даже прикрепление файла локальной базы данных к процессу, например fbembed.dll, займет некоторое время и ресурсы - будут проверены привилегии SQL, отдельные буферы будут распределены для каждого вложения, даже если это тот же процесс и тот же файл базы данных (> = FB 2.5). Таким образом, объединение соединений применяется здесь. – emk

+0

Определение «соединений» и защита их критической секцией - это не объединение соединений? Итак, зачем изобретать колесо, когда есть проверенный. Даже если ваш сценарий кажется простым, потому что это всего лишь одно «соединение» для каждой базы данных, мне кажется, что мне нужно как минимум два из них, потому что иногда один клиент может получить соединение в течение более длительного периода времени, поскольку он должен синхронизировать более крупный журнал изменений, поскольку он был в последний раз онлайн. В любом случае, ваше решение является хорошим, потому что у него есть один критический раздел на каждый бит, и у Firedac будет один критический раздел для всех баз данных. – emk

0

Глядя на Firedac источников, кажется, что все о добавляющих определений соединений и приобретающие соединения в объединенном режиме потокобезопасно.

Добавление определения соединения или соответствие один охраняются TMultiReadExclusiveWriteSynchronizer и получения соединения из пула охраняются TCriticalSection.

Итак, ответы:

  1. Я не должен создавать все "ConnectionDef" s, прежде чем сервер начнет обслуживать запросы.
  2. Да, я могу безопасно позвонить FDManager.AddConnectionDef (..), в то время как другие пулы используются.

Использование Firedac, приобретая соединение для любой из этих баз данных будет охраняться одним TCriticalSection. Решение, предложенное @Arnaud Bouchez, представляет собой более узкий доступ, создавая один TCriticalSection для каждой базы данных, и я думаю, что он будет масштабироваться лучше, но вы должны знать об ошибке при использовании нескольких TCriticalSection, тем более, что все будет инициировано сразу :

https://www.delphitools.info/2011/11/30/fixing-tcriticalsection/

В этой статье представляет собой очень простое исправление этой ошибки.

+0

Поскольку вы используете mORMot, вы можете использовать запись 'TSynLocker' или интерфейс/класс' IAutoLocker'/'TAutoLocker', который исправляет ошибку' TCriticalSection', позволяет защитить весь метод за один вызов и использует чтобы сохранить некоторые значения, которые будут защищены блокировкой. См. [TAutoLocker] (http://synopse.info/files/html/api-1.18/SynCommons.html#TAUTOLOCKER) и [TSynLocker] (http://synopse.info/files/html/api-1.18/SynCommons. html # TSYNLOCKER). –

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

  • Нет связанных вопросов^_^