|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
Здравствуйте, Есть 2-tier бизнес-приложение: [ UI + BLL + DAL ] <---> [ Data Storage ] Что вы думаете о реализации кеша на клиентах? Нужно ли? Какие проблемы при этом возникают и как их можно решить? Я вот у себя решил сделать кеш клиентов, поставщиков и производителей. Разместить его в DAL. Сделал. Правда что-то не догадался запрофилировать скорость работы до использования кеша и после, поэтому насколько повысилась производительность на клиентах сказать не могу. Ну плюсы какие: В памяти только один объект в кеше и все ссылки на него, а не куча одинаковых объектов (например если заказ на 1000 позиций, то в позициях заказа мы не будем иметь 1000 разных объектов производителя которые по сути представляют одного и того же производителя). Ну и из БД не надо тянуть лишний раз объекты которые в кеше. Это особенно полезно в ситуациях типа опять же ситуации с заказом. Читаем заказ из БД и не надо нам читать из БД и создавать на каждую позицию объект производителя — дергаем его из кеша: ManufacturerRepository.GetByID(manufacturerID); Ну да ладно, это я отвлекся. Возникли проблемы с синхронизацией кеша на разных клиентах (компьютерах). Казалось бы такие сущности как клиент, поставщик, производитель редко изменяются. Но дело в том что у меня например в классе клиента есть поля Balance и LastOrderN, которые могут изменяться несколько раз в день. Рассинхронизация значений этих полей может привести к очень неприятным последствиям. Т.е. например на одном клиенте у customer'а номер последнего заказа увеличивается на единицу, а другой клиент то об этом сразу не узнает.. Начинаются думы и приседания с синхронизацией кеша. Потом в голову приходит мысль: Может кеш делать только для объектов которые изменяются реально очень редко (раз в несколько дней и реже). Либо например из класса Customer убрать поля Balance и LastOrderN и сделать работу с ними через методы типа CustomerRepository.GetCustomerBalance(Customer customer) и т.д.? Что скажете? Буду рад если кто-то внесет ясность в этот вопрос, ну и вообще вашим мнениям =) ... |
|||
:
Нравится:
Не нравится:
|
|||
19.04.2008, 17:43 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgC пишет: > Что вы думаете о реализации кеша на клиентах? Нужно ли? Не всегда, но вполне может быть, что можно и нужно. Для кэширования справочников. Какие проблемы > при этом возникают и как их можно решить? Естественно, обновление кэша при изменении справочников данным или другими пользователями. Возможны подходы: автоматически или вручную пользователем, когда он не находит какой-то записи. Вторая проблема - ограничение на размер кэша, т.е. вытеснение. Здесь подойдут классические алгоритмы со счетчиками попаданий в кэш. Но мы разрешаем кэшу расти бесконечно в рамках одной сессии. Третья проблема - разделение закэшированных наборов данных между разными компонентами клиентского приложения. Мы решаем эту проблему копированием наборов - они не должны быть большими, поэтому это достаточно дёшево. > Правда что-то не догадался запрофилировать скорость работы до > использования кеша и после, поэтому насколько повысилась > производительность на клиентах сказать не могу. Так тут и гадать нечего, она повысится однозначно. > Но дело в том что у меня например в классе клиента есть поля Balance и > LastOrderN, которые могут изменяться несколько раз в день. > Рассинхронизация значений этих полей может привести к очень неприятным > последствиям. Т.е. например на одном клиенте у customer'а номер > последнего заказа увеличивается на единицу, а другой клиент то об этом > сразу не узнает.. Значит такие данные просто нельзя кэшировать. вот и все. Кэшируй только вообще неизменяемые справочники. > Начинаются думы и приседания с синхронизацией кеша. > Потом в голову приходит мысль: Может кеш делать только для объектов > которые изменяются реально очень редко (раз в несколько дней и реже). Правильные мысли тебе в голову приходят ! > Либо например из класса Customer убрать поля Balance и LastOrderN и > сделать работу с ними через методы типа > CustomerRepository.GetCustomerBalance(Customer customer) и т.д.? Ну это - другой вопрос, вопрос проектирования БД, но - тоже вариант. Собственно, то, что контрагент и его балланс находятся в одной таблице, иначе как ошибкой проектирования я бы не назвал, но это все - отдельный разговор. Но даже не изменяя структуры БД можно получать эти два поля и все остальные данные контрагентов двумя или трема запросами и кэшировать только один из них, несодержащий эти поля. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
19.04.2008, 21:08 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
M> Автор: MozgC M> Здравствуйте, M> M> Есть 2-tier бизнес-приложение: M> [ UI + BLL + DAL ] <---> [ Data Storage ] M> M> Что вы думаете о реализации кеша на клиентах? Нужно ли? Какие M> проблемы при этом возникают и как их можно решить? В целом, идея правильная. Повышение быстродействия через кэширование - основное преимущество 2-х уровневых приложений перед 3-х уровневыми (где приходиться довольствоваться возможностями тонкого клиента-браузера). Теоретические аспекты хорошо прописаны в подходе, называемом Object-relational mapping. Даже если Вы не программируете на Java, рекомендую почитать документацию по Hibernate. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
20.04.2008, 12:15 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgCЧто вы думаете о реализации кеша на клиентах? Нужно ли? Зависит от ситуации. Для загруженной системы может дать существенный прирост производительности; для плохих каналов - существенный прирост быстродействия. MozgCНо дело в том что у меня например в классе клиента есть поля Balance и LastOrderN, которые могут изменяться несколько раз в день. При кэшировании на клиенте однозначно нужно тянуть с сервера не только id объекта (для поиска в кэше) но и id/таймстамп его последнего изменения и соответственно прочищать кэш. MozgCРассинхронизация значений этих полей может привести к очень неприятным последствиям. Т.е. например на одном клиенте у customer'а номер последнего заказа увеличивается на единицу, а другой клиент то об этом сразу не узнает.. Вот этот вот абзац наводит на мысль, что Вы перетянули на клиента то, что нужно делать на сервере... MozgCПотом в голову приходит мысль: Может кеш делать только для объектов которые изменяются реально очень редко (раз в несколько дней и реже). В чем принципиальная разница? Полагаете, глюка раз в несколько дней принципиально лучше, нежели глюка несколько раз в час? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.04.2008, 15:47 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MasterZiv >Какие проблемы при этом возникают и как их можно решить? Естественно, обновление кэша при изменении справочников данным или другими пользователями. Возможны подходы: автоматически или вручную пользователем, когда он не находит какой-то записи. Если запись не находится в кеше, то кеш автоматически обновляется. С этим проблем нет. Проблема когда на одном клиента данные изменяются - эти изменения должны отобразиться в кешах на других клиентах. > Правда что-то не догадался запрофилировать скорость работы до > использования кеша и после, поэтому насколько повысилась > производительность на клиентах сказать не могу. MasterZiv Так тут и гадать нечего, она повысится однозначно. Вот МакКоннелл пишет что это очень большая ошибка так думать. И что пока реально не запрофилировали нельзя говорить об эффекте оптимизации. Я считаю что он прав. Но допустим, конечно, что производительность повысится. Вопрос в том - насколько она повысится. Если высокоуровневая функция (считывание заказа например) выполнялась 100 мс, а стала 15 мс, то стоит ли из-за этого заморачиваться с кешем? > Но дело в том что у меня например в классе клиента есть поля Balance и > LastOrderN, которые могут изменяться несколько раз в день. > Рассинхронизация значений этих полей может привести к очень неприятным > последствиям. Т.е. например на одном клиенте у customer'а номер > последнего заказа увеличивается на единицу, а другой клиент то об этом > сразу не узнает.. MasterZivЗначит такие данные просто нельзя кэшировать. вот и все. Кэшируй только вообще неизменяемые справочники. Я кеширую клиентов, поставщиков, производителей товара, потому что иногда идут сотни позиций с их идентификаторами. Например мы открываем все заказы за сегодня и ходим сделать один общий заказ нашему дилеру. При чтении заказанных позиций, в каждой позиции идут например CustomerID и ManufacturerID, соответственно на каждую позицию из БД вытягивать все данные клиентов и производителей чтобы создать объекты клиента и производителя - долго. А если есть кеш, то просто делаем типа Customer customer = CustomerRepository.GetByID(customerID) - все моментально. Дополнительно получаем единство объекта, т.е. у нас в кеше один объект клиента Вася Пупкин, и 1000 ссылок на него, а не 1000 разных объектов фактически обозначающих одного и того же Васю Пупкина. > Либо например из класса Customer убрать поля Balance и LastOrderN и > сделать работу с ними через методы типа > CustomerRepository.GetCustomerBalance(Customer customer) и т.д.? MasterZivНу это - другой вопрос, вопрос проектирования БД, но - тоже вариант. Собственно, то, что контрагент и его балланс находятся в одной таблице, иначе как ошибкой проектирования я бы не назвал, но это все - отдельный разговор. А не прочитаете очень краткую лекцию где хранить например баланс клиента и номер его последнего заказа? Мне будет полезно. ... |
|||
:
Нравится:
Не нравится:
|
|||
20.04.2008, 20:42 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
Dmitriy IvanovВ целом, идея правильная. Повышение быстродействия через кэширование - основное преимущество 2-х уровневых приложений перед 3-х уровневыми (где приходиться довольствоваться возможностями тонкого клиента-браузера). Теоретические аспекты хорошо прописаны в подходе, называемом Object-relational mapping. Даже если Вы не программируете на Java, рекомендую почитать документацию по Hibernate. Ну в 3х уровневых приложениях никто так же не мешает сделать кеш на клиентах, хотя думаю что обычно делают на application server'е, на котором размещают DAL с кешем и возможно BLL. Хотя вы наверное говорите о веб-приложениях. Кстати на ASP .NET на серверной стороне можно сделать постоянный кеш а не только на сессию? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.04.2008, 20:46 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
softwarer При кэшировании на клиенте однозначно нужно тянуть с сервера не только id объекта (для поиска в кэше) но и id/таймстамп его последнего изменения и соответственно прочищать кэш. Можно пожалуйста подробнее? softwarer MozgCРассинхронизация значений этих полей может привести к очень неприятным последствиям. Т.е. например на одном клиенте у customer'а номер последнего заказа увеличивается на единицу, а другой клиент то об этом сразу не узнает.. Вот этот вот абзац наводит на мысль, что Вы перетянули на клиента то, что нужно делать на сервере... Может быть. Как бы вы сделали? Напоминаю, что на сервере у меня только СУБД и все. softwarer MozgCПотом в голову приходит мысль: Может кеш делать только для объектов которые изменяются реально очень редко (раз в несколько дней и реже). В чем принципиальная разница? Полагаете, глюка раз в несколько дней принципиально лучше, нежели глюка несколько раз в час? Наверное вы правы... Научите как правильно :) ... |
|||
:
Нравится:
Не нравится:
|
|||
20.04.2008, 20:49 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgCМожно пожалуйста подробнее? Для реализации любого кэша мы должны либо быть уверены, что все обращения к объекту идут через владельца кэша, либо контролировать соответствие объекта в кэше основному. Для контроля следует ввести некий идентификатор версии объекта - например, timestamp его последнего изменения. Каждый раз, когда мы запрашиваем с сервера выборку, следует тянуть не только id объектов, но и их версию, сравнивать с локальной и использовать объект из кэша только при совпадении (при несовпадении - дозапрашивать). Каждый раз, когда мы отправляем на сервер изменение объекта, следует отправлять также локальную версию и при несовпадении с серверной - запускать процедуру разрешения конфликта обновлений. MozgCМожет быть. Как бы вы сделали? Напоминаю, что на сервере у меня только СУБД и все. И чего Вам там не хватает? ... |
|||
:
Нравится:
Не нравится:
|
|||
20.04.2008, 21:55 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
softwarerДля реализации любого кэша мы должны либо быть уверены, что все обращения к объекту идут через владельца кэша, либо контролировать соответствие объекта в кэше основному. Для контроля следует ввести некий идентификатор версии объекта - например, timestamp его последнего изменения. Каждый раз, когда мы запрашиваем с сервера выборку, следует тянуть не только id объектов, но и их версию, сравнивать с локальной и использовать объект из кэша только при совпадении (при несовпадении - дозапрашивать). Как это поможет в следующей ситуации: открываем форму создания заказов поставщикам. При этом загружаются все существующие поставщики (и помещаются в combobox). Поставщики загружаются из кеша, с описанной вами проверкой по timestamp. все ок. Тут на другом клиенте кто-то делает заказ поставщику X и номер его последнего заказа увеличивается на 1. На первоначальном клиенте мы тоже создаем заказ поставщику X и так как номер последнего заказа поставщика X берется из объектка Supplier из кеша (который у нас точно обновленный на момент загрузки формы, но уже устаревший на данный момент), то происходит попытка создать заказ под номером, под которым уже есть заказ (сделанный недавно на другом клиенте). Как быть? Чем в этом случае помогает дополнительная проверка по timestamp'у? softwarerКаждый раз, когда мы отправляем на сервер изменение объекта, следует отправлять также локальную версию и при несовпадении с серверной - запускать процедуру разрешения конфликта обновлений. Не понял что вы имеете в виду.. softwarer MozgCРассинхронизация значений этих полей может привести к очень неприятным последствиям. Т.е. например на одном клиенте у customer'а номер последнего заказа увеличивается на единицу, а другой клиент то об этом сразу не узнает.. Вот этот вот абзац наводит на мысль, что Вы перетянули на клиента то, что нужно делать на сервере... Можно подробнее, пожалуйста? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 02:15 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgC Для реализации любого кэша мы должны либо быть уверены, что все обращения к объекту идут через владельца кэша, либо контролировать соответствие объекта в кэше основному. Для контроля следует ввести ..... ещё одну СУБД-КЭШ которая постоянно синхронизироется с основной БД. Разве не видно, что это велосипед и работать не будет. А если будет, то слишком дорогой ценой. Я видел почти такую работу, при которой у пользователя в меню был пукт: "Очистить кэш". Ну или почти такое... Никакому пользователю нельзя было вразумительно объяснить - когда и как работает этот пункт. НО всякий раз как что-то неработало, была рекомендация большого брата-программиста - жать этот пункт. ====== авторЯ вот у себя решил сделать кеш клиентов, поставщиков и производителей. Разместить его в DAL. Сделал. Правда что-то не догадался запрофилировать скорость работы до использования кеша и после, поэтому насколько повысилась производительность на клиентах сказать не могу. вот захотелось .... и сделал. Что улучшилось после этого непонятно. Зато геморроя добавилось это точно. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 09:39 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgC пишет: > Если запись не находится в кеше, то кеш автоматически обновляется. С > этим проблем нет. Это как это вы понимаете, какая запись там должна находится? Вы что в приложение заранее прошиваете все возможные записи ? Ну-ка объясните ... Проблема когда на одном клиента данные изменяются - > эти изменения должны отобразиться в кешах на других клиентах. Я вообще-то об этом и говорил, ну да ладно. > Вот МакКоннелл пишет что это очень большая ошибка так думать. И что пока > реально не запрофилировали нельзя говорить об эффекте оптимизации. Я > считаю что он прав. приведите хотя бы умозрительный пример, когда это будет не так. И до этого - определение производительности, чтобы было понятно, о чем спрорить. Но допустим, конечно, что производительность > повысится. Вопрос в том - насколько она повысится. Если высокоуровневая > функция (считывание заказа например) выполнялась 100 мс, а стала 15 мс, > то стоит ли из-за этого заморачиваться с кешем? тут главное - дать приложению механизм, который может быть потом использован. А использовать его или нет - уже надо решать конкретно. > Я кеширую клиентов, поставщиков, производителей товара, потому что > иногда идут сотни позиций с их идентификаторами. Например мы открываем И что, затем делаете JOIN на клиенте ? Не, я такого не имел в виду. Это - согласен, далеко не всегда будет лучше по производительности и вообще - вредно. Такого я бы не делал. СУБД Join-ит записи лучше, чем клиент. > А не прочитаете очень краткую лекцию где хранить например баланс клиента > и номер его последнего заказа? Мне будет полезно. Если и прочитаю, то в другом треде. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 10:14 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
softwarer пишет: > Для реализации любого кэша мы должны либо быть уверены, что все > обращения к объекту идут через владельца кэша, либо контролировать > соответствие объекта в кэше основному. Для контроля следует ввести некий > идентификатор версии объекта - например, timestamp его последнего > изменения. Каждый раз, когда мы запрашиваем с сервера выборку, следует > тянуть не только id объектов, но и их версию, сравнивать с локальной и > использовать объект из кэша только при совпадении (при несовпадении - > дозапрашивать). Каждый раз, когда мы отправляем на сервер изменение > объекта, следует отправлять также локальную версию и при несовпадении с > серверной - запускать процедуру разрешения конфликта обновлений. И зачем все эти навороты ? Если надо прочитать что-то в кэш - так зачем что-то там сравнивать ? Все равно оно уже пришло, просто сохранить и все. Ну и модифицировать что-то через кэш - это тоже по-моему неправильно. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 10:18 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgC пишет: > Как это поможет в следующей ситуации: открываем форму создания заказов > поставщикам. При этом загружаются все существующие поставщики (и > помещаются в combobox). Поставщики загружаются из кеша, с описанной вами > проверкой по timestamp. все ок. Тут на другом клиенте кто-то делает > заказ поставщику X и номер его последнего заказа увеличивается на 1. На > первоначальном клиенте мы тоже создаем заказ поставщику X и так как > номер последнего заказа поставщика X берется из объектка Supplier из > кеша (который у нас точно обновленный на момент загрузки формы, но уже > устаревший на данный момент), то происходит попытка создать заказ под > номером, под которым уже есть заказ (сделанный недавно на другом > клиенте). Как быть? Я еще раз говорю (и softwarer вам говорил тоже), что такую логику через кэш делать нельзя. Вот закачать список поставщиков в комбик - можно. А номер заказа нужно присваивать на сервере. Номер заказа в кэше лежать не должен. Чем в этом случае помогает дополнительная проверка > по timestamp'у? Ничем. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 10:21 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
Petro123 пишет: > Я видел почти такую работу, при которой у пользователя в меню был пукт: > "Очистить кэш". Ну или почти такое... > Никакому пользователю нельзя было вразумительно объяснить - когда и как > работает этот пункт. > НО всякий раз как что-то неработало, была рекомендация большого > брата-программиста - жать этот пункт. у нас в каждой форме есть такая кнопка - обновить справочники для этой формы. Все пользователи вроде бы понимают, что это и зачем. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 10:22 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
если под кэшем вы понимете просто справочник, то я фигею. Т.к. сам комбобокс справочника можно рассматривать как кэш :) MasterZiv Естественно, обновление кэша при изменении справочников данным или другими пользователями. Возможны подходы: автоматически или вручную пользователем, когда он не находит какой-то записи. ======== при обновлении формы -> перезапрос -> комбобокс покажет новую запись? Вторая проблема - ограничение на размер кэша, т.е. вытеснение. Здесь подойдут классические алгоритмы со счетчиками попаданий в кэш. Но мы разрешаем кэшу расти бесконечно в рамках одной сессии. ======== что решает промежуточный уровень? Третья проблема - разделение закэшированных наборов данных между разными компонентами клиентского приложения. Мы решаем эту проблему копированием наборов - они не должны быть большими, поэтому это достаточно дёшево. ======== т.е. простое копирование указателя на объект ADODataSet? ADODataSet2 := ADODataSet1 ? Так тут и гадать нечего, она повысится однозначно. ======= сколько будет в граммах? Значит такие данные просто нельзя кэшировать. вот и все. Кэшируй только вообще неизменяемые справочники. ======= в компонентах доступа к БД уже есть КЭШ в таком случае. Это набор данных на клиенте. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 11:06 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MasterZiv у нас в каждой форме есть такая кнопка - обновить справочники для этой формы. Все пользователи вроде бы понимают, что это и зачем. Posted via ActualForum NNTP Server 1.4 только не надо называть это кэшем? И его проектировать. В ослике F5 тоже кэш? ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 11:09 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgCКак это поможет в следующей ситуации: В первую очередь, кэш вообще не имеет отношения к этой ситуации. Если Вы уберете из модели кэш и будете каждый раз читать из базы, описанная "проблема" ничуть не изменится. Далее, кэш (как и любое другое средство) вовсе не предназначен быть панацеей от заведомо кривой архитектуры, справедливо раскритикованной еще пятнадцать лет назад. Наконец, поможет указанным способом - возможностью определить наличие конфликта и разрешить его. MozgCКак быть? Чем в этом случае помогает дополнительная проверка по timestamp'у? Тем, что программа не испортит молча данные, как случилось бы без проверки. MozgCНе понял что вы имеете в виду.. Гуглите по словам "оптимистическая блокировка". MozgCМожно подробнее, пожалуйста? Так что подробнее? Судя по описанию, Вы тянете на клиента ту бизнес-логику, которой там совершенно не место. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 13:09 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
M> Автор: MasterZiv M> M> softwarer пишет: M> M>> Для реализации любого кэша мы должны либо быть уверены, что все M>> обращения к объекту идут через владельца кэша, либо контролировать M>> соответствие объекта в кэше основному. Для контроля следует ввести M>> некий идентификатор версии объекта - например, timestamp его M>> последнего изменения. Каждый раз, когда мы запрашиваем с сервера M>> выборку, следует тянуть не только id объектов, но и их версию, M>> сравнивать с локальной и использовать объект из кэша только при M>> совпадении (при несовпадении - дозапрашивать). Каждый раз, когда мы M>> отправляем на сервер изменение объекта, следует отправлять также M>> локальную версию и при несовпадении с серверной - запускать M>> процедуру разрешения конфликта обновлений. M> M> И зачем все эти навороты ? Если надо прочитать что-то в кэш - так M> зачем что-то там сравнивать ? Все равно оно уже пришло, просто M> сохранить и все. Ну и модифицировать что-то через кэш - это тоже M> по-моему неправильно. Это не навороты, а минимально необходимый набор. Через призму ORM естественней объяснить. Кэш на клиенте - это объектно-ориентированная модель реального мира, который в РБД представлен таблицами. Разумеется, эта модель охватывает меньшую часть реальности: в кэш - попадает не все данные из РБД. Редактирование на клиенте - это прежде всего изменение в ОО-модели. Затем он передается по цепочке РБД -> другие клиенты. Дальше все по классике: транзакция редактирования длинная, другие клиенты за это время могут что-то изменить - значит, необходима либо пессимистическая блокировка, либо оптимистическая с разрешением конфликтов. Поддержание актуальности кэша - эта необходимая плата. Лучше ее платить за интересный ОО-кэш, чем за "плоские" наборы данных :-) Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 19:03 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
Dmitriy IvanovПоддержание актуальности кэша - эта необходимая плата. Лучше ее платить за интересный ОО-кэш, чем за "плоские" наборы данных :-) Фи. ... |
|||
:
Нравится:
Не нравится:
|
|||
21.04.2008, 22:26 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
Petro123 пишет: > Т.к. сам комбобокс справочника можно рассматривать как кэш :) Да, что ж плохого-то ? > ======== при обновлении формы -> перезапрос -> комбобокс покажет новую > запись? При обновлении формы - нет. при обновлении справочников - да. > ======== что решает промежуточный уровень? какой промежуточный уровень ? > ======== т.е. простое копирование указателя на объект ADODataSet? > ADODataSet2 := ADODataSet1 ? У нас ADO не используется, так что что такое ADODataSet я представляю с трудом. > ======= в компонентах доступа к БД уже есть КЭШ в таком случае. Это > набор данных на клиенте. Да, в компонентах доступа к БД есть кэш. Posted via ActualForum NNTP Server 1.4 ... |
|||
:
Нравится:
Не нравится:
|
|||
22.04.2008, 17:57 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
В общем, очень долго поразмышляв, я решил отказаться от кеша на клиенте. Точнее использовать только "местный кеш", в пределах одной бизнес-транзакции. Но сначала решил сделать "замеры" и вот результаты: Задача: загрузка всех позиций из заказа клиента. Позиций 80, среди 80 позиций 7 разных производителей. ХП к сожалению не использовались в виду лени их создания. ПО и СУБД находились на одном компьютере (1-tier). Схема 1: Кеширование "на процесс", т.е. единый кеш на весь клиент и на все время работы клиента. Кеш предварительно заполнен всеми производителями. Результат: 19 мс Схема 2: Местное кеширование, т.е. как я сейчас собираюсь сделать — кеширование в пределах бизнес-транзакции. Результат: 23 мс Схема 3: Местное кеширование. Местный кеш вначале бизнес-транзакции полностью заполняется производителями. Результат: 12 мс Схема 4: Без какого-либо кеширования на клиенте, вся информация о производителях подключаются INNER JOIN'ом и для каждой позиции создается свой объект производителя: Результат: 11 мс Схема 5: Без какого-либо кеширования на клиенте, за каждым производителем лезем отдельным запросом в БД. Результат: 177 мс На результаты конечно нельзя сильно полагаться из-за того что не использовались ХП и думаю мог быть достаточный overhead из-за парсинга и построения планов зарпосов СУБД. Смущает результат первой схемы. Он почему-то больше чем результат схемы 3, хотя казалось бы результаты должны быть одинаковы. Разница только что в схеме 1 использовался мой самодельный Cache<T> который прямо делегировал работу в Dictionary, а в схеме 3 Dictionary использовался напрямую. Результаты подтвердили мои мысли о том, что использование единого кеша на процесс особых преимуществ по скорости не дает, и что схемы 2-3 дают хорошие результаты при намного меньшем геморое. Но тут все-таки вопрос к более опытным: какие могут быть подводные камни при использовании кеша на бизнес-транзакцию вместо кеша на процесс? Само собой сразу приходит на ум синхронизация изменений, типа в одном окошечке изменили, в другом окошке изменения отобразились. Но реально ли это нужно и реально ли из-за этого могут быть какие-нибудь проблемы? Теперь буду думать как красиво сделать использование такого кеша на бизнес-транзакцию. Если делать отдельный generic класс типа LocalCache, то ему видимо надо будет передавать объект доступа к БД из DAL, реализующий какой-нибудь универсальный IAccessor с методом типа LoadObject(PrimaryKey key), либо сразу делегат на метод загрузки объекта по PK. Либо делать отдельные классы кешей на каждую сущность, типа CustomerLocalCache =) но это я почти уверен неправильно. Как лучше? Буду рад примерам. PS. Тут мне говорили что я перетаскиваю на клиент то, что должно делаться на сервере. Имеете в виду, что правильнее чтобы например ХП сама назначала номер заказу поставщика? ... |
|||
:
Нравится:
Не нравится:
|
|||
23.04.2008, 05:55 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgC PS. Тут мне говорили что я перетаскиваю на клиент то, что должно делаться на сервере. Имеете в виду, что правильнее чтобы например ХП сама назначала номер заказу поставщика? правильнее не делать велосипедов, а использовать библиотеки доступа к БД (там есть всё что Вам нужно). Или вы системщик, и её разрабатываете. - какой язык? - какие библиотеки используете по данному ЯП? - чем не устраивает кэш в СУБД (штатный) - вы прикладник или пишете системную библиотеку? - что за изобретение - "местный кеш", в пределах одной бизнес-транзакции? - правильная работа с СУБД/ЯП/клиент-серверной технологией исключит нужность кэша - чтобы не грузить весь справочник на клиента, кроме кэша есть A,B,C,D.... технологии кроме кэша. - не гонись за миллисекундами, - смотри выше. Удачи! ... |
|||
:
Нравится:
Не нравится:
|
|||
23.04.2008, 11:53 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
Petro123 MozgC PS. Тут мне говорили что я перетаскиваю на клиент то, что должно делаться на сервере. Имеете в виду, что правильнее чтобы например ХП сама назначала номер заказу поставщика? правильнее не делать велосипедов, а использовать библиотеки доступа к БД А в чем я делаю велосипед? Можно пожалуйста конкретнее, без абстракций и метафор? И что вы имеете в виду под библиотеками доступа к БД? Petro123 - какой язык? - какие библиотеки используете по данному ЯП? Хм.. Вам действительно важно это? C#, ADO .NET, MySQL Connector for .NET. Petro123 - чем не устраивает кэш в СУБД (штатный) По скорости вытаскивания плоских данных устраивает. Хочется обеспечить единство объектов, а не городить одинаковые объекты к тому же еще и понижая скорость за счет постоянного инстанциирования. Petro123 - вы прикладник или пишете системную библиотеку? прикладник. Petro123 - что за изобретение - "местный кеш", в пределах одной бизнес-транзакции? Это не изобретение. Identity Map который заполняется и используется во время одной бизнес-транзакции. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.04.2008, 03:20 |
|
Кеш в 2-tier приложении
|
|||
---|---|---|---|
#18+
MozgC Petro123 MozgC PS. Тут мне говорили что я перетаскиваю на клиент то, что должно делаться на сервере. Имеете в виду, что правильнее чтобы например ХП сама назначала номер заказу поставщика? правильнее не делать велосипедов, а использовать библиотеки доступа к БД А в чем я делаю велосипед? Можно пожалуйста конкретнее, без абстракций и метафор? ====== Велосипед, это когда не разобравшись в штатных средствах пишут новые. Ниже вы привели ADO. ТАМ ЕСТЬ КЭШ. И что вы имеете в виду под библиотеками доступа к БД? ======= то что написал НЕПРИКЛАДНИК :) Petro123 - какой язык? - какие библиотеки используете по данному ЯП? Хм.. Вам действительно важно это? C#, ADO .NET, MySQL Connector for .NET. ======= в технических статьях (а также топиках) пишутся и анализируются Ваши, так называемые кэши, в этих ЯП. Petro123 - чем не устраивает кэш в СУБД (штатный) По скорости вытаскивания плоских данных устраивает. ==== справочник - это ПЛОСКИЙ НАБОР ДАННЫХ Хочется обеспечить единство объектов, а не городить одинаковые объекты к тому же еще и понижая скорость за счет постоянного инстанциирования. ===== займись ООБД. Там кэши тоже уже есть Petro123 - вы прикладник или пишете системную библиотеку? прикладник. ==== учись использовать чужие решения Petro123 - что за изобретение - "местный кеш", в пределах одной бизнес-транзакции? Это не изобретение. Identity Map который заполняется и используется во время одной бизнес-транзакции. ====== да, неправ, есть такое. Только не для прикладника :). См. ниже http://ooad.asf.ru/Pattern.aspx?IdKat=7&IdPat=9 шаблон проектированияКоллекция объектов помогает избежать конфликтов обновления, возникающих в пределах одного сеанса, однако она бессильна что-либо сделать в случае межсеансовых проблем, а это довольно сложный вопрос ЗЫ. Вопросы того как "подружить" плоскую СУБД с объектной моделью на клиенте чрезвычайно сложные. IMHO Удачи. ... |
|||
:
Нравится:
Не нравится:
|
|||
24.04.2008, 10:01 |
|
|
start [/forum/topic.php?fid=33&fpage=45&tid=1548800]: |
0ms |
get settings: |
8ms |
get forum list: |
11ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
55ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
54ms |
get tp. blocked users: |
1ms |
others: | 305ms |
total: | 455ms |
0 / 0 |