Re[13]: Подходы к организации 3-tier
От: IT Россия linq2db.com
Дата: 29.07.05 04:55
Оценка:
Здравствуйте, vdimas, Вы писали:

Пофлудим?

IT>>Здесь мы дружно упираемся в вопрос, что эффективнее — забрать сразу всё состояние или выщемлять его из сервера по одному маленькому кусочку.


V>Или использовать некий стандартный механизм хранения данных серверного объекта на клиенте. А если этот механизм еще будет поддерживать бининг в полном объеме — то это в разы все упрощает.


Вопрос не в простоте, вопрос в производительности приложения. Что больше напрягает сервер — один большой запрос или много маленьких?

IT>>Ну как же? Твой объект живёт на сервере и у меня имеется только ссылка на него. Занимать такой ерундой как запоминать какие его свойства я уже прочитал, а какие нет, я не собираюсь.


V>Хм, я именно это и делаю в своей системе. Вернее, система сама это делает.


Да это как бы не проблема, в RFD даже поддержка для этого есть. Но всё равно вопрос, если тебе надо прочитать сначала поле FirstName, а затем LastName, ты два раза к серверу будешь обращаться?

V>Это особенно актуально, если нам нужно не просто значение некоего св-ва (строка или число), а список связанных объектов.


Подгрузка списков это отдельная задача. Обычно достаточно двух типов методов для top-объектво в иерархии: GetSomething и GetSomethingDetails. Первый возвращает единственную запись в которой хранится сам объект, второй ту же запись + все подчинённые объекты, их списки и т.д. Т.е. такой запрос полностью восстанавливает иерархию объекта.

IT>>Для таких задач лучше подходят всевозможные системы data/business flow, которые как раз и обеспечивают то, что ты называешь длинными транзакциями. TK уже предлагал для этого задействовать BizTalk, в принципе я с ним согласен. Подобные задачи представляются достаточно простыми при наличии соответствующего софта и осилисть их может человек, являющийся специалистом в предметной области. Высококвалифицированным программистом для этого быть не надо. Но если же заниматься разработкой такого софта, при этом работая в отделе автоматизации, то гуд лак


V>Можно обойтись и без "длинных транзакций". Если мы имеем на серваке StateFull, и эти незакоммиченные данные доступны другим сессиям по read-only, то можно добиться интересных эффектов.


Ну да. Можно добиться, например, подвисания сервера и, в результате, потери данных.

V>Пример из жизни:

V>- десятки девочек набивают накладные
V>- накладные состоят в среднем из 100-300 строк (оптовая торговля бытовой химией), т.е. процедура набивки одной накладной довольно длинная
V>- в системах типа 1С постоянно случаются накладки, когда несколько девочек пытаются одновременно продать остатки одной и той же позиции товара, ибо на момент набивки им всем система показывает наличие товара

Действительно, такие задачи иногда встречаются в жизни. Но строить на основании этого всю систему как stateful — это нонсенс. Такую задачку надо выделить из общей массы, отвести её в сторонку (можно вместе с девочками) и там решить. Но только не надо обобщать подход к решению подобных задач на всё бизнес приложение в целом (если оно, конечно, не состоит из одной такой задачки).

V>В моей системе сервер приложений разруливал подобную ситуацию. Т.е. используя statefull модель накладных, он позволял оперировать не только остатками товаров на складах по результатам транзакций, но и мгновенными остатками, с учетом текущих редактируемых данных коллеги за соседним столом.


Думаю, что можно было бы отделаться только кешированием твоих мгновенных остатков. Делать для этого statefull модель накладных скорее всего совсем не обязательно.

V>Подобная задача может быть решена и через stateless, но весьма ненадежно.


Не верю По большому счёту stateful от stateless отличается только лишь тем, что state в stateless всегда гарантированно ложится в базу данных, а в statefull не всегда, иногда только в память апп-сервера. Остальное — это приёмы использования кеша и борьбы с ним.

