Сервис индекса на основе WebService .NET
От: Serpenter_i  
Дата: 05.05.09 09:32
Оценка: :)
Здравствуйте,

хочу создать сервис на основе .NET WebService для разгрузки базы данных. Сервис будет при инициализации кешировать все нужные таблицы, затем где нибудь раз в секунду обновлять свой кеш новыми записями. Это позволит при обращении к сервису получать информацию и делать сложные вычисления, не нагружая БД, а считая по кешу в оперативке. Очень хочется использовать .net веб-сервисы, потому что привык и чувствую себя удобно при разработке. Хочется получить масштабируемость не сменой технологий (переход на unix системы, c++, итп) а простым размножением количества компьютеров.

Прокомментируйте пожалуйста такой подход, какие будут подводные камни. Я вижу только минус что WebService хостит IIS, который управляет пулом потоков неизвестным мне способом.

Наполнение кеша пока думаю делать так: в Application_Start создавать один поток, который будет отвечать за наполнение кеша, он будет жить очень долго и раз в секунду выполнять работу. Возникает вопрос — создавать поток самому (через System.Threading.ThreadStart) или через пул потоков ASP.NET (System.Threading.ThreadPool.QueueUserWorkItem). Прокомментируйте пожалуйста оба варианта, какие плюсы и минусы.
Re: Сервис индекса на основе WebService .NET
От: s_viy  
Дата: 05.05.09 11:39
Оценка:
Здравствуйте, Serpenter_i, Вы писали:

S_>Здравствуйте,


S_>хочу создать сервис на основе .NET WebService для разгрузки базы данных. Сервис будет при инициализации кешировать все нужные таблицы, затем где нибудь раз в секунду обновлять свой кеш новыми записями. Это позволит при обращении к сервису получать информацию и делать сложные вычисления, не нагружая БД, а считая по кешу в оперативке. Очень хочется использовать .net веб-сервисы, потому что привык и чувствую себя удобно при разработке. Хочется получить масштабируемость не сменой технологий (переход на unix системы, c++, итп) а простым размножением количества компьютеров.


В свое время достаточно много сделал подобных сервисов, но как раз на с++ и linux. Преимущество такого подхода в том, что такие сервисы очень и очень быстры (при грамотной реализации конечно) — одного хоста бывает достаточно чтобы обслуживать многие тысячи запросов в секунду — этого вполне хватит чтобы обслуживать несколько тысяч пользователей одновременно. НО, если производительности всегда хватало с лихвой, то с объемом оперативной памяти могут возникнуть сложности. Проблемы с производительностью решаются просто — путем распределения нагрузки по нескольким хостам, при условии что они имеют одинаковые кэши, но этого этого как правило не требуется. Если данных очень много (нельзя их загрузить все в кэш), то распределять нужно данные, а это гораздо сложнее — придется делать мини-поисковую систему (куча хостов с загруженными в оперативку частью данных, сервис обслуживающий пользователей, отправляющий запросы Index-сервисам и формирующий результат ну и пр.)

S_>Прокомментируйте пожалуйста такой подход, какие будут подводные камни. Я вижу только минус что WebService хостит IIS, который управляет пулом потоков неизвестным мне способом.


С начала необходимо оценить объем индексируемых данных — хватит ли оперативки для кэша и индексации. Если нет, то простым размножением количества компьютеров не отделаешься — лучше не ввязываться. И обязательно постоянно проводи нагрузочные тесты, с самого начала разработки. Но наверняка 90% времени и более будет занимать разбор и формирование сообщений. Рассмотри варианты REST и JSON — они гораздо легче и быстрее SOAP.

S_>Наполнение кеша пока думаю делать так: в Application_Start создавать один поток, который будет отвечать за наполнение кеша, он будет жить очень долго и раз в секунду выполнять работу. Возникает вопрос — создавать поток самому (через System.Threading.ThreadStart) или через пул потоков ASP.NET (System.Threading.ThreadPool.QueueUserWorkItem). Прокомментируйте пожалуйста оба варианта, какие плюсы и минусы.


