Redash で 502 Bad Gateway が発生したときに見直すべき Gunicorn のタイムアウト

業務で使い倒している Redash で、あるクエリーの結果をダウンロードすると、「502 Bad Gateway」が発生していたので調査・対応したメモ

発生していた現象

行数約28,000行、列数約70の結果を返すクエリーを Excel ダウンロードしようとすると nginx の 「502 Bad Gateway」エラーが発生しファイルがダウンロードできない。条件を絞って取得行数を減らすとダウンロードできる。

調査

nginx のエラーログには以下のようなメッセージが記録されていた。

... upstream prematurely closed connection while reading response header from upstream, client: xxx.xxx.xxx.xxx ...

また、server コンテナのログには、ワーカーがタイムアウトしたようなログが記録されていた(詳細は割愛)

ここでの「ワーカー」は Celery 上で動く Redash のワーカーではなく、Redash がアプリケーションサーバーとして使用している Gunicorn のワーカーのこと。

対応

エラーログから Gunicorn がタイムアウトしていると推測し、設定を調査した。

結果として、タイムアウトのオプションがあり、それはデフォルトで 30 秒になっていることがわかった。

docs.gunicorn.org

また、Gunicorn のオプションはコマンドライン引数として与える以外にも、以下のように環境変数で渡すことができる。

$ GUNICORN_CMD_ARGS="--bind=127.0.0.1 --workers=3" gunicorn app:app

Redash は現在 Docker 環境を推奨しているため、コマンドラインオプションの変更ははイメージの再構築が必要になってしまい、相性が悪い。

その点、GUNICORN_CMD_ARGS 環境変数を使えば docker-compose.yml の変更のみでオプションを適用できる。

これらを踏まえて、以下の設定を docker-compose.yml の server サービス内、 environment に追加した。

GUNICORN_CMD_ARGS: "--timeout 90"

90秒という設定は適当。

docker-compose.yml を編集後、docker-compose down、docker-compose up -d でコンテナを再起動。

エラーが出ていたクエリをブラウザで表示し、クエリー結果を Excel ダウンロードしたところ、ダウンロード成功。

まとめ

Redash でファイルダウンロード時に 502 エラーが発生した際は、Gunicorn のタイムアウトを見直すことで解決することがある。

この記事では Docker 環境で動作している Redash を扱っているが、レガシー(Ubuntu に直接導入)セットアップでも似たような対応ができるはず。