вторник, 7 июня 2011 г.

Когда StreamInsight не подходит?

Пытался объяснить друзьям, зачем нужен Microsoft StreamInsight, чем он может быть лучше традиционной базы данных. Но как-то не очень получилось. И вот нашел презентацию, где приведен хороший пример.

Представим, что на парковке находится несколько сотен машин. Требуется посчитать количество красных машин. Как решалась бы эта проблема с помощью реляционной базы данных? Очень просто: надо обойти всю парковку и пересчитать красные машины.

Усложняем задачу: надо посчитать количество красных автомобилей, которые проехали по трассе I-80 и свернули в сторону Сан-Франциско в течение последнего часа. Решение с помощью реляционной базы данных: начиная с определенного момента, полиция тормозит все свернувшие машины и приказывает им ехать на специальную парковку. И так до тех пор, пока не пройдет час. После этого обходим парковку, считаем красные машины. Когда закончили, отпускаем всех с миром.

А вот более эффективное решение, с использованием StreamInsight: стоим с блокнотиком на съезде с трассы. Когда в нужном направлении проезжает красная машина, ставим в блокнотике палочку. По прошествии часа считаем палочки и выдаем общее число.

Можно ещё немного это оптимизировать: считать общее число палочек не только в конце часа, а постоянно, как только у нас появляется свободное время (на горизонте не видно никаких машин). В таком случае по прошествии часа придется суммировать не все сотни палочек, а только несколько десятков промежуточных чисел.


Всё это заманчиво, но обратите внимание: в приведенном примере нужно было посчитать всего лишь один показатель ("число красных машин"). А что, если показателей тысячи или даже десятки тысяч? Постепенно усложним задачу:

  • Наблюдатель считает не просто количество красных машин, а количество машин всех цветов и оттенков (десятки).

  • Подсчет ведется не один час, а один день.

  • Нас также интересует производитель машины ("проехало четыре красных Мерседеса и одна зеленая Тойота").

  • Добавим ещё разбивку по модели, году выпуска, объему двигателя и типу коробки передач ("три красных бензиновых Mazda 3 с автоматом")


Можно фанатазировать дальше, к примеру, добавить штат регистрации машины и пол водителя.

Я сомневаюсь, что StreamInsight будет хорошим инструментом для решения это задачи. Ведь "блокнотик" (оперативную память) придется разделить на тысячи разделов, в каждом из которых придется ставить палочки, а потом ещё их считать. Это не блокнот получится, а, извините, гроссбух, которых придется быстро листать каждый раз, когда мимо проезжает машина...

Ну, это был немного абстрактный пример, а вот более реальная задача, над которой я работаю: анализ логов веб-сервера. Допустим, есть сотни продавцов и десятки тысяч видов товаров. Один и тот же товар почти всегда предлагается разными продавцами. Нужно посчитать CTR для каждого сочетания товара и продавца.

Сейчас это реализовано так: в течение дня мы тупо пишем всю "сырую" статистику в staging database, в конце дня считаем итоговые показатели, потом отработанные данные стираем. К сожалению, это работает медленно, и система сейчас уже на грани своих возможностей. Если раза в полтора-два выростет посещаемость сайта, то она уже не справится.

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

Можно попробовать гибридное решение: с помощью StreamInsight агрегировать данные в течение, скажем десятки минут, и записывать эти "частично агрегированные" данные в базу. И уже там раз в день выполнять финальный подсчет с помощью хранимой процедуры. Но не знаю, стоит ли игра свечь...



P.S. Пример про подсчет машин на парковке, конечно, упрощен. С одной стороны, надо помнить, что в процессе подсчета машины могут приезжать, уезжать или даже просто перемещаться с одного парковочного места на другое. Для этого можно на время подсчета запретить любое движение (полная блокировка таблицы). Или можно сфотографировать всю парковку со спутника и спокойно считать по фотографии (изоляция). Либо наплевать на возможные ошибки и считать традиционным способом (это получится dirty reads).

С другой стороны, подсчет можно ускорить, если заставить все красные машины парковаться только в определенной части парковки (clustered index), заставить их ехать вообще на отдельный этаж (partitioned table), или обязать всех владельцев красных машин сообщать охраннику номер своего места (обычный индекс).

2 комментария:

Dima Pasko комментирует...

Посмотри еще Reactive Extensions (или Rx) они тоже в эту сторону смотрят

Z комментирует...

У меня была похожая задача. Мне нужно было сделать систему мониторинга специфического трафика. Я реализовал её надстройкой к ETL. У меня job отрабатывает по расписанию, но можно было бы приаттачить его к индикатру окончания загрузки (т.е. после того как машина приехала на парковку, проверить не красная ли она). В итоге, каждые 3 минуты я проверяю многомиллионную "парковку" на предмет красных машин с зимней резиной летом.. Отставание от ETL - минута - полторы.

Ratings by outbrain