Сделай лучше windows-сервис который читает данные из БД и отправляет данные на сервис для кэширования, а в своем сервисе сделай интерфейс для заполнения кэша. Чтобы каждый раз не загружать все данные можно использовать ChangeLog — специальная таблицы, в которую скидываются ID изменившихся записей. Если нужна максимальная оперативность, то приложение которое вносит изменения в БД одновременно отправляет их на индексацию на сервис, и только если сервис недоступен скидывает ID в ChangeLog
Re: Сервис индекса на основе WebService .NET
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.05.09 13:39
Оценка: +1
Здравствуйте, Serpenter_i, Вы писали:

S_>Здравствуйте,


S_>хочу создать сервис на основе .NET WebService для разгрузки базы данных. Сервис будет при инициализации кешировать все нужные таблицы, затем где нибудь раз в секунду обновлять свой кеш новыми записями. Это позволит при обращении к сервису получать информацию и делать сложные вычисления, не нагружая БД, а считая по кешу в оперативке. Очень хочется использовать .net веб-сервисы, потому что привык и чувствую себя удобно при разработке. Хочется получить масштабируемость не сменой технологий (переход на unix системы, c++, итп) а простым размножением количества компьютеров.


Моя плакать. Думаете до этого разработчики БД не додумались?
Сама СУБД отлично кеширует данные в памяти и может туда затянуть всю базу если объемов оперативки хватит. Кроме того СУБД поддерживает SQL, индексы, распараллеливание вычислений.

S_>Прокомментируйте пожалуйста такой подход, какие будут подводные камни. Я вижу только минус что WebService хостит IIS, который управляет пулом потоков неизвестным мне способом.

Вижу дофига минусов, начиная от необоснованности лишнего звена, до тормознутости и остуствия гибкости.
Кстати работа пула IIS отлично описана в MSDN.

S_>Наполнение кеша пока думаю делать так: в Application_Start создавать один поток, который будет отвечать за наполнение кеша, он будет жить очень долго и раз в секунду выполнять работу. Возникает вопрос — создавать поток самому (через System.Threading.ThreadStart) или через пул потоков ASP.NET (System.Threading.ThreadPool.QueueUserWorkItem). Прокомментируйте пожалуйста оба варианта, какие плюсы и минусы.

Варианты с потоками при любом раскладе бредовые. Время жизни app pool при отсутсвии запросов заканчивается очень быстро (20 минут), в реальном окружении еще могут стоять квоты на использование памяти, которые будут глушить app pool еще чаще.

Если вам нужна скорость, то лучше оптимизируйте свое приложение. Напишите правильные запросы, сделаейте разумные проекции. Оптимизируйте схему БД, создайте индексы, индексированные вьюхи.

Потом пожно заниматься разумной денормализацией данных, поддерживать денормальзованные данные в согласованном состоянии можно с помощью триггеров.

Если нужно совмещать OLTP (частые простые выборки и частые изменения) и OLAP (тяжкие аналитические запросы), то стоит задуматься об использовании служб бизнес-аналитики (SSAS) и использовать службы интеграции (SSIS) для перемещения данных.

Это все должно сопровождаться кешированием данных в приложении.

Если нужно периодически выполнять какой-то код, то можно задействовать шедулер ОС, SQL Server Agent или написать службу.

Реально нужен middleware когда нужно работать с распределенными БД, но изобретать его не нужно. Зачастую можно обойтись существующими библиотеками.
Re[2]: Сервис индекса на основе WebService .NET
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 05.05.09 13:41
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Реально нужен middleware когда нужно работать с распределенными БД, но изобретать его не нужно. Зачастую можно обойтись существующими библиотеками.


Если нужно кеширование больших объемов, то можно воспользоваться Velocity
Re[2]: Сервис индекса на основе WebService .NET
От: Serpenter_i  
Дата: 06.05.09 05:36
Оценка:
Здравствуйте, s_viy, Вы писали:

