Ruby on Rails并发数据库请求崩溃

时间:2015-06-03 15:36:32

标签: ruby-on-rails multithreading activerecord

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项目,所以非常感谢任何帮助!

1 个答案:

答案 0 :(得分:0)

问题已经解决了。我使用原始SQL而不是ActiveRecord重写了我的记录加载函数,最重要的是我从加载函数周围删除了“EM.defer”。我似乎不知道如何正确使用EventMachine,它实际上干扰了多线程。我希望切换到Postgres或MySQL进行生产,以期有望提高性能。