V>(Именно таким был первый вариант решения задачи). Т.е. суть решения состояла в организации доп. состояния документа — черновик, и каждая строчка накладной отправлялась на сервак. Был общий регистр "набиваемых" данных. Вроде все работало, до тех пор, пока девочки корректно выходили из клиентских программ. Если же из программы вышли неккоректно в момент набивки накладных, то вся логика просто слетала. Приходилось наверчивать доп. операции, типа — сброс регистров набиваемых данных, эту операцию нужно было выполнять в тот момент, когда никто не редактировал накладные... И вся эта пляска вокруг однойтолько бизнес-задачи. В общем, наглядная демонстрация процедуры удаления гланд при неправильной начальной предпосылке расположения оных.


И как ты удаляешь эти гланды теперь?

V>Статефулл решил все проблемы сразу, просто и элегантно.


Неужели stateful штрафует девочек за некорректный выход из программы?

V>Правильная тема для обсуждения. Свой енжин пишу как раз и для подобных задач. Дело в том, что мы, разработчики, обычно точно знаем характер взаимодействия со своими данными, а сервак SQL — нет. Справочники я обычно смело кеширую на апп-серваке, и уверяю, эти join-ы работают гораздо быстрее, чем на стороне SQL. Если решать задачу не каждый раз заново, а именно решить единожды — то все получается ok.


Советую пользоваться индекстами
Впрочем, для монстрообразных справочников кеширование здорово помогает. Но, как я уже сказал выше, это с успехом и с теми же проблемами делается как в stateless, так и в stateful. Разницы никакой.

V>Кеширование бывает не только на апп-серваке, но и на клиенте. В статефул-модели мы можем поручить нашему движку самому разбираться, какие данные надо подгрузить на клиента, а какие не надо. То же самое при отправке их обратно на сервак. В случае медленного коннекта клиента — это сильное подспорье. Даже в случае быстрого, но тарифицируемого за каждый MB трафика — тоже.


Могу ещё раз сказать про кешь — в обоих подходах с ним работа практически идентична. За исключением, пожалуй, одной вещи. В stateful кешь легко превращается в storage объектов в памяти, что при всей своей привлекательности несёт в себе массу других проблем.

IT>>Не так. Ты путаешь понятия cache и storage. Да, они оба как бы типа хранят состояние. Но наличие данных в первом совсем не обязательно и предназначено только для одной функции — снятие нагрузки с базы данных постредством реиспользования ранее произведённых запросов. Для второго — наличие данных это часть логики. Например, через кэш можно получить два разных экземпляра одной и той же записи БД. Для stateless в этом нет ничего страшного. Но, если твоё хранилище в stateful вернёт два экземпляра одного и того же объкта, то это уже не stateful, а либо глючный stateful, либо stateless


Ну да, видишь, я об этом ещё два года назад говорил

V>Правильное замечание. Для этих целей у нас отделены Entity от EntityView. Entity может быть только в 1-м экземпляре в кеше или не быть вовсе. Экземпляров EntityView может быть много. Всю потоко- и транзакционную безопасность они разруливают м/у собой сами.


Ok. Пример из жизни. Загружаешь ты, например, накладную. Вместе с ней поднимается и товары. Товаров в базе данных мильёны. Грузить их все в кешь не имеет смысла. А может и имеет для каких-то случаев В любом случае какие-то товары у тебя уже в памяти. Теперь в другой части приложения ты делаешь запрос по какому то критерию для получения списка товаров. В качестве результата приезжает список как закешированных, так и не закешированных товаров. Что ты делаешь в этом случае? Мне правда интересно. Я занималься в своё время такой фигнёй, задача решаемая, но как-то глядя на это всё плакать хочется.

IT>>Слова мужа Вопрос только в том, какую модель брать в качестве базовой, от чего отталкиваться.


V>Конечно StateFull. Ибо любой statefull легко приводим к stateless.


Ты это серьёзно? Может мы используем разные термины? Ты под stateful понимаешь то, что я под statless, а я под stateful, то что ты под stateless? Вот простой вопрос. Как ты превратишь stateful решение в масштабируемое?

