Ruby ActiveRecord 做数据统计的常用方案

lb563 · 2013年05月31日 · 最后由 mvj3 回复于 2013年08月03日 · 4371 次阅读

各位大牛。有大批量的数据需要进行分析和统计。

用 activerecord 处理时会有大量的查询操作。

在时间和性能不太满意。我想可以把数据全部读到内存中然后再处理这些数据

有哪些比较好的方案来处理这种情况呢?

Modal.all

重构你的统计表吧,个人更倾向于数据表与统计表分离,而不是统计的时候去实际操作数据表。

结合下数据库的特性吧。看你用的什么数据库了。

考虑加大 cache,你自己在内存中处理的速度,未必比数据库本身的算法快。

我一般情况统计是直接 sql。sql 出来已经满足 80% 的统计数据了。当然不一定就一个 sql。

如果你说的统计是把数据全列出来。。。好吧,我们把那叫做查询

#2 楼 @zfjoy520 能推荐几个例子么? 我也碰到类似的问题,某些统计结果需要多个 join+ 排序才能搞定。

#2 楼 @zfjoy520 现在是把所有的中间过程的数据都生成数据表放到 mysql 中,最后再来用 AR 统计分析这析中间表。

#3 楼 @gavinju #5 楼 @badboy 现在处理使用 Mysql+ActiveRecord 同时结合使用 activerecord-import 来批量导入数据

基本的数据库吧,这种统计页面或导出访问应该不是很频繁;多了可以后台批处理到单独数据库和计算过程的表和最终结果,可以定期同步下数据。

考虑过 db 是一主一备,备的那个可以用来统计之类只查询不修改,但是没有实际操作过。

#6 楼 @xmonkeycn 与 mysql 的 binlog 的原理类似,记录一些统计需要的 mysql 日志流。

首先是设计一系列的与业务逻辑相对应的统计表,然后再在每一个业务逻辑中,你加了什么,加了多少,都以明文 mysql 的形式记录到一个 log 文件中,比如:

insert into table_name values(****);

然后再通过定时任务,把这些日志 mysql xxxx < logfile 批量导入到统计表中。

然后再在这个统计表的基础之上,做一些统计分析,而不是去分析核心数据表本身。

虽然这样的做法,会导致一部分数据信息的滞后,但个人觉得,相对于高并发下,去分析海量的 live 数据,从性能上,从安全上来讲,是有一定的优势的。

个人意见,仅供参考。

#10 楼 @zfjoy520 现在的做法是把日志写到 log 文件中以 csv 的方式写入 (为了缩小文件的大小),一段时间后用 ruby 脚本解析 CSV 格式的 log 文件并用 AR 写入到 Mysql 数据库。并把这部分数据做为分析的源数据.最后到这些源数据上分析统计。现在做到一半.感觉如果出现大文件的话。解析 log 文件会成为一个坎。即使保存到 mysql 中用 AR 做查询的话可能还是会出现效率问题。

#11 楼 @lb563 建议还是利用原生的 mysql 导入方式,多条语句 1 个 commit,应对海量数据的导入是没有问题的。AR 写入太慢。

#10 楼 @zfjoy520 通过分析日志把几个导入统计表这个方法很有启发。 另外 AR 的导入问题,之前@xdite 有个分享,专门讲 AR 的额外开销的问题。 http://blog.xdite.net/posts/2012/08/22/rails-with-massive-data/

@lb563

整个流程的解决方案

从你的说明来看,我把过程分为两个步骤,

其一是收集,日志以 CSV 格式写入,而不是数据库,可能是应用程序为了写入性能的考虑。

其二是分析数据的清理和初始化,上面你提到为了时间和性能上的考虑,你是想把它们全部读入内存来提升访问速度以此来加快计算的。

但是这里的“全部读入内存”我觉得是不可取的,尤其是要”大量查询“和“性能”,我觉得应该存在为数据索引而生的数据库里(推荐支持 MapReduce 的 Mongodb,或者专门为统计分析优化的列式数据库),并尽量缓存部分计算结果在磁盘上是比较可取的自然的一个方案。(如果你需要实时统计等其他需求就别论了)。

另外推荐我写的一个基于 Ruby DSL 的统计分析解决方案,地址在 https://github.com/eoecn/statlysis ,它也支持多表的数据查询统计。目前在开发第二版,欢迎使用和完善:)

日志导入的解决方案

CSV 是一个很规范的数据格式,mysql 和 mongodb 等数据库是直接支持导入的,不必再解析然后通过 ORM 导入数据库。

需要 登录 后方可回复, 如果你还没有账号请 注册新账号