【发布时间】:2018-05-03 22:13:24
【问题描述】:
我正在一个应用程序中构建多个报告,并且遇到了几种构建报告的方法,并希望让您了解构建可扩展且尽可能实时的报告的最佳/常用方法。
首先,一些条件/限制/目标:
- 报告应该能够实时处理(使用 node.js 或 ajax 轮询)
- 报告应该以优化的方式更新
- 如果报告是关于页面浏览量的,而您每秒获得数千次,则最好不要在每次页面浏览时更新报告,而是每 10 或 100 次更新报告。
- 但它仍应接近实时(因此每日/每小时 cron 不是可接受的替代方案)。
- 报告不应该重新计算它已经计算过的东西。
- 如果有计数,它会增加一个计数器。
- 如果它有平均值,也许它可以以某种方式更新平均值,而无需获取它每秒平均的所有记录并重新计算(尚不确定如何执行此操作)。
- 如果它具有某个日期范围(今天、last_week、last_month等)的计数/平均值,并且它是实时的,它不应该每秒/请求重新计算这些平均值,以某种方式只执行最少的操作。
- 如果报告是关于记录并且记录的“生命周期”是完整的(比如
Project,并且该项目持续了 6 个月,有很多活动,但现在结束了),则应该永久保存报告因此后续检索只需提取一个预先计算的文档。
报告不需要是可搜索的,因此一旦数据在文档中,我们只是显示文档。客户端基本上得到一个表示所有统计数据、图表等的 JSON 树,因此它可以在 Javascript 中呈现。
之所以提出我的问题,是因为我正试图找出一种方法来对大型数据集进行实时报告。
假设我正在报告网站上的整体用户注册和活动。该网站有 100 万用户,平均每秒有 1000 次页面浏览量。假设有一个User 模型和一个PageView 模型,其中User has_many :page_views。假设我有这些统计数据:
report = {
:users => {
:counts => {
:all => user_count,
:active => active_user_count,
:inactive => inactive_user_count
},
:averages => {
:daily => average_user_registrations_per_day,
:weekly => average_user_registrations_per_week,
:monthly => average_user_registrations_per_month,
}
},
:page_views => {
:counts => {
:all => user_page_view_count,
:active => active_user_page_view_count,
:inactive => inactive_user_page_view_count
},
:averages => {
:daily => average_user_page_view_registrations_per_day,
:weekly => average_user_page_view_registrations_per_week,
:monthly => average_user_page_view_registrations_per_month,
}
},
}
我尝试过的事情:
1。其中User 和PageView 都是ActiveRecord 对象,所以一切都通过SQL。
我将所有用户分块抓取,如下所示:
class User < ActiveRecord::Base
class << self
def report
result = {}
User.find_in_batches(:include => :page_views) do |users|
# some calculations
# result[:users]...
users.each do |user|
# result[:users][:counts][:active]...
# some more calculations
end
end
result
end
end
end
2。两条记录都是MongoMapper::Document 对象
当场计算 Map-reduce 真的很慢,而且我还没有花时间弄清楚如何使这项工作成为实时式(查看hummingbird)。基本上我做同样的事情:对记录进行分块,将结果添加到哈希中,就是这样。
3。每个计算都是它自己的 SQL/NoSQL 查询
这是 Rails statistics gem 采用的一种方法。我唯一不喜欢的是这可能产生的查询量(没有基准测试每个请求每个报告进行 30 个查询是否比将所有对象分块到内存中并在直接 ruby 中排序更好)
问题
我想问题是,根据您的经验,对大型数据集进行实时报告的最佳方式是什么?通过对每个请求的内存中的记录进行分块/排序(我现在正在做的事情,我可以使用每小时 cron 进行一些优化,但它不是实时的),生成报告大约需要一秒钟(复杂的日期公式和这样),有时更长。
除了传统的优化(更好的日期实现、sql/nosql 最佳实践)之外,我在哪里可以找到一些关于构建报告的实用且经过验证的文章?我可以毫无问题地生成报告,问题是,您如何使其快速、实时、优化且正确?真的什么都没找到。
【问题讨论】:
-
你能分享你的方法吗?我想实现同样的目标。你能分享你的面向可扩展性的面向对象设计吗?
-
@Lance Pollard 嗨,您对上述问题有什么解决方案吗?
-
@krunalshah 你找到解决方案了吗。请与我分享我也需要同样的
标签: ruby-on-rails