使用Heroku构建可扩展分析后端的最佳方法是什么?

时间:2013-06-22 17:48:14

标签: node.js heroku websocket

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

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

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

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

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

要求

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

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

问题

  1. 是否有商业系统可以做到这一点(如Pusher,但数据捕获和分发)?
  2. 我是否应该使用HTTP请求或websockets进行此操作?
  3. node.js是正确的选择还是时尚?
  4. 如果我选择基于套接字的解决方案,Heroku上的dyno可以为每个网络服务器处理多少个套接字
  5. 选择Mongo / Reddis等进行存储的相关注意事项
  6. 这是一种实际上需要两种解决方案的问题 - 第一种是让您快速,低成本地达到合理规模,第二种是让您在降低增量成本的情况下超越这种规模,但需要提前进行更多的开发工作?

2 个答案:

答案 0 :(得分:9)

我对您的高级评论是按照12 factor设计构建您的系统,然后担心随着客户的到来进行扩展。我对Node.js和npm生态系统感到非常兴奋,但我也认为你可以用Rails构建一个完全可以接受的平台。如果使用3个dynos来支持100个并发用户并使用Rails加倍,那么使用Rails可能会更好,如果你对Ruby的安慰让你上市3个月更快。无论如何,假设你使用Node,这是我的答案:

  1. 以下是Pusher的一些alternatives,可能对您有用,并且对Pusher vs. Pubnub进行了讨论。另请参阅Ably
  2. 使用socket.io。它主要是标准,因为它使用了最好的传输,并从WebSockets回退到HTTP方法。
  3. Node是一个很棒的选择,也很新潮(参见模块growth rate)。我怀疑你可以让你的系统在Node,Rails或其他几个框架中正常工作。
  4. Heroku dyno应该能够支持数以万计的并发连接,具体取决于你对RAM的效率。具有16 GB RAM的服务器能够支持million并发连接。假设你受RAM限制,带有512 MB RAM的Heroku dyno应该能够支持~30 K连接。
  5. 您可能希望选择两个不同的系统,一个用于存储和处理数据,另一个用于缓存。关于从Instagram的创建者那里挑选核心数据平台,这是一个很棒的post。对于核心数据,我推荐使用Sequelize ORM的Postgres(在Heroku上)。但是,使用SOLR进行搜索的Mongo可能也可以正常工作。请注意,Postgres 9.2可以用作NoSQL数据存储区,如果这是您想要的方式。对于缓存系统,我强烈推荐Redis。
  6. 不,我会尽量避免丢掉工程。相反,构建一些有效的东西,并期望每当你达到一个数量级的更多流量时,系统的某些部分将会中断并需要被替换。但是,如果你遵循12因素原则,那么在你投资替换时,你应该处于良好状态以横向扩展。
  7. 祝你好运。

答案 1 :(得分:3)

  1. 有许多套接字服务,但Pusher和Pubnub似乎是这个领域的市场领导者。无论你做什么,都不要托管自己的socket.io,因为heroku times out requests longer超过30秒,包括websockets。因此,除非您计划每隔几秒钟关闭并重新打开套接字,否则托管套接字肯定是不可能的。
  2. 如果你要使用像Pusher这样的套接字服务,那么你需要为服务实现一个http端点,无论如何都要向你发送数据。所以我只是把中间人剪掉,直接用http请求。当然,您需要收集持续的用户交互,但这些交互都可以记录在JavaScript客户端上,并通过CORS XHR或跟踪图像定期发送回应用程序。
  3. 节点是一个很好的选择,它很轻松,很容易设置,并且npm库可以提供您开始使用所需的一切。 Rails也可以非常迅速,特别是如果你剪掉了你不需要的东西。关于这个主题有一个很棒的railscast。重要的是保持尽可能简单。也许将它分成两个应用程序;一个用于收集数据,另一个用于分析/处理数据。通过这种方式,您可以收集节点中的数据,因为它很快并且可以在轨道中分析/处理它,因为它很容易。
  4. 正如我在1.套接字中提到的那样,套接字不会在heroku中工作,即使你使用了pusher,你仍然需要支持相同数量的http请求,因为当推送器接收到它将要发送的数据时它直接给你。至于你需要多少个dynos,这将是一个容易测试的东西,但不是我能估计的东西。它完全取决于收集数据的代码的效率。使用您期望的加载和并发性的简单Apache AB测试将为您提供所需内容的良好指示。 Node带有它自己的并发性,但是如果你使用rails来收集数据,那么使用unicorn或puma作为你的服务器,因为它们支持并发。 Apache AB测试时也尝试不同的配置; heroku现在提供2x dynos,它们是1024mb而不是512,这将允许你更多的并发
  5. This stackoverflow thread表示redis越来越快,你想要收集数据的速度越来越快。虽然在收集它之后,您可能希望处理它并将其存储在一个键值存储中。 Mongo是一个很好的选择,但我会使用像neo4j这样的图形数据库,因为分析有复杂的连接。
  6. 如果你在这里进入新的领域,那么你不会在第一时间做到正确,你会发现自己在迭代它以获得最佳性能和最准确的数据。最终你可能会删除它并重新开始使用新架构,循环将继续。保持数据收集和分析分离意味着您可以专注于分别获得每个位。
  7. 我想提到的一些附加点是使用CDN来分发JavaScript客户端,或者更好的是,提供从页面提供的完整JS。无论哪种方式,加载速度和异步加载。这听起来像一个有趣的项目。祝好运!

    编辑在备用Universe中,您不必使用heroku,websockets将是一个非常棒的解决方案。