Какую архитектуру создать для написания сервера статистики на Ruby?
Всем добрый день!
На работе возникла необходимость в тотальном сборе статистики на сайте. Статистика необходима как поведенческая по сайту (кол-во посещенных страниц, нажатые кнопки и т.д.), так и статистика по просмотру видео в нашем flash плейере (длительность просмотра, страница, с которой был сделан просмотр и т.д.).
Поэтому первый вопрос - есть ли для этого готовые решения, которые могут хотя бы частично покрыть данную задачу? Рассматривал по началу вариант использования Google Analytics или Yandex.Метрика, но есть два момента:
1. с помощью них невозможно отследить конкретно какой пользователь выполнил событие (имеется ввиду, кто из зарегистрированных на сайте пользователей)
2. данные оттуда вынимать придется через API в тяжеленных .XML файлах, что может со временем сильно аукнуться даже в случае дублирования данных у них и у нас на серверах.
Прочитал про такой сервис Piwik, но это по сути та же гугл аналитика, но на собственном сервере и на PHP. Или я не прав?
Поэтому, видимо, придется создавать собственный сервис. Отсюда второй вопрос - на чем его делать? В данный момент сайты, на которых данный сервис будет использоваться, написаны на Ruby (RoR, Sinatra). Хотелось бы не распыляться на технологии и статистический сервер/приложение сделать на нем же. Но м.б. лучше сразу посмотреть в сторону Erlang/Closure/Node.js по причине производительности? Потому что для высоких нагрузок видимо придется посмотреть в сторону асинхронной обработки запросов (EventMachine), что м.б. не очень удобно сделать на Ruby, да и вряд ли данное решение будет производительнее других технологий в данном списке.
Причем с выбором базы тоже не все так просто. Я бы даже сказал, что там еще все более запутанно. Очень часто слышал и читал, что NoSQL решения (Redis, MongoDB, CouchDB, Riak, etc.) "лучше" справляются с подобными задачами как в плане хранения данных по статистике (нет табличной структуры), так и в плане производительности (map-reduce, отсутствие join'ов). Но есть сомнения в плане надежности (транзакций то не будет), да и насколько вообще удобно и просто будет использовать Map-Reduce неизвестно, если честно. Все-таки тот же PostgreSQL не стоял на месте последние несколько лет и прекрасно работает с таблицами в много миллионов/десятков миллионов записей.
Буду благодарен за любые советы, опыт создания аналогичных сервисов и ссылки на статьи по теме :)
Мне тут посоветовали Scribe для быстрого сбора событий. Используется facebook'ом, объемы статистики которого малыми не назвать. Scribe может очень быстро принять сообщение, а затем сбрасывать его произвольное время на другой Scribe сервер или в локальный файл. Таким образом отослать событие "ничего" не стоит по времени. События могут быть внутренние (открытие страницы) или принятые от вашего плеера/приложения (play/pause) через (REST) API. Во втором случае лучше не использовать тяжелый стек RoR, а взять что-то крайне легковесное. Ведь там не будет никакой логики, принять данные и сразу в Scribe. Я бы сделал на чистом python/WSGI.
В идеале поставить по scribe процессу на каждый app. сервер, которые будут сливать события на единый выделенный scribe сервер, сливающий все в набор файлов. На этом же сервере можно поставить любую аналитику, которая на вход получит большие файлы с логами, а на выходе необходимую вам статистику (можно на map-reduce, можно и попроще). Ротацию файлов можно поставить на 10 минут, scribe сам за вас их крутит. Готовые агрегаты сливаются в любую БД, скорость ее работы не принципиальна, ведь они пойдут на графики для узкого круга людей.
Наверно не совсем отвечу на ваш вопрос по архитектуре, но все же.
Если смотреть ваши требования к аналитике, то вам может помочь KissMetrics . Прекрасно справляется с аналитикой поведения пользователей... и многое другое.
Спасибо за совет, отличный инструмент! Но опять таки, эти данные очень проблемно "вынимать" из базы KissMetrics. Хотя для некоторых других сервисов он будет полезен безусловно :)
Меня смущает, что это всего лишь прослойка для принятия запросов и записи их в файл. Потом эти данные ведь нужно еще залить в БД и в БД их обрабатывать. Да и необязательно, что в будущем данной статистикой будет пользоваться узкий круг лиц. Поэтому обработка данных тоже критичный вопрос.
Я наткнулся на вот такую статью: kkovacs.eu/cassandra-vs-mongodb-vs-couchdb-vs-redis
В ней сравниваются разного рода NoSQL базы. Мне понравился вариант с Redis, за его высокую скорость работы и шардинг. А так же понравился HBase за возможность хранить огромное ("Billions of rows X millions of columns") кол-во данных. Но как-то не сильно верится, что все так безоблачно :)
Просто, будет ли смысл поднимать Disk I/O usage на серваке со Scribe, если можно сразу эти данные в Redis/HBase писать, которые висят в памяти?
Хранить и оперировать данными - разные вещи. Можно построить кластер на десяток террабайт, но расчет в нем среднее арифметическое на какой-нибудь гигантской таблице/колонке, займет минуты, если не часы. Гарантий по времени исполнения вам никто не давал.
Главное понять, высчитывать статистику "на лету" - плохая не эффективная практика. Нет смысла держать миллионы записей в БД для их постоянного GROUP BY, если только база не поддерживает материализованные представления (хак, достойный отдельного разговора).
Из моего опыта, должно быть хранилище для логов "как есть", медленное, но под большие объемы. Обычные файлы с архивами на сетевом диске для этого хорошо подходят. Должен быть вычислительный комплекс, можно на map-reduce, который не спеша расчитывает аналитику по логам. При этом комплекс может всегда начать считать что-то новое с самой первой записи архива. Результаты аналитики (коэфициенты линейной регрессии; sum/max/min/avg по часу/дню/неделе/месяце; корреляционные таблицы и т.д.) сливаются в любую БД. Очевидно, что результаты аналитики будут во много раз меньше исходных данных. Далее, по аналитике рисуем красивые графики.
Минус подхода - отсутствие произвольных запросов. Но как показала практика, люди не любят и путаются в произвольных запросах к статистике. Человек хочет видеть динамику роста продаж на графике с резолюцией в заранее известные интервалы (день, неделя и т.д.), а также ее корреляцию с днем недели и т.п. Вы всегда можете дополнить ваш вычислительный комплекс новым view на данные и расчитать все с первых записей архива.