V> У нас в системе есть несколько сущностей, которые ведут себя как stateless, потому как на каждый чих скидывают свое сосстояние в БД (и в кеш соответственно). Владение разными экземплярами EntityView одним экземпляром Entity автоматичеки синхронизирует изменения в соседних клиентских сессиях.


Какой же это stateless? Типичный stateful, только с гарантированным сохранением данных в БД.

IT>>>>То ли в память, то ли в процессор. И не надо говорить что сейчас памяти навалом. Возьмём хотя бы наш сайт, у нас данных в базе на гиг, но если это всё положить в память, в виде найс объектной модели, то сервер сразу ляжет, т.к. под это понадобится в разы больше памяти чем используется БД.


V>Всю модель никто и не ложит в память. Обычно настраивают политику использования кеша для каждой сущности. Для справочных данных — это было бы оправданно почти всегда, для остальных — в зависимости от задачи.


Для остальных вообще как правило ничего не имеет смысла кешировать.

IT>>Более того, оказывается в GUI очень неплохо смотрятся несложные веб-формы


V>Скажем прямо — когда как. Стоит захотеть положить на форму полнофункциональный грид — и сразу прощай веб-форма в ГУИ. Да и вообще, при интенсивном взаимодействии на клиенте с этим ГУИ неудобно работать с embedded web-form, гораздо проще оперировать обычным Windows.Forms.


Разве? А где ты видел нормальный грид для гуёв? Веб-грид хоть и простенький, но с ним можно практически всё делать. А что нельзя, можно на таблицах. Думаю, кода будет не больше, чем при кастомизации гуёвого грида.

V>Хотя, в своем редакторе запросов взяли именно WebForm, и прилично натрахались со сложным взаимодействием с ней... И все только из-за мощных ср-в управления layout-ом.


Вы наверное стремились всё сделать pixel-perfect?

IT>>>>Масштабируемость в стэйтфул — это вообще занятие для мазахистов. Сложность приложения из-за синхронизации увеличивается в разы.


V>В разы обычно уменьшается и трафик и время отклика. При централизованном подходе к синхронизации, и применении кеша не только на стороне апп-сервера, но и при агрессивном кешировании на клиенте — все начинает работать гораздо быстрее.


Подожди-ка, мы не о кеше опять, а о синхронизации состояний одного и того же объекта на разных серверах.

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


V>Обычно нужно разработать небольшое семейство политик кеширования и политик синхронизации, а конкретным прикладным сущностям просто прописывать эти политики. Подобная гибкость и не снилась серверам SQL. Например, после годовой работы с приложением можно скорректировать политику сущностей исходя из реальных объемов и соотношений данных.


Ну ты понял... про кеширование

IT>>Вопрос не в конкретном приложении. Вопрос в том какая архитектура позволит это приложение расширять с минимальными усилиями.


V>Все ясно. Вопрос вообще о подходе к написанию многозвенных приложений. С тем, что statefull изначально проще в реализации простых операций, типа: прочитать, изменить, записать, никто и не спорил. Однако очевидно, что с помощью statefull становится сложновато строить приложения, где необходима мгновенная реакция на изменения в системе, вызванные "соседним" пользователем. Применяя stateless вообще сложновато координировать м/у собой действия различных пользователей в системе, если таковая задача вдруг встанет. И этот принцип я бы не стал делить по применимости на Web- или GUI-приложения. On-line GUI клиента к RSDN я бы тоже выполнил в виде stateless модели. Однако WEB-формы выписки накладных из приведенного выше примера — однозначено statefull.


Я уже сказал, что такой класс задач гораздо реже встречается в природе чем "простые операции типа: прочитать, изменить, записать". Да и такие задачи можно и нужно раскладывать на простые операции и в результате там от stateful останется один простой список текущих остатков. Ты же, похоже, создав целый фреймворк для твоей задачи, пытаешься не только обобщить это всё на весь stateful, но и убедить всех, что это единственно правильное решение. Это не так. Уверен, что твою задачу можно было бы спокойно решить малой кровью без строительства завода для производства одного гвоздя.
... << RSDN@Home 1.2.0 alpha rev. 0>>
Если нам не помогут, то мы тоже никого не пощадим.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.