2017-02-03 31 views
0

ヘロクのCeleryの下でバックグラウンドタスクを実行していると、「Error R14(Memory quota exceeded)」が頻繁に「Error R15(Memory quota exceeded)」になることがあります。データベースからたくさんのものを(PostgresのDjango経由で)ロードしていますが、大きなオブジェクトをロードして処理し、次に参照を破棄して次の大きなオブジェクトをロードする必要があります。Herokuがメモリクォータを大幅に超過したことを警告すると、Pythonガベージコレクトは実行されますか(R15)?

私の質問は、Herokuのメモリ制限を打つ前にガベージコレクタが実行することを知っていますか?手動でgcを実行する必要がありますか?

もう1つのことは、自分のタスクが失敗することがあり、セロリが自動的に再試行して成功することです。それは決定論的でなければなりません。私は、タスクが完了した後に何かがメモリにぶら下がっているのだろうと思っていて、次のタスクが始まるときにまだスペースを取っています。ワーカープロセスを再起動すると、メモリがクリアされ、成功します。たぶんDjangoまたはDBにはクリアされていないキャッシュがいくつかありますか?

私は標準2倍のサイズを使用しています。私はパフォーマンスやパフォーマンスに行くことができましたが、それを避けようとすればより多くの費用がかかるでしょう。

+1

私は、pythonプロセスがメモリクォータについて知っているのではないかと疑うので、ガベージコレクタを実行しないと思います。いずれにしても、手作業によるガベージコレクションは、大量のメモリを解放することができる少数のエッジケースでのみ有効ですが、自動収集のしきい値はヒットしません。あなたが単純に大量のメモリを使用している可能性が高くなります。この場合、ガベージコレクションは何もクリーンアップできません。 – knbk

+0

オブジェクトをフェッチしているワーカーコードを貼り付けることはできますか?ここに問題がある可能性があります。おそらく、発電機を使用していないか、あまりにも熱心に物を積載していません。 Herokuのメモリエラーは、(ディスク上の)スワップメモリ​​の使用を開始することを意味します。これは非常に遅いです。最終的に、スワップとしてメモリを1.5倍にすると、Herokuはプロセスを再開し、セロリはすべてのジョブを再試行します。 – rdegges

答えて

0

問題のように見えますが、私は.iterator()をメインクエリーセットで反復処理していません。私が各反復の後に作成しているデータ構造を解放しても、実際のクエリ結果はすべてキャッシュされます。

prefetch_relatedを広く使用しているため、残念ながら.iterator()は使用できません。

私はある種のハイブリッド方法が必要です。トップレベルのクエリーセットをバッチ処理することになると思います。 prefetch_relatedが持つ有限数のクエリの利点は完全にはありませんが、モデルオブジェクトごとに1つのクエリよりも優れています。

関連する問題