_>В свое время достаточно много сделал подобных сервисов, но как раз на с++ и linux. Преимущество такого подхода в том, что такие сервисы очень и очень быстры (при грамотной реализации конечно) — одного хоста бывает достаточно чтобы обслуживать многие тысячи запросов в секунду — этого вполне хватит чтобы обслуживать несколько тысяч пользователей одновременно. НО, если производительности всегда хватало с лихвой, то с объемом оперативной памяти могут возникнуть сложности. Проблемы с производительностью решаются просто — путем распределения нагрузки по нескольким хостам, при условии что они имеют одинаковые кэши, но этого этого как правило не требуется. Если данных очень много (нельзя их загрузить все в кэш), то распределять нужно данные, а это гораздо сложнее — придется делать мини-поисковую систему (куча хостов с загруженными в оперативку частью данных, сервис обслуживающий пользователей, отправляющий запросы Index-сервисам и формирующий результат ну и пр.)


_>С начала необходимо оценить объем индексируемых данных — хватит ли оперативки для кэша и индексации. Если нет, то простым размножением количества компьютеров не отделаешься — лучше не ввязываться. И обязательно постоянно проводи нагрузочные тесты, с самого начала разработки. Но наверняка 90% времени и более будет занимать разбор и формирование сообщений. Рассмотри варианты REST и JSON — они гораздо легче и быстрее SOAP.


В рамках текущей задачи данные влазят, если потом разрастется буду думать. Про REST и JSON мысли есть, но пока нет сервиса нечего нагруженно тестировать. Т.к. веб-сервисы писать довольно просто, то перевести их на rest/json будет тоже просто.

_>Сделай лучше windows-сервис который читает данные из БД и отправляет данные на сервис для кэширования, а в своем сервисе сделай интерфейс для заполнения кэша. Чтобы каждый раз не загружать все данные можно использовать ChangeLog — специальная таблицы, в которую скидываются ID изменившихся записей. Если нужна максимальная оперативность, то приложение которое вносит изменения в БД одновременно отправляет их на индексацию на сервис, и только если сервис недоступен скидывает ID в ChangeLog


Правильно ли я понял, вы предлагает сделать 3 сервиса для обслуживания одного индекса — кеш, сервис наполнения кеша, собственно сервис индекса? Совсем не понял фразу — "в своем сервисе сделай интерфейс для заполнения кеша".

Вопрос с ChangeLog интересный. Т.е. вы предлагаете создать еще один сервис для ведения истории записей? При записи в БД нужно ли дожидаться успешной записи в ChangeLog? Если нет, то непонятно как мы гарантируем что в индексах рано или поздно появится актуальная информация. Если да, то возникает вопрос, в чем отличие ChangeLog от БД? Если в БД отказаться от update и delete, и реализовать их за счет версионности, то БД превратится в ChangeLog, потому что индексы смогут успешно обновлять себя из БД, и ChangeLog становится ненужным. Если я правильно помню, что-то типа ChangeLog есть у фейсбука, но им ненужна гарантия что индекс рано или поздно обновится до актуальной информации. Даже наоборот, например, когда они показывают новости то показывают лишь небольшой процент случайно выбранных новостей, про остальное забывают, потому что иначе поток новостей слишком большой.
Re[2]: Сервис индекса на основе WebService .NET
От: Serpenter_i  
Дата: 06.05.09 05:40
Оценка:
Здравствуйте, gandjustas, Вы писали:

G>Моя плакать. Думаете до этого разработчики БД не додумались?


Посмотрите в сторону CAP Theorem
Re[3]: Сервис индекса на основе WebService .NET
От: gandjustas Россия http://blog.gandjustas.ru/
Дата: 06.05.09 05:56
Оценка:
Здравствуйте, Serpenter_i, Вы писали:

S_>Здравствуйте, gandjustas, Вы писали:


G>>Моя плакать. Думаете до этого разработчики БД не додумались?


S_>Посмотрите в сторону CAP Theorem


Я же написал что middleware нужно в случае распределенной БД.
Если хочется просто "снизить нагрузку" на БД, то созданием middleware это решается только отчасти. И обычно ценой быстродействия приложения.
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.