Каков наилучший способ построения масштабируемой аналитической базы с использованием Heroku?

Мне нужно создать простой аналитический интерфейс для захвата поведения пользователя. Это будет зафиксировано с помощью фрагмента Javascript на веб-странице, как данные Google Analytics или Mixpanel.

Системе необходимо фиксировать данные браузера с близкого расстояния до реального времени (прокручивание позиции страницы, положение мыши и т.д.). Она будет записывать состояние страницы пользователей каждые 5 секунд. На каждое измерение есть только три атрибута, но их нужно принимать часто.

Данные не обязательно должны отправляться каждые 5 секунд, их можно было бы отключить реже, однако необходимо, чтобы я получал все данные, пока пользователь находится на странице. то есть я не могу его пропустить один раз в минуту и ​​потерять последние 59 секунд данных для тех, кто уходит после 119 секунд.

Если возможно, я бы хотел создать систему, которая будет масштабироваться в обозримом будущем, что означает, что она работает на 10 000 сайтов, каждая из которых имеет 100 одновременных посетителей, т.е. 100 000 одновременных пользователей, каждый из которых отправляет одно событие каждые 5 секунд.

Я не беспокоюсь о запросе данных, это можно сделать с помощью отдельной системы. Меня больше всего интересует, как обрабатывать захват самих данных.

Требования

На основе вышеописанного бюджета система должна обрабатывать 20 000 событий в секунду, исходящих из пула из 100 000 пользователей.

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

Вопросы

  • Есть ли коммерческая система, которая была бы хороша для этого (например, Pusher, но для сбора данных, а также для распределения)?
  • Должен ли я искать это с помощью HTTP-запросов или веб-сайтов?
  • Является ли node.js правильным выбором для этого или просто модным?
  • Если бы я выбрал решение на основе сокетов, сколько сокетов может иметь дино на дескрипторе Heroku для каждого веб-сервера
  • Каковы соответствующие соображения для выбора между Mongo/Reddis и т.д. для хранения
  • Это тот тип проблемы, который на самом деле требует двух решений - первый, чтобы вы получили разумный масштаб быстро и недорого, а второй, чтобы пройти мимо этой шкалы при более низких дополнительных затратах, но с большим количеством усилий по разработке, требуемых заранее?

Ответ 1

Мой комментарий высокого уровня для вас состоит в том, чтобы построить вашу систему, следуя 12 факторам, а затем беспокоиться о масштабировании по мере поступления клиентов. Я в восторге от Node.js и экосистемы npm, но я также думаю, что вы могли бы создать совершенно приемлемую платформу с Rails. Если для поддержки 100 K одновременных пользователей с Node потребовалось 3 динамика, и вдвое больше, чем с Rails, вам все равно может быть лучше с Rails, если ваш комфорт с Ruby заставит вас выйти на рынок на 3 месяца быстрее. В любом случае, если вы идете с Node, вот мои ответы:

  • Вот несколько alternatives для Pusher, которые могут сработать для вас и обсуждения Pusher vs. Pubnub. Также см. Ably.
  • Используйте socket.io. Это в значительной степени стандарт, поскольку он использует лучший доступный транспорт и отказывается от методов WebSockets для HTTP.
  • Node - фантастический выбор, а также модный (см. модуль темп роста). Я подозреваю, что вы можете сделать вашу систему хорошо работать в Node, Rails или нескольких других фреймворках.
  • Динамик Heroku должен поддерживать десятки тысяч одновременных подключений, в зависимости от того, насколько вы эффективны с ОЗУ. Сервер с 16 ГБ оперативной памяти смог поддерживать параллельные соединения миллионов. Предполагая, что вы ограничены оперативной памятью, динар Heroku с 512 МБ ОЗУ должен поддерживать ~ 30 K соединений.
  • Вероятно, вы захотите выбрать две разные системы: одну для хранения и обработки ваших данных, а также одну для кэширования. Вот отличный пост о выборе вашей основной платформы данных от создателя Instagram. Для основных данных я рекомендую Postgres (на Heroku) с помощью Sequelize ORM. Но, Mongo с SOLR для поиска, вероятно, тоже будет работать. Обратите внимание, что Postgres 9.2 можно использовать в качестве хранилища данных NoSQL, если это так, как вы хотите. Для системы кеширования я настоятельно рекомендую Redis.
  • Нет, я бы постарался не выбрасывать инженер. Вместо этого создайте что-то, что работает, и ожидайте, что каждый раз, когда вы наберете на порядок больше трафика, какая-то часть системы сломается и должна быть заменена. Но, если вы следуете принципам 12 факторов, вы должны быть в хорошей форме, чтобы масштабироваться горизонтально, пока вы инвестируете в замену.

