10

我需要构建一个简单的分析后端来捕获用户行为。这将通过网页上的 Javascript 片段捕获,就像 Google Analytics 或 Mixpanel 数据一样。

系统需要捕捉接近实时的浏览器数据(页面滚动位置、鼠标位置等),每5秒记录一次用户页面的状态。每次测量只有三个属性,但必须经常使用。

数据不一定需要每 5 秒发送一次,它可以不那么频繁地发送,但是当用户在页面上时,我必须获取所有数据。即,我不能每分钟总线一次,并且对于在 119 秒后离开的人丢失最后 59 秒的数据。

如果可能的话,我想构建一个可在可预见的未来扩展的系统,这意味着它可以为 10,000 个站点工作,每个站点有 100 个并发访问者,即 100,000 个并发用户,每个用户每 5 秒发送一个事件。

我不担心查询数据,这可以使用单独的系统来完成。我最感兴趣的是如何处理数据本身的捕获。

要求

根据上述预算,系统每秒需要处理来自 100,000 个用户池的 20,000 个事件。

我想在 Heroku 上托管这项服务,但是虽然我已经使用 Rails 做了很多工作,但我对高吞吐量系统完全陌生(除了知道你不使用 Rails 处理它们之外)。

问题

  1. 是否有适合执行此操作的商业系统(例如 Pusher,但用于数据捕获和分发)?
  2. 我是否应该使用 HTTP 请求或 websockets 来执行此操作?
  3. node.js 是正确的选择还是只是时尚?
  4. 如果我要选择基于套接字的解决方案,Heroku 上的测功机可以为每个网络服务器处理多少个套接字
  5. 在 Mongo / Reddis 等之间进行存储选择的相关考虑因素是什么
  6. 这种类型的问题实际上需要两种解决方案吗?第一种是让您快速、廉价地进行合理扩展,第二种是让您以较低的增量成本超过该规模,但需要更多的开发工作前期?
4

2 回答 2

8

我对您的高级评论是按照12 因素设计构建您的系统,然后在客户到达时担心扩展。我对 Node.js 和 npm 生态系统感到兴奋,但我也认为您可以使用 Rails 构建一个完全可以接受的平台。如果使用 Node 需要 3 个 dyno 来支持 10 万并发用户,而使用 Rails 则需要翻倍,如果您对 Ruby 的熟悉让您更快进入市场 3 个月,那么使用 Rails 可能会更好。无论如何,假设您使用 Node,这是我的答案:

  1. 这里有一些可能对您有用的 Pusher替代方案以及关于Pusher 与 Pubnub的讨论。另请参阅Ably
  2. 使用socket.io。它在很大程度上是标准,因为它使用了可用的最佳传输并从 WebSockets 回退到 HTTP 方法。
  3. Node 是一个绝妙的选择,也很流行(参见模块增长率)。我怀疑你可以让你的系统在 Node、Rails 或其他几个框架中正常工作。
  4. Heroku dyno 应该能够支持数万个并发连接,具体取决于您使用 RAM 的效率。具有 16 GB RAM 的服务器能够支持一百万个并发连接。假设您的 RAM 有限,那么具有 512 MB RAM 的 Heroku dyno 应该能够支持约 30 K 的连接。
  5. 您可能想要选择两种不同的系统,一种用于存储和处理数据,另一种用于缓存。这是一篇关于从 Instagram 的创建者那里挑选核心数据平台的好文章。对于核心数据,我推荐使用 Sequelize ORM 的 Postgres(在 Heroku 上)。但是,使用 SOLR 进行搜索的 Mongo 可能也可以正常工作。请注意,如果您愿意,Postgres 9.2 可以用作 NoSQL 数据存储。对于缓存系统,我强烈推荐 Redis。
  6. 不,我会尽量避免丢弃工程。相反,构建一些有效的东西,并期望每当你达到一个数量级的流量时,系统的某些部分就会损坏并需要更换。但是,如果您遵循 12 要素原则,那么在投资替代品时,您应该能够很好地横向扩展。

祝你好运。

于 2013-06-26T10:49:53.647 回答
2
  1. 套接字服务有很多,但 Pusher 和 Pubnub 似乎是该领域的市场领导者。无论你做什么,都不要像 socket.io 那样托管你自己的,因为heroku 超时请求超过 30 秒,包括 websockets。因此,除非您计划每隔几秒钟关闭和重新打开套接字,否则托管套接字肯定是不可能的。
  2. 如果您要使用像 Pusher 这样的套接字服务,那么您将需要为该服务实现一个 http 端点,以便无论如何都向您发送数据。所以我会直接切断中间人并直接提出http请求。当然,您需要收集持续的用户交互,但所有这些都可以记录在 JavaScript 客户端上,并通过CORS XHR 或跟踪图像定期发送回应用程序。
  3. node 是一个不错的选择,它很轻巧,很容易设置,并且可用的 npm 库将拥有您入门所需的一切。Rails 也可以非常迅速,尤其是当您删除不需要的东西时。关于这个主题有一个很棒的railscast 。重要的是让它尽可能简单。也许把它分成两个应用程序;一个用于收集数据,另一个用于分析/处理它。通过这种方式,您可以在节点中收集数据,因为它速度很快,并在 Rails 中分析/处理它,因为它很容易。
  4. 正如我在 1. 中提到的那样,套接字在 heroku 中不起作用,即使您使用 pusher,您仍然必须支持相同数量的 http 请求,因为当 pusher 接收到数据时,它会直接发送它给你。至于您需要多少测功机,这将是容易测试的东西,但我无法估计。这将完全取决于收集数据的代码的效率。一个简单的 Apache AB 测试,包含您期望的负载和并发性,可以很好地表明您需要什么。Node 自带并发,但如果您要使用 rails 收集数据,请使用 unicorn 或 puma 作为您的服务器,因为它们支持并发。Apache AB 测试时也尝试不同的配置;
  5. 这个stackoverflow线程表明redis越来越快是您收集数据所需要的。尽管在收集它之后,您可能希望对其进行处理并将其存储在不止一个键值存储中。Mongo 是一个不错的选择,但我会使用像neo4j这样的图形数据库,因为分析具有复杂的连接。
  6. 如果您在这里进入新领域,那么您不会第一次就做好,您会发现自己在迭代它以获得最佳性能和最准确的数据。最终,您可能会删除它并重新开始使用新架构,然后循环将继续。将数据收集和分析分开意味着您可以专注于分别正确处理每一位。

我想提到的几点是使用 CDN 分发 JavaScript 客户端,或者更好的是,提供完整的 JS 以从页面提供服务。无论哪种方式,快速加载并异步加载。这听起来像是一个有趣的项目。祝你好运!

编辑在另一个宇宙中,您不必使用 heroku,websockets 将是一个很棒的解决方案。

于 2013-06-26T18:20:19.973 回答