我正在使用Ruby EventMachines已经有一段时间了,我认为我理解它的基础知识。
但是,我不确定如何在大文件(120 MB)中正常读取。我的目标是逐行读取文件并将每一行写入Cassandra数据库(同样应该使用MySQL,PostgreSQL,MongoDB等,因为Cassandra客户端显式支持EM)。简单的片段阻塞了反应堆,对吗?
require 'rubygems'
require 'cassandra'
require 'thrift_client/event_machine'
EM.run do
Fiber.new do
rm = Cassandra.new('RankMetrics', "127.0.0.1:9160", :transport => Thrift::EventMachineTransport, :transport_wrapper => nil)
rm.clear_keyspace!
begin
file = File.new("us_100000.txt", "r")
while (line = file.gets)
rm.insert(:Domains, "#{line.downcase}", {'domain' => "#{line}"})
end
file.close
rescue => err
puts "Exception: #{err}"
err
end
EM.stop
end.resume
end
但是,以异步方式读取文件的正确方法是什么?
答案 0 :(得分:5)
EventMachine中没有异步文件IO支持,实现您尝试执行的操作的最佳方法是在每个tick上读取几行并将其发送到数据库。最重要的是不要读太大的块,因为这会阻塞反应堆。
EM.run do
io = File.open('path/to/file')
read_chunk = proc do
lines_sent = 10
10.times do
if line = io.gets
send_to_db(line) do
# when the DB call is done
lines_sent -= 1
EM.next_tick(read_chunk) if lines_sent == 0
end
else
EM.stop
end
end
end
EM.next_tick(read_chunk)
end
请参阅What is the best way to read files in an EventMachine-based app?
答案 1 :(得分:1)
如果您还没有,可以查看EM::FileStreamer。首先,FileStreamer使用基于C ++的“快速文件阅读器”。你不能通过本地套接字/管道传输文件,并在一个单独的进程中处理发送到数据库,该进程正在另一端进行侦听吗?
还有一个基于非光纤的示例,在ThreadedResource中优雅地处理同步数据库连接,以防有用......特别提到了Cassandra。虽然听起来你的Cassandra库是基于光纤的。