Re[10]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 20.08.07 16:08
Оценка:
Здравствуйте, TK, Вы писали:

TK>Тут можно определиться с тем, насколько критичными являются кешированные данные. В каких-то случаях, может оказаться достаточным просто сбросить закешированное значение при его изменении. для каких-то, можно завести специальную табличку в FB для отслеживания блокировок...



Мда, про то, что можно просто сбросить кэш я банально не подумал.
Получается что-то типа строк в CLR — один раз получил и они всегда константные. А при изменении создается новый объект, который ложится в кэш.
Процедура обновления будет выглядеть примерно так:
class Updater { // класс, которому зачем-то надо поменять данные
...
    public void ChangeData(int ID) {
        IFirstBE old = firstBE_DAC.Get(ID);
        IFirstBE editing = old.Clone();
        // some operations with editing
        ...
        bool success = firstBE_DAC.Update(editing, old);
    }
}

class FirstBE_DAC {
...
    public IFirstBE Get(int ID) {
        if (_cache.ContainsKey(ID))
            return _cache[ID];
        IFirstBE entity = GetFromDb(ID);
        _cache.Add(ID, entity);
        return entity;
    }

    public bool Update(IFirstBE edited, IFirstBE old) {
        current = Get(edited.ID);
        if (match(current, old) { 
            _cache[edited.ID] = edited;
            UpdateToDB(edited);
            return true;
        }
        else
        {
            //    optimistic concurrency failed
            return false;
        }
    }
 }

Правда, на класс кэша и бизнес-объектов тоже придется навесить SynchronizationAttribute, чтобы при добавлении/изменении и клонировании не попортились.

Так можно, или я все криво сделал?
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[10]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 20.08.07 16:13
Оценка:
Здравствуйте, AndrewVK, Вы писали:

AVK>А никак, пускай FB кеширует.


Хм. А не слишком ли велики затраты на выполнение по 15 раз одних и тех же запросов? Само время выполнения запроса будет небольшим. Но пока запрос достучится до СУБД, пока вернется ответ... А если все это на разных машинах — то еще плюс латентность сети.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 20.08.07 16:16
Оценка:
Только клонирование перенести в обязанности кэша. Чтобы выдавал не свой объект, а копию. И проблем меньше, и BE синхронизировать не надо будет — все равно у всех разные.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Multithreading в Application server layer
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.08.07 16:28
Оценка:
Здравствуйте, Ivan Danilov, Вы писали:

ID>Хм. А не слишком ли велики затраты на выполнение по 15 раз одних и тех же запросов?


А это смотря что для тебя важнее — минимально возможное время отклика системы при низкой загрузке или максимально возможная загрузка при лимите на стоимость железа.
... << RSDN@Home 1.2.0 alpha rev. 716>>
AVK Blog
Re[12]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 20.08.07 16:37
Оценка:
Здравствуйте, AndrewVK, Вы писали:

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


Минимальное время отклика при низкой нагрузке. Больше 100 пользователей пока что нету даже в перспективе, да и больших объемов данных нету. А вот разнесение по разным серверам вполне возможно, в целях безопасности (от меня это никак не зависит).

Думал даже при загрузке сервера считывать ВСЮ базу в память (по запросу на каждую таблицу), т.е. использовать БД исключительно для долговременного хранения, а всю текущую информацию держать в памяти.

Размер базы пока весьма скромный и не превышает 50 Мб, так что перегрузок сети быть не должно.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[13]: Multithreading в Application server layer
От: AndrewVK Россия http://blogs.rsdn.org/avk
Дата: 20.08.07 16:50
Оценка:
Здравствуйте, Ivan Danilov, Вы писали:

ID>Минимальное время отклика при низкой нагрузке.


Ну тогда имеет смысл делать кеши в памяти.

ID>А вот разнесение по разным серверам вполне возможно, в целях безопасности (от меня это никак не зависит).


Разнесение чего по серверам? СУБД и апп-сервера? Все равно в таком случае как правило канал до БД толстый и в эксклюзивном пользовании, в отличие от канала до клиентов. Опять же, у тебя БД маленькая, значит и время проталкивания по сети невысоко. Значит имеет смысл учитывать только латентность. У тебя латентность канала до БД сопоставима со временем отклика апп-сервера на запрос клиента?

ID>Думал даже при загрузке сервера считывать ВСЮ базу в память (по запросу на каждую таблицу), т.е. использовать БД исключительно для долговременного хранения, а всю текущую информацию держать в памяти.


Совсем не факт что это приведет к сильному росту производительности. Хотя, кто его знает в случае FB.
И, в любом случае, для начала нужно сделать прототип с простейшими алгоритмами, а потом уже, если производительность не удовлетворяет, подкручивать где надо. Иначе есть риск проделать всю работу в холостую.
... << RSDN@Home 1.2.0 alpha rev. 716>>
AVK Blog
Re[14]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 20.08.07 17:03
Оценка:
Здравствуйте, AndrewVK, Вы писали:

ID>>Минимальное время отклика при низкой нагрузке.

AVK>Ну тогда имеет смысл делать кеши в памяти.
Что я и делаю

ID>>А вот разнесение по разным серверам вполне возможно, в целях безопасности (от меня это никак не зависит).

AVK>Разнесение чего по серверам? СУБД и апп-сервера? Все равно в таком случае как правило канал до БД толстый и в эксклюзивном пользовании, в отличие от канала до клиентов. Опять же, у тебя БД маленькая, значит и время проталкивания по сети невысоко. Значит имеет смысл учитывать только латентность. У тебя латентность канала до БД сопоставима со временем отклика апп-сервера на запрос клиента?
Сопоставима. Там везде каналы толстые, т.е. локалка, поделенная на 2 домена.

ID>>Думал даже при загрузке сервера считывать ВСЮ базу в память (по запросу на каждую таблицу), т.е. использовать БД исключительно для долговременного хранения, а всю текущую информацию держать в памяти.

AVK>Совсем не факт что это приведет к сильному росту производительности. Хотя, кто его знает в случае FB.
Хм. Как Вы написали чуть выше, имеет смысл учитывать только латентность. Она таким образом сокращается ровно вдвое — на запрос к СУБД (если посчитать каналы к серверу и клиенту одинаковыми).
А если еще учесть специфику данных — иерархическое дерево в БД, что влечет за собой большое количество запросов для обхода — выигрыш может быть даже и больше. Ведь так я все дерево сразу собираю на апп-сервере, а так его по частям придется выдирать из СУБД (например, если нужен отчет по ветке со всеми детьми).

AVK>И, в любом случае, для начала нужно сделать прототип с простейшими алгоритмами, а потом уже, если производительность не удовлетворяет, подкручивать где надо. Иначе есть риск проделать всю работу в холостую.

Делал. Загрузка всей базы и распихивание по business entities занимает около минуты, может быть чуть-чуть больше.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[12]: Multithreading в Application server layer
От: TK Лес кывт.рф
Дата: 20.08.07 17:53
Оценка:
Здравствуйте, Ivan Danilov, Вы писали:

ID>Только клонирование перенести в обязанности кэша. Чтобы выдавал не свой объект, а копию. И проблем меньше, и BE синхронизировать не надо будет — все равно у всех разные.


SynchronizationAttribute — их есть два. Один для COM+ другой, для ContextBoundObject. думаю, что ни тот ни другой тут не подойдут.
Что касается кеширования то, тут можно рассмотреть две альтернативы — кешировать объекты или кешировать "сырые" данные. Например, NHibernate занимается кешированием "сырых" данных. Вообще, если проект у вас относительно простой, можно рассмотреть использование того-же NHibernate/ActiveRecord это вполне может решить задачи кеширования/доступа к данным при минимальном риске от использования новой технологии
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[13]: Multithreading в Application server layer
От: TK Лес кывт.рф
Дата: 20.08.07 18:03
Оценка:
Здравствуйте, Ivan Danilov, Вы писали:

ID>Думал даже при загрузке сервера считывать ВСЮ базу в память (по запросу на каждую таблицу), т.е. использовать БД исключительно для долговременного хранения, а всю текущую информацию держать в памяти.


Не думаю, что считывать в память всю базу данных это будет хорошей идеей (лично я видел много отрицательных примеров когда, приложение становилось от этого слишком ресурсоемким и не поворотливым). Альтернативрой считывания всех данных в память может быть использование локальной БД содержимое которой, синхронизируется с "внешней" (Многие статьи с ключевым словом SmartClient рассказывают о подобном подходе). Локальная БД (тот-же встраиваемый firebird или SqlServer) будет крутиться в процессе сервера что даст высокую производительность (т.к все операции в рамках одного процесса) и эффективное использование ресурсов (хранение данных на локальном диске и т.п)

ID>Размер базы пока весьма скромный и не превышает 50 Мб, так что перегрузок сети быть не должно.


И бы рассмотрел "худший" сценарий. 50Мб надо будет скачать, сохранить в локальной памяти, плюс, орагнизовать к ним доступ и т.п. Все это может привести к достаточно ощутимой нагрузке.
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[14]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 20.08.07 18:11
Оценка:
Здравствуйте, TK, Вы писали:

<skipped>

В плане загрузки всей базы — убрать один оператор LoadAll() для каждого маппера — не проблема. Это я буду уже под реальной нагрузкой смотреть — стоит там что-то прикручивать или пусть так работает
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[13]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 20.08.07 18:15
Оценка:
Здравствуйте, TK, Вы писали:

TK>Здравствуйте, Ivan Danilov, Вы писали:


ID>>Только клонирование перенести в обязанности кэша. Чтобы выдавал не свой объект, а копию. И проблем меньше, и BE синхронизировать не надо будет — все равно у всех разные.


TK>SynchronizationAttribute — их есть два. Один для COM+ другой, для ContextBoundObject. думаю, что ни тот ни другой тут не подойдут.

TK>Что касается кеширования то, тут можно рассмотреть две альтернативы — кешировать объекты или кешировать "сырые" данные. Например, NHibernate занимается кешированием "сырых" данных. Вообще, если проект у вас относительно простой, можно рассмотреть использование того-же NHibernate/ActiveRecord это вполне может решить задачи кеширования/доступа к данным при минимальном риске от использования новой технологии

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

Насчет NHibernate — я с ним не очень знаком, так что пока оставлю свое кэширование (все-таки уже написано, отлажено и протестировано), а если будет время/необходимость — вернусь к этому вопросу.

Фактически, я создал тему потому что боялся расползания локов по всему тексту — и идею, как этого избежать — уже получил, спасибо
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[11]: Multithreading в Application server layer
От: IB Австрия http://rsdn.ru
Дата: 20.08.07 21:20
Оценка:
Здравствуйте, Ivan Danilov, Вы писали:

ID> Но пока запрос достучится до СУБД, пока вернется ответ... А если все это на разных машинах — то еще плюс латентность сети.

Что такое Connection Pooling знаешь? "достучиться" в данном случае не правильный термин, правильный — "передастся". А это существенно меньше времени и латентность уже такой роли не играет.
Ну и второе — с кешем я бы по прежнему рекомендовал бы связываться только в том случае, когда станет ясно, что БД не справляется. При размере БД в 50 Мб, любая вменяемая СУБД ее все равно сама в память поднимет, так что возня с кешем в этом месте заметного эффекта не окажет.
Мы уже победили, просто это еще не так заметно...
Re[12]: Multithreading в Application server layer
От: Cyberax Марс  
Дата: 21.08.07 00:32
Оценка: +2
IB wrote:
> При размере БД в 50 Мб, любая вменяемая СУБД ее все равно сама в память
> поднимет, так что возня с кешем в этом месте заметного эффекта не окажет.
Смотри что за приложение. Скорость извлечения данных из локального кэша
обычно в тысячи раз быстрее даже простого обращения к БД.

Если у нас есть много мелких запросов — выигрыш может быть весьма
значителен.
Posted via RSDN NNTP Server 2.1 beta
Sapienti sat!
Re[12]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 21.08.07 06:04
Оценка:
Здравствуйте, IB, Вы писали:

IB>Здравствуйте, Ivan Danilov, Вы писали:


ID>> Но пока запрос достучится до СУБД, пока вернется ответ... А если все это на разных машинах — то еще плюс латентность сети.

IB>Что такое Connection Pooling знаешь? "достучиться" в данном случае не правильный термин, правильный — "передастся". А это существенно меньше времени и латентность уже такой роли не играет.
Чтобы что-то передавать — сначала надо достучаться
Я не имел в виду открыть новый Connection, я имел в виду именно задержки при передаче запроса/ответа. И, кроме латентности,

IB>Ну и второе — с кешем я бы по прежнему рекомендовал бы связываться только в том случае, когда станет ясно, что БД не справляется. При размере БД в 50 Мб, любая вменяемая СУБД ее все равно сама в память поднимет, так что возня с кешем в этом месте заметного эффекта не окажет.

А какая разница, куда поднимет ее сама СУБД? О_о Предположим, что время обработки любого запроса СУБД — 0. То есть на время отклика влияет только сеть. Представь, что клиент хочет отчет, для формирования которого надо очень много небольших запросов (сейчас — вполне реальная ситуация). Если считать, что каналы клиент-апп.сервер и апп.сервер-субд.сервер одинаковые и пренебречь временем извлечения данных из кэша — производительность возрастет ровно вдвое.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[15]: Multithreading в Application server layer
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.08.07 07:11
Оценка: +1
Здравствуйте, Ivan Danilov, Вы писали:

ID>Что я и делаю

Неправильно делаете.

ID>>>Думал даже при загрузке сервера считывать ВСЮ базу в память (по запросу на каждую таблицу), т.е. использовать БД исключительно для долговременного хранения, а всю текущую информацию держать в памяти.

AVK>>Совсем не факт что это приведет к сильному росту производительности. Хотя, кто его знает в случае FB.
ID>Хм. Как Вы написали чуть выше, имеет смысл учитывать только латентность. Она таким образом сокращается ровно вдвое — на запрос к СУБД (если посчитать каналы к серверу и клиенту одинаковыми).
ID>А если еще учесть специфику данных — иерархическое дерево в БД, что влечет за собой большое количество запросов для обхода — выигрыш может быть даже и больше. Ведь так я все дерево сразу собираю на апп-сервере, а так его по частям придется выдирать из СУБД (например, если нужен отчет по ветке со всеми детьми).
Не надо так делать. Читайте классику. Хранимая процедура обхода дерева пишется на FB на раз-два. Прочитайте для начала статьи на RSDN, посвяшенные хранению иерархических структур.

AVK>>И, в любом случае, для начала нужно сделать прототип с простейшими алгоритмами, а потом уже, если производительность не удовлетворяет, подкручивать где надо. Иначе есть риск проделать всю работу в холостую.

ID>Делал. Загрузка всей базы и распихивание по business entities занимает около минуты, может быть чуть-чуть больше.
Разработчики RDBMS уже вложили сотни человеко-лет в отладку ACID. Что, есть острое желание повторить всё то же самое? Если грамотно пользоваться сервисами CУБД, то всё получится само — и производительность, и масштабируемость, и параллелизм.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[13]: Multithreading в Application server layer
От: Sinclair Россия https://github.com/evilguest/
Дата: 21.08.07 07:11
Оценка: +2
Здравствуйте, Ivan Danilov, Вы писали:

IB>>Ну и второе — с кешем я бы по прежнему рекомендовал бы связываться только в том случае, когда станет ясно, что БД не справляется. При размере БД в 50 Мб, любая вменяемая СУБД ее все равно сама в память поднимет, так что возня с кешем в этом месте заметного эффекта не окажет.

ID>А какая разница, куда поднимет ее сама СУБД? О_о Предположим, что время обработки любого запроса СУБД — 0. То есть на время отклика влияет только сеть. Представь, что клиент хочет отчет, для формирования которого надо очень много небольших запросов (сейчас — вполне реальная ситуация). Если считать, что каналы клиент-апп.сервер и апп.сервер-субд.сервер одинаковые и пренебречь временем извлечения данных из кэша — производительность возрастет ровно вдвое.
А если переписать отчет так, чтобы выполнялся один большой запрос вместо "очень много небольших", то производительность возрастет до оторопи.
... << RSDN@Home 1.2.0 alpha rev. 677>>
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[14]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 21.08.07 07:18
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А если переписать отчет так, чтобы выполнялся один большой запрос вместо "очень много небольших", то производительность возрастет до оторопи.


А хранить нужные данные в памяти даст не тот же самый результат? За тем исключением, что так они уже разобраны и готовы, а результаты запроса еще нужно обработать перед передачей на клиента.
... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
Re[14]: Multithreading в Application server layer
От: TK Лес кывт.рф
Дата: 21.08.07 07:25
Оценка: +1
Здравствуйте, Sinclair, Вы писали:

ID>>А какая разница, куда поднимет ее сама СУБД? О_о Предположим, что время обработки любого запроса СУБД — 0. То есть на время отклика влияет только сеть. Представь, что клиент хочет отчет, для формирования которого надо очень много небольших запросов (сейчас — вполне реальная ситуация). Если считать, что каналы клиент-апп.сервер и апп.сервер-субд.сервер одинаковые и пренебречь временем извлечения данных из кэша — производительность возрастет ровно вдвое.

S>А если переписать отчет так, чтобы выполнялся один большой запрос вместо "очень много небольших", то производительность возрастет до оторопи.

Только, вот сопровождаемость этого дела (если запихнуть всю логику в БД) может упасть точно так же...
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[16]: Multithreading в Application server layer
От: Ivan Danilov Украина  
Дата: 21.08.07 07:31
Оценка:
Здравствуйте, Sinclair, Вы писали:

ID>>Хм. Как Вы написали чуть выше, имеет смысл учитывать только латентность. Она таким образом сокращается ровно вдвое — на запрос к СУБД (если посчитать каналы к серверу и клиенту одинаковыми).

ID>>А если еще учесть специфику данных — иерархическое дерево в БД, что влечет за собой большое количество запросов для обхода — выигрыш может быть даже и больше. Ведь так я все дерево сразу собираю на апп-сервере, а так его по частям придется выдирать из СУБД (например, если нужен отчет по ветке со всеми детьми).
S>Не надо так делать. Читайте классику. Хранимая процедура обхода дерева пишется на FB на раз-два. Прочитайте для начала статьи на RSDN, посвяшенные хранению иерархических структур.
Я в курсе пользы хранимых процедур и активно их использую. Статьи читал, и не только их.

AVK>>>И, в любом случае, для начала нужно сделать прототип с простейшими алгоритмами, а потом уже, если производительность не удовлетворяет, подкручивать где надо. Иначе есть риск проделать всю работу в холостую.

ID>>Делал. Загрузка всей базы и распихивание по business entities занимает около минуты, может быть чуть-чуть больше.
S>Разработчики RDBMS уже вложили сотни человеко-лет в отладку ACID. Что, есть острое желание повторить всё то же самое? Если грамотно пользоваться сервисами CУБД, то всё получится само — и производительность, и масштабируемость, и параллелизм.
ACID я использую именно из СУБД
Разворор вроде сейчас идет о кэшировании, а не о поддержке транзакций? В контексте кэша:
  • Атомарность (Atomicity) — не имеет смысла, т.к. при изменениях часть кэша просто сбросится. Никакие Commit/Rollback не требуются.
  • Непротиворечивость (Consistency) — оставляется полностью на откуп бизнес-логике и проверкам на стороне СУБД. Кэш тут вообще не при чем.
  • Изоляция (Isolation) — это и было проблемой. Но если сделать по копии данных для каждого потока — и она отпадает. А оптимистическая блокировка реализуется очевидным образом, — не в нее вложили сотни человеко-лет.
  • Долговечность (Durability) — для кэша не имеет смысла по определению.
    ... << RSDN@Home 1.1.4 stable SR1 rev. 568>>
  • Re[15]: Multithreading в Application server layer
    От: Sinclair Россия https://github.com/evilguest/
    Дата: 21.08.07 07:45
    Оценка: +1
    Здравствуйте, Ivan Danilov, Вы писали:
    ID>А хранить нужные данные в памяти даст не тот же самый результат?
    Нет, не тот же.
    В отличие от данных в памяти, запрос автоматически выполняется с нужным уровнем изоляции и нет нужды вручную обеспечивать ACID.
    ID> За тем исключением, что так они уже разобраны и готовы, а результаты запроса еще нужно обработать перед передачей на клиента.
    Непонятно, что значит "разобраны и готовы". Клиенту вряд ли передают набор бизнес-объектов; скорее речь идет о построении какого-то сериализованного представления — HTML/XML/PDF/XLS. Ну так вот генерация этого представления из удобным образом сформированного датасета ничуть не дороже, чем по бизнес-объектам, лежащим в памяти.
    Если хочется что-то покэшировать, то лучше кэшировать именно отчет. См. напр. серверные генераторы отчетов (Crystal, MS SQL Server Reporting Services и др.).
    Не надо изобретать велосипедов. Кэширование в стейтлесс среде — хорошая и правильная штука; нужно только аккуратно выбрать гранулярность кэша.
    ... << RSDN@Home 1.2.0 alpha rev. 677>>
    Уйдемте отсюда, Румата! У вас слишком богатые погреба.
    Подождите ...
    Wait...
    Пока на собственное сообщение не было ответов, его можно удалить.