Ruby 针对大量数据跑任务

niedhui · 2012年04月17日 · 最后由 kehao 回复于 2012年04月19日 · 4940 次阅读

我们现在有一千万条左右的数据,需要针对其中的每一条进行操作 大体的逻辑是这样, 很简单

lot_of_rows.each do |row|
  # Resque.enqueue(job, row)  
end


一开始数据量很小,不用 resque, 一个 each 就行了。后来数据量大了,上了 resque, 也从原来的一个 each 分成了很多小的 each,逻辑大体变成这样(当然,日期是计算的,不是写死的:)):

XX.where(created_at: Time.local(2012, 1)..Time.local(2012,2).each do ||
end

XX.where(created_at: Time.local(2012, 2)..Time.local(2012,3).each do ||
end 


像这种情况各位有没有什么更好的方法呢.处理大数据一点经验也没啊

是海量数据处理不是存储?如果是尝试过 MapReduce 没有? 我用 Hadoop 来处理; 没有用 Ruby 处理,别拍我 :)

单从这几行代码看,把 each 换成 find_each ,不过像你说的那个数据量的话 find_each 后对数据做处理后最终还是要自己构造 sql 语句批量 insert 和 update

#1 楼 @donnior 现在数据都是存在 mongodb 里面,不到最后,不太想试 Hadoop 啊,总觉得好重的东西:)

#2 楼 @vkill 现在用的是 mongoid,一次查询如果返回的数据量稍微大一点的话,cursor 移到后面就会变的很慢

#3 楼 @niedhui 能不使用就不使用!不过 heavy 也不至于,我是因为要对千万级的数据进行分析才用的

这事别让 ruby 来干了 不适合 用 java 开几个线程跑 千万级也不是很多

ruby 当然适合,只要有 thread/process 的语言都适合 并行处理就对了,注意下数据库链接是不是 thread safe 的 比如用这个 http://burgestrand.se/code/ruby-thread-pool/

感觉用 MapReduce 比较好

mongdodb 是可以用 MapReduce 的 可以尝试一下

1000 万不用什么特殊的,如之前所说,用 java/jruby 写,开几个线程跑就好了。 数据最好 dump 到文件,避免对数据库造成压力,处理起来也简单。

@reus 你跑跑大数据就知道了。。内存泄漏不是一点点。。

#8 楼 @Rei #9 楼 @ltl3884 MongDB 自身的 MapReduce 是单线程的(原因:它是由 Mongo Shell 支持的,而后者是 JavaScript)。所以如果你要作的操作本身仅对一条数据进行改动(这里单纯理解 MapReduce 要对所有数据进行汇总),那恐怕用 MapReduce 帮助不大,而且内存使用和性能影响也不小。

另外,考虑到 Ruby Driver 的语法跟 shell js 语法差不多,如果是 Mongoid 或 driver 上开销大,可以尝试一下直接在 mongo shell 里进行操作。

PS,如果是要用 MapReduce 来做统计,那么将数据 dump 到另一个不直接使用的 mongod 上,或是一个 secondary node 上来进行会更好一点。

之前优化了一个跑数据的任务,数据在 150W * 8,从 40 天-10 天-1 天,用的就是 ruby,那次瓶颈在网络 IO,因为要通过 http 得到图片,去计算图片的分辨率,因为历史原因,图片分布在多台机器上,后来还是改成了 socket,然后跑数据的还是在一台机子上 fork 了多个进程一起跑。主要还是找出根本原因吧。

#13 楼 @kenshin54 很有道理。找出瓶颈就解决了问题的 80%。

#11 楼 @bony 内存泄漏是指 ruby 解释器本身的 bug,还是使用者不释放资源引起的?如果是后者,现场全部销毁下就是了。千万级算不上大数据吧,单机都可以处理的

可以考虑 异步处理,用 eventmachine

sidekiq 是类似 resque,但多线程处理。

先谢谢各位了。我的这个情况逻辑很简单,用 mapreduce 的话好你都找不到要 reduce 啥,内存这个问题到是确实有,一次返回的结果大一些内存就飚上去了。数据分段有什么好的建议吗?因为即使是 mapreduce 也不会一次把数据都取回来吧,我现在就是一个月的一组,以后可能要每周一组了,或者有类似的实现不

@reus 我的意思是有加农炮就别用小米步枪凑合了。

#17 楼 @anklos sidekiq 似乎没法支持 Mongoid

@huacnlee 对,是不支持。我也是才接触。看了下他们只支持 redis,没有计划支持其他类型 db

建议先做数据库优化,索引很重要,可以考虑分表,读写分离。实时性不是很高的需求不建议用队列,这种一个操作就要更改上 1000 万条数据的需求真的并不多,客户又不要求你一下把这上 1000 万的数据给列出来.

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