My Rails 4应用程序有一个每小时运行一次的进程,它会根据.csv文件中的数据创建/更新数据库中的100,000多条记录。
在此过程正在运行时,应用程序的最终用户也尝试访问数据库密集型页面(选择数千条记录)。这导致应用程序超时/崩溃。当上述过程未运行时,这些页面会快速加载。
我曾尝试使用“EM.defer”和“Thread.new”,但我认为这是我的数据库正在变得过载(CPU和内存都很好)。使用thin-threre和Passenger也会发生同样的问题。
以下是将数据加载到ActiveRecord中的代码:
def load_records # load thousands of records from CSV files
EM.defer do
loadRecordsFromCSV
end
end
def loadRecordsFromCSV
require "csv"
csvfile = "./lib/csvfile.csv" # 100,000+ lines
CSV.foreach(csvfile) do |row|
d = row[0]
s = row[1]
g = row[2]
ss = row[3]
n = row[4]
c = row[5]
cc = row[6]
p = row[7]
ad = row[8]
av = row[9]
params = { d: d, s: s, g: g, ss: ss, n: n, c: c, cn: cn, p: p, ad: ad, av: av }
existingFoo = Foo.find_by(d: d, s: s, c: c)
if existingFoo != nil
existingFoo.update(params)
else
Foo.create(params)
end
end
end
有没有办法设置它,在运行时不会冻结/减慢我的应用程序?这个过程需要几分钟,并且每小时冻结应用程序这个时间不是一个选择。
我尝试使用原始SQL而不是ActiveRecord,并且还首先写入临时表,但是同样的问题正在发生。
这无疑是我的第一个RoR项目,所以非常感谢任何帮助!
答案 0 :(得分:0)
问题已经解决了。我使用原始SQL而不是ActiveRecord重写了我的记录加载函数,最重要的是我从加载函数周围删除了“EM.defer”。我似乎不知道如何正确使用EventMachine,它实际上干扰了多线程。我希望切换到Postgres或MySQL进行生产,以期有望提高性能。