Улучшить множественный синхронизированный доступ к данным
В начале я хотел бы извиниться за чрезмерное использование жирного текста. Я хотел упростить понимание моих длинных вопросов.
У меня проблема с множественным доступом к данным.
Я должен реализовать следующую проблему: у меня есть серверное приложение SERVER_A (на основе TIdServer) со многими (около 100) TCP-соединениями. Целью каждого из этих соединений является:
- Получить сообщение о состоянии (каждые 2-5 с) от КЛИЕНТА. Статус содержит 3 двойных числа, хранящихся в виде текста.
- Отправить ответ от SERVER_A КЛИЕНТУ- после получения статуса
Эти статусы (около 100) должны быть сохранены в таблице базы данных Firebird - TABLE (я использую для этого AnyDAC). Каждый КЛИЕНТ имеет свой номер и свою запись в ТАБЛИЦЕ.
Три других клиентских приложения локальной сети - LOCAL_APPLICATIONS также должны иметь доступ к TABLE. Они должны визуализировать статистические данные из таблицы.
LOCAL_APPLICATIONS иногда приходится изменять одну из записей таблицы. Результаты этого изменения должны быть доставлены нужному КЛИЕНТУ через TCP-соединение SERVER_A в качестве ответа.
Проблема в эффективности такого решения достигается.
Пока что каждый TCP-вызов записывает данные отдельно в TABLE, вызывая значительную перегрузку Firebird, и любая из операций, выполняемых LOCAL_APPLICATIONS, выполняется очень медленно.
Можно также спросить: правильно ли построить LOCAL_ARRAY в SERVER_A, собирать данные со всех TCP-соединений и периодически сохранять их все вместе через фиксированные промежутки времени (например, каждые 2 секунды) в TABLE? Если так, как сделать эффективную синхронизацию данных: пора менять блокировку на LOCAL_ARRAY и блокировать ее во время чтения данных из нее, чтобы сохранить данные в TABLE?
Может быть, лучше использовать переменную sigle для каждого состояния соединения, а затем использовать LOCAL_ARRAY, чтобы избежать блокировки всех полей в LOCAL_ARRAY во время вставки данных из одного КЛИЕНТА? Но это не гибкое решение.
Моя идея хороша для повышения эффективности? Или скорее нет? Что может быть лучшим решением?
С уважением Артик
2 ответа
Посмотрите на шаблон CQRS.
CQRS расшифровывается как разделение ответственности по командным запросам. В основе ее лежит простое понятие, что вы можете использовать другую модель для обновления информации, нежели модель, которую вы используете для чтения информации. Это простое понятие приводит к некоторым глубоким последствиям для проектирования информационных систем.
Из моего эксперимента это очень хорошая схема для реализации масштабирования и отзывчивости в архитектуре клиент-сервер.
Вы можете использовать отдельную базу данных (в памяти, если это возможно) для запросов, а затем иметь командную шину для записи данных.
Это очень близко к тому, что вы хотите реализовать. Возможно, вам может помочь некоторая более высокоуровневая информация, такая как этот шаблон CQRS.
Например, в CQRS для увеличения скорости обычно объединяют несколько команд в один "пакет" операторов SQL в рамках одной транзакции. Некоторые БД допускают привязку массива, что делает его еще быстрее.
Без исходного кода будет сложно выяснить, что не так. С цифрами, которые вы показываете, я подозреваю, что вы должны найти реальные узкие места вашего приложения. Я предполагаю, что вы на самом деле далеки от того, чтобы достичь ограничений FireBird, но именно от того, как вы его используете, он ограничен. Добавление некоторого умного кэша и использование четкого паттерна CQRS может сильно помочь.
Клиентская сторона: создайте функцию / процедуру, которая будет сообщать серверу / таблице "я онлайн" или "я оффлайн" или подобные сообщения, когда пользователь выполняет действие. вместо отправки сообщений о состоянии каждые 2-5 секунд.
Серверная сторона: создайте функцию / процедуру, которая будет сообщать клиентам только самые последние изменения (не полные таблицы), когда новое сообщение поступает от любого клиента.
Или вы можете создать процедуры в Firebird для этого. Это снизит вашу сеть и трафик / нагрузку на сервер.
РЕДАКТИРОВАТЬ:
Другая идея есть; Вы можете создавать дополнительные таблицы для идентификации / перечисления ваших стандартных данных. Как это?
Допустим, вы отправляете или получаете данные "HOT", "COLD", "COOL" для клиентов или от клиентов. длинный текст означает большую нагрузку на сеть и базу данных. Вы можете создать таблицу, которая является стандартной для всех вещей. Давайте сделаем пример;
Название таблицы HotColdCool
ID Description
1 HOT
2 COLD
3 COOL
С этой таблицей вы будете отправлять и получать только ID (любой тип int) вместо полного текста. Это снизит нагрузку на вашу сеть и базу данных для многих клиентов.
если вы объясните больше о вашем проекте, я могу дать вам больше представления об этом.