Название: Кэширование данных, полученных с сервера Отправлено: JamS007 от Сентябрь 24, 2011, 10:54 Здравствуйте, прошу помощи в решении следующей задачи:
Есть сервер, который напрямую связывается с сервером БД (postgres) и выполняет роль посредника между всеми клиентами и самой БД. Такой механизм выбран по нескольким причинам и уже на 90% реализован, поэтому от него отказываться нельзя. На стороне клиента должна отображаться таблица с товарами и их характеристиками в зависимости от выбранного раздела. Но, проблема в том, что товаров в выбранном разделе может быть очень много, и передать всю информацию про них из БД клиенту будет очень накладно по времени, да и нагрузка на сеть вырастет. У меня уже есть несколько идей по оптимизации этого процесса: 1. Передавать клиенту только то, что уместиться в регион видимости QTableView, а если ползунок прокрутки спуститься - передать еще порцию информации. Тут проблема в том, как отследить какая информация уже передана на клиент, а какая еще нет. ведь если хранить на сервере список с переданными полями, то он очень быстро скушает всю оп. память, а диск его кидать = затормозить сервер. 2. Все ранее принятые записи писать в кэш, и загружать данные в первую очередь из кэша, а уже потом обращаться к серверу. В этом случае проблема в том, чтобы синхронизировать информацию между несколькими клиентами, так как каждый клиент имеет право удалить или изменить запись, а все другие клиенты должны об этом "знать", чтобы обновить свой кэш. Другие идеи также приветствоваться, спасибо. Название: Re: Кэширование данных, полученных с сервера Отправлено: asvil от Сентябрь 24, 2011, 11:10 А почему бы не предоставить пользователю фильтрацию запрашиваемых данных?
Название: Re: Кэширование данных, полученных с сервера Отправлено: JamS007 от Сентябрь 24, 2011, 11:15 Эта возможность есть, но даже она в теории может давать на выходе много данных, которые тоже желательно кеэшировать или показывать не все.
Название: Re: Кэширование данных, полученных с сервера Отправлено: demiurg от Сентябрь 24, 2011, 11:21 А что вам мешает на сервере с БД поставить APACH и запустить php скрипт. Сразу все проблемы отпадут... И на хост любой поставитьм можно... И клиенту не надо будет ставить какие то приложения... Всё из браузера посмотрит...
Название: Re: Кэширование данных, полученных с сервера Отправлено: JamS007 от Сентябрь 24, 2011, 11:26 demiurg, спасибо но данный вариант не подходит.
Название: Re: Кэширование данных, полученных с сервера Отправлено: Rem Norton от Сентябрь 24, 2011, 12:11 Под описаную задачу подходит QSqlQueryModel. Она засасывает 256 строк сразу, остальные по факту прокрутки View. НО есть ограничение: если резалтсет forwardOnly(), то она ничего не отобразит. Наступал на эти грабли только когда пытался подружить QSqlQueryModel с MS SQL. У MS, если резалтсет надо получить из хранимой процедуры, то в QSqlQuery надо ставить forwardOnly = true, а в коде QSqlQueryModel четко прописано, что с такими курсорами она не работает. Возможно у Postgres (не проверял, не уверен) есть подобное ограничение при получении резалтсета из хранимой процедуры.
Название: Re: Кэширование данных, полученных с сервера Отправлено: JamS007 от Сентябрь 24, 2011, 14:07 Rem Norton, да, я знаю что QSqlQueryModel подходит под описанную задачу, но, для ее работы нужен адрес хоста с БД, а мы имеем только адрес промежуточного сервера.
Возможно, покопаю исходники QSqlQueryModel. Спасибо. Название: Re: Кэширование данных, полученных с сервера Отправлено: Rem Norton от Сентябрь 24, 2011, 19:19 Копать QSqlQueryModel не нужно. Если какая-то экзотика в подключении, то капать надо QSqlDriver. Все подключения только там, все остальное - надстройка.
Кстати QSqlDriver легко пишется самостоятельно при наличии документации на API нужной СУБД. Название: Re: Кэширование данных, полученных с сервера Отправлено: vlad-mal от Сентябрь 30, 2011, 16:24 Здравствуйте, прошу помощи в решении следующей задачи: Совсем недавно решил подобную задачу, обычной двузвенкой. Основная идея: клиенту информация передается только та, которая ему нужна (т.е., на которую он смотрит) :)Есть сервер, который напрямую связывается с сервером БД (postgres) и выполняет роль посредника между всеми клиентами и самой БД. Такой механизм выбран по нескольким причинам и уже на 90% реализован, поэтому от него отказываться нельзя. На стороне клиента должна отображаться таблица с товарами и их характеристиками в зависимости от выбранного раздела. Но, проблема в том, что товаров в выбранном разделе может быть очень много, и передать всю информацию про них из БД клиенту будет очень накладно по времени, да и нагрузка на сеть вырастет. У меня уже есть несколько идей по оптимизации этого процесса: 1. Передавать клиенту только то, что уместиться в регион видимости QTableView, а если ползунок прокрутки спуститься - передать еще порцию информации. Тут проблема в том, как отследить какая информация уже передана на клиент, а какая еще нет. ведь если хранить на сервере список с переданными полями, то он очень быстро скушает всю оп. память, а диск его кидать = затормозить сервер. 2. Все ранее принятые записи писать в кэш, и загружать данные в первую очередь из кэша, а уже потом обращаться к серверу. В этом случае проблема в том, чтобы синхронизировать информацию между несколькими клиентами, так как каждый клиент имеет право удалить или изменить запись, а все другие клиенты должны об этом "знать", чтобы обновить свой кэш. Другие идеи также приветствоваться, спасибо. 1. Клиент, желая отобразить набор записей в нужном порядке, загружает только набор идентификаторов этих записей, в том же порядке (если использовать 4-байтное целое, то получается быстро и не накладно: 4МБ для миллиона записей). 2. Данные отображаются в табличке (ну или в дереве) со множеством столбцов, состав которых клиент, естественно, знает. 3. Перед выполнением перерисовки (по любой причине - скроллинг, ресайзинг и проч.) таблички формируется список идентификаторов, которые должны быть показаны в обновляемой области (причем, не обязательно она совпадает с клиентской областью). 4. Для полученного списка идентификаторов выполняется проверка наличия значений полей (записей) в локальном кэше. Для тех, которых в локальном кэше нет, данные подгружаются в кэш одним запросом. 5. Далее, при выполнении перерисовки элементов (ячеек) таблички, последняя извлекает данные из кэша. ~~~~~~~~~~~~ Все операции выполняются по инициативе элемента отображения (таблички). При изменении данных на сервере локальные кэши клиентов сбрасываются и выполняется перерисовка видимой части таблички, и, если измененная информация попала в область видимости других клиентов - она сразу видна. Таким образом, в кэши грузится только то, на что смотрит пользователь. При удалении записи на других клиентах она не исчезает (ибо список идентификаторов не изменялся), а отображается пустой строкой серого цвета, что наглядно. Есть еще кнопа "Обновить", обновляющая список идентификаторов. Отслеживание добавления записей реализовывать не стал по политическим причинам (при добавлении у других клиентов энейблится кнопка "Обновить" - что оказалось достаточно). Трудность была, как ни странно, в реализации быстрого кэша (сказывались незнания основ). В общем, пригодились ассоциативные массивы в комбинации со связным списком (связный список - для того, чтобы ограничить рост кэша - хотя, если записей не более сотни тысяч, можно и не ограничивать). ...когда клиентов стало достаточно много, пришлось ввести небольшую случайную задержку для операции сброса кеша/перерисовки при модификации данных ну других клиентах, чтобы не перегружать сервер сотней одновременных запросов со всех клиентов. |