内存泄漏Rails + Sidekiq + Heroku + jsonb

时间:2018-03-08 23:14:16

标签: ruby-on-rails json heroku memory-leaks sidekiq

我目前正在获取某一货币对过去两年的大量加密每小时价格。我同时使用Sidekiq获得多个硬币。

问题在于,当我使用jsonb存储信息时,我怀疑它导致了大量的内存泄漏。但我可能错了,我的Active Record查询没有优化。

由此产生的因素是我的Heroku Workers一直在超越配额并关闭。

def get_2_years_of_btc_data(coin_id)
        begin
            time_batches = [1451606400,1458810000,1466013600,1473217200,1480420800,1487624400,1494828000,1502031600,1509235200,1516438800,1523642400]
            time_batches.each do |time| 
                 sync_hourly_btc_data(coin_id,time)                 
            end
        rescue => e
            #ScrapeLog.create(error: e.message, process: "Cryptocompare - Sync Coin Prices", resource: "coin", resource_id: coin_id)
        end
    end

def sync_hourly_btc_data(coin_id,floored_timestamp)
    coin = Coin.find(coin_id)
    snap = coin.snap        
    response = HTTParty.get("https://min-api.cryptocompare.com/data/histohour?fsym=#{coin.ticker}&aggregate=1&tsym=BTC&limit=2000&toTs=#{floored_timestamp}")
    json = JSON.parse(response.body)
    data = json["Data"]
    if snap.btc_counter_cache < 1
        snap.to_btc = data
    else
        new_data = data.select {|data| data["time"] > snap.btc_to_ts} 
        snap.to_btc = snap.to_btc + new_data
    end
    snap.btc_from_ts = snap.to_btc.first["time"]
    snap.btc_to_ts = snap.to_btc.last["time"]
    snap.coin.real_price_btc = snap.to_btc.last["close"]
    snap.btc_counter_cache = snap.to_btc.size
    snap.save
end

Snaps 是存储每个硬币价格信息的表格, to_btc 是存储所有数据的jsonb列。

我知道这是一个常见的jsonb问题,当它的大小增加或我的Active Record查询效率低下时,我需要帮助。

谢谢!

1 个答案:

答案 0 :(得分:1)

这看起来不像jsonb。我假设所提供的代码是实际的工作者,所以我在这里的第一步是将时间批处理队列入队列。您目前正在这样做的方式是将内存中的所有API响应保留在内存中。

因此,如果您按批次排队工作/工作人员,您可以单独处理每个响应 - 假设工人之间有一些退避(排队等待2分钟或相隔某事),您应该没事。

我认为数据是那么大,你正在做的选择遍历也相当昂贵