Удачи.

Ответ 2

  • Существует множество сервисов для сокетов, но Pusher и Pubnub, похоже, являются лидерами рынка в этом пространстве. Что бы вы ни делали, не размещайте свой собственный, как socket.io, потому что heroku раза больше запросов больше, чем 30 секунд, включая websockets. Поэтому размещенный сокет определенно не может быть и речи, если вы не планируете закрывать и повторно открывать сокет каждые несколько секунд.
  • Если вы должны использовать службу сокетов, такую ​​как Pusher, тогда вам нужно будет реализовать конечную точку http для службы, чтобы отправить вам данные в любом случае. Поэтому я бы просто вырезал среднего человека и отправился с прямым запросом http. Конечно, вам нужно собирать постоянные пользовательские взаимодействия, но все это может быть записано на клиенте JavaScript и периодически отправляться обратно в приложение через CORS XHR или изображение отслеживания.
  • node - отличный выбор, легкий, довольно простой в настройке, и доступные библиотеки npm будут иметь все необходимое для начала работы. Рельсы могут быть довольно быстрыми, особенно если вы вырезаете то, что вам не нужно. Существует большой railscast по этому вопросу. Важно держать его как можно проще. Возможно, разбить его на два приложения; один для сбора данных, другой для анализа/обработки. Таким образом, вы могли бы собирать данные в node, чтобы быстро и анализировать/обрабатывать их в рельсах, так как это легко.
  • Как я упоминал в 1. Розетки просто не будут работать в героике, и даже если вы использовали толкатель, вам все равно придется поддерживать одинаковое количество HTTP-запросов, потому что когда толкатель получает данные, которые он собирается отправить это прямо на вас. Что касается того, сколько динамиков вам понадобится, это будет то, что будет легко протестировано, но не то, что я могу оценить. Это будет полностью зависеть от эффективности кода, собирающего данные. Простой тест Apache AB с нагрузкой и concurrency, который вы ожидаете, даст вам хорошее представление о том, что вам нужно. node поставляется с собственным concurrency, но если вы собираетесь использовать рельсы для сбора данных, используйте единорог или пуму как ваш сервер, потому что они поддерживают concurrency. Также попробуйте различные конфигурации при тестировании Apache AB; heroku теперь обеспечивают 2x dynos, которые 1024mb вместо 512, которые позволят вам больше concurrency
  • fooobar.com/info/33783/... предлагает redis быстрее и быстрее - это то, что вы собираетесь собирать для сбора данных. Хотя после его сбора вы, вероятно, захотите обработать его и сохранить в более чем ключевом хранилище значений. Mongo - хороший вариант для этого, но я бы пошел с графической базой, например neo4j из-за сложной аналитики соединений.
  • Если вы входите в новое место здесь, то сначала вы не поймете это правильно, вы найдете себе итерацию над ним, чтобы получить лучшую производительность и самые точные данные. В конце концов вы, вероятно, удалите его и начнете снова с новой архитектуры, и цикл продолжится. Сохранение сбора данных и отдельного анализа означает, что вы можете сосредоточиться на получении каждого бита отдельно.

Несколько дополнительных точек, которые я хотел бы упомянуть, это использование CDN для распространения клиента JavaScript или, еще лучше, предоставление полного JS для обслуживания со страницы. В любом случае, загрузите быстро и загрузите асинхронно. Это звучит как забавный проект. Удачи!

РЕДАКТИРОВАТЬ В альтернативном юниверсе, где вам не нужно использовать heroku, веб-разъемы будут отличным решением.