LoginSignup
5
6

More than 3 years have passed since last update.

Splashメモリ使いすぎ問題の回答(案)

Posted at

弊研究室のアドベントカレンダーまさか無事に終わるとは思っていませんでした。
今回ははSplashのメモリ問題について書きます。

結論

メモリ食いすぎたら勝手に落ちるから再起動

これは何か

以前にScrapyはいいぞぉって記事を書きました。しかしScrapyには一点問題があります。それは、当然のようにJavaScriptが動作しないことです。JavaScriptを使うページをScrapyでスクレイピングするときによく使うのがSplashというツールです。

Splashは、JavaScriptをレンダリングしてくれるサーバで、WebAPIを使ってアクセスすることで指定したサイトのJavaScript実行後のソースを取得することができます。中身はPythonで書かれていて、TwistedとQT3を使っているみたいです。

問題

そんな便利なSplashですが、1つ大きな問題があります。それは、メモリをめちゃくちゃ消費することです。
下の図は、Splashのメモリ消費量のグラフです。
Image from Gyazo
リクエストをすればするほど消費するメモリが増えていきます。この調子ではいくらメモリを積んでもあっという間になくなってしまいます。
Githubにも同様のIssueは立っていますが、Pythonの仕様でメモリを解放することができないみたいです。
https://github.com/scrapinghub/splash/issues/674

解決策

Pythonの問題は流石に手が打てません。もし知っている人がいたら教えてください。
上記のIssueにも書いてあるように、メモリを解放するには一回Splashを落とす以外に方法がありません。ただ、Splashを手動で落とすわけにはいかないので自動で落とす必要があります。cronとかで1分ごとに再起動みたいなスクリプトを書くのもアリですがめんどくさい。そんなときにどうすればいいか。

メモリ不足で落ちるまで待ちましょう。そして自動で再起動させましょう

あまり頭がいい解決策ではないですがこれが一番楽です。

どうするか

以下のような状況を対象にします。

  • SplashはDockerで動かしてる
  • docker-composeを使っている

まず、SplashのDockerコンテナが使えるメモリの上限を設定します。docker-composeはversion3からmem_limitがなくなってしまったので2を使います。
また、落ちた時に自動で再起動するようにrestart:alwaysをつけてあげます。

version: "2"
services: 
    splash:
        image: "scrapinghub/splash:3.3"
        ports: 
            - "8050:8050"
        mem_limit: 2g
        restart: always
        command: --disable-browser-caches --maxrss 4000

これでメモリを必要以上に食うことがなくなりました。

終わりに

途中でも言ったようにあまり頭のいい解決策ではないです。もっと賢く楽にできる方法があったら教えてください。

参考にしたサイト

5
6
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
5
6