2017-06-29 36 views
0

問題:在預期清除並重建特定的redis密鑰後,工作器dynos不會分配內存(直到重新啓動dyno)。Redis在大型DEL&HMSET功能上消耗最大內存

我體驗過程中刪除在我的Heroku的工人DYNOS均創下95%-100%最大內存使用的問題,重建關於鍵。我有一個計劃重建,每天凌晨4點開始。基於日誌,我假設按鍵的DEL鍵+按鍵的重建大約需要〜1490秒。

Jun 29 04:01:41 app app/worker.2: 4 TID-...io8w RedisWorker JID-...cd2a7 INFO: start 
Jun 29 04:06:28 app app/worker.1: 4 TID-...mtks RedisWorker JID-...bf170 INFO: start 
Jun 29 04:26:32 app app/worker.1: 4 TID-...mtks RedisWorker JID-...bf170 INFO: done: 1203.71 sec 
Jun 29 04:26:33 app app/worker.2: 4 TID-...io8w RedisWorker JID-...cd2a7 INFO: done: 1490.938 sec 

內存將懸停最大使用率,直到dyno重新啓動(已安排)或我們部署。示例圖片:Heroku Memory Usage

這是一個高層次得到什麼在凌晨4點觸發:

def full_clear 
    RedisWorker.delete_keys("key1*") 
    RedisWorker.delete_keys("key2*") 
    RedisWorker.delete_keys("key3*") 
    self.build 
    return true 
    end 

    def build 
    ... rebuilds keys based on models ... 
    return true 
    end 

    def self.delete_keys(regex) 
    $redis.scan_each(match: regex) do |key| 
     $redis.del(key) 
    end 
    end 

我至今還是我的思想研究:

  • 後Redis的DEL被調用內存不分配?

  • 是否有更好的實現找到所有匹配和做批量刪除的鍵?

  • 我使用默認值爲美洲獅;將配置puma + sidekiq更好地匹配我們的資源是最好的開始行動嗎? Deploying Rails Applications with the Puma Web Server。重新啓動後,內存只有大約30%-40%,直到下一次完全重建(即使在大量使用hmset期間)。

  • 我注意到,在dyno重新啓動/休息一天之後,我的ObjectSpace計數相當低很多,直到下一個預定的full_rebuild。

任何想法我怎麼能去試圖找出什麼導致DYNOS掛內存?看起來很喜歡/正在使用的工人dynos會重建Redis。

回答

0

解決方案:

我安裝了新的文物,看看是否有一個潛在的內存膨脹。我們最常用的函數調用之一是執行N + 1查詢。修正了N + 1查詢,並在New Relic中觀看了我們的60k電話,降至〜5K。

GC也沒有收集,因爲它沒有達到我們的門檻。稍後可能會有潛在的GC優化 - 但目前我們的直接問題已得到解決。

我也接觸了Heroku的爲他們的想法,這是討論的內容:

在測功機內存使用情況將由Ruby VM的管理,並且很可能是你保持荷蘭國際集團太多密鑰重建期間內存中的信息。在數據添加redis之後,您應該考慮釋放用於生成鍵值的內存。

花時間修復您的N + 1查詢一定會有所幫助!