2019年末版: Redash のメモリ使用量を節約する

まえがき

約2年前にこんな記事を書きました。

ariarijp.hatenablog.com

最近、Twitter で趣味の Redash エゴサをしていると、メモリ使用量でお悩みの方がいるようだったので、2019/12/20 現在で Redash のメモリ節約にチャレンジしてみます。

サクッといきます。

環境

先日公開した以下の記事の手順に沿って Vagrant 上で環境構築しました。

ariarijp.hatenablog.com

コンテナのリソース確認のため、 ctop も使います。

github.com

節約前

ctop コマンドで見るとこんな感じ。

f:id:ariarijp:20191220232537p:plain

ざっくり Redash のコンテナ群だけで1.2 GB 前後といったところでしょうか。

(注)PostgreSQL のメモリ使用量については、この記事ではいっさい触れません。

節約後

f:id:ariarijp:20191220232728p:plain

起動しているコンテナ自体が減っていることもありますが、全体で300MBほど。メモリ使用量だけでいえば 1/4 程度に収まりました。

何をやったか

サービス、プロセスを減らす

docker-compose.yml をいろいろ書き換えました。詳しくは diff を見てみましょう。

@@ -13,25 +13,13 @@
     ports:
       - "5000:5000"
     environment:
-      REDASH_WEB_WORKERS: 4
-  scheduler:
+      REDASH_WEB_WORKERS: 1
+  worker:
     <<: *redash-service
     command: scheduler
     environment:
-      QUEUES: "celery"
+      QUEUES: "celery,scheduled_queries,schemas,queries"
       WORKERS_COUNT: 1
-  scheduled_worker:
-    <<: *redash-service
-    command: worker
-    environment:
-      QUEUES: "scheduled_queries,schemas"
-      WORKERS_COUNT: 1
-  adhoc_worker:
-    <<: *redash-service
-    command: worker
-    environment:
-      QUEUES: "queries"
-      WORKERS_COUNT: 2
   redis:
     image: redis:5.0-alpine
     restart: always

Web のワーカーを減らす

性能度外視で節約を目的にするので、プロセス数を1にします

Celery のワーカーをまとめて減らす

デフォルトでは Celery の管理、スケジュール実行、アドホック実行と、3つのサービスにわかれていますが、それをひとつのサービスにまとめます。

ひとつのサービスに詰め込むことになるので、サービス名を worker としています。さらにワーカーのプロセス数も減らして 1 にします。

もちろん、キューが処理されるのは遅くなりますが、これも節約のためです。

使用しないクエリランナーを無効にする

Redash は多くのデータソースに対応している反面、依存パッケージも多く、それらの読み込みによってメモリが多く消費されるようです。

今回の検証では、PostgreSQLMySQLSQLite、BigQuery 以外は無効にするため、以下の設定を /opt/redash/env に追加しました。

REDASH_DISABLED_QUERY_RUNNERS=redash.query_runner.athena,redash.query_runner.google_spreadsheets,redash.query_runner.graphite,redash.query_runner.mongodb,redash.query_runner.couchbase,redash.query_runner.url,redash.query_runner.influx_db,redash.query_runner.elasticsearch,redash.query_runner.amazon_elasticsearch,redash.query_runner.presto,redash.query_runner.databricks,redash.query_runner.hive_ds,redash.query_runner.impala_ds,redash.query_runner.vertica,redash.query_runner.clickhouse,redash.query_runner.yandex_metrica,redash.query_runner.rockset,redash.query_runner.treasuredata,redash.query_runner.dynamodb_sql,redash.query_runner.mssql,redash.query_runner.memsql_ds,redash.query_runner.mapd,redash.query_runner.jql,redash.query_runner.google_analytics,redash.query_runner.axibase_tsd,redash.query_runner.salesforce,redash.query_runner.prometheus,redash.query_runner.qubole,redash.query_runner.db2,redash.query_runner.druid,redash.query_runner.kylin,redash.query_runner.drill,redash.query_runner.uptycs,redash.query_runner.snowflake,redash.query_runner.phoenix,redash.query_runner.json_ds,redash.query_runner.cass,redash.query_runner.dgraph,redash.query_runner.azure_kusto

まとめ

とにかくメモリ使用量を減らすことに集中すると、設定を変えるだけでかなり多くのメモリを節約できます。実用性はともかく、ここまでやれば AWS EC2 の t3.micro 相当でもなんとか動かせるのではないかなと思います。

この記事で紹介した設定はあくまでメモリ使用量節約のデモであり、そのまま使うことはおすすめできませんが、使っていないデータソースの精査だけでも効果が大きいというのを以前の記事でもご紹介していますので、まずはそこから手を付けてみるのが良いと思います。

この記事が Redash の運用でお困りのかたの役に立つとうれしいです。

Redash v8.0.0 の環境を構築する3行のコマンド

まえがき

フォーラムで質問いただいたので、2019/12時点でサクッと環境構築できる方法を確かめてみました。

使用しているバージョンは記事執筆時点で最新の安定版リリースである v8.0.0AWS を使用していない方も多くいらっしゃると思いますので、Vagrant で立ち上げた VM で検証しました。

使用した Vagrantfile はこちら。 Redash の公式ドキュメントにあわせて、スペックは AWS EC2 の t2.small を意識しています

Vagrant.configure("2") do |config|
  config.vm.box = "ubuntu/bionic64"
  config.vm.network "forwarded_port", guest: 80, host: 8080

  config.vm.provider "virtualbox" do |vb|
    vb.cpus = 1
    vb.memory = 2048
  end
end

手順

まっさらな Ubuntu 18.04 で以下を実行します。

$ export REDASH_BRANCH=v8.0.0
$ wget https://raw.githubusercontent.com/getredash/redash/${REDASH_BRANCH}/setup/setup.sh
$ sudo -E bash ./setup.sh

Docker イメージの pull に時間がかかりますが、ネットワーク環境がよければ5分ほどでインストールが完了します

確認

先述の Vagrantfile で VM で起動していれば、 http://localhost:8080/ にアクセスすると Redash の画面が確認できます。

f:id:ariarijp:20191219003243p:plain

ユーザー名など必要な情報を登録して、トップページを表示、右上のメニューをクリックして、v8.0.0 がインストールされていることを確認しました。

f:id:ariarijp:20191219003346p:plain

まとめ

Redash はバージョンによって導入の仕方が変わることがあり、初心者ユーザーにとっては優しくない一面もありますが、基本的には簡単に導入ができます。

この記事をきっかけに、ひとりでも多く Redash に触れてみようと思ってもらえると嬉しいです。

使われていない、を知る

この記事について

既存の仕組みを「捨てる」というのは得てして影響が大きく、それを実行するには準備と勇気がいる。

builderscon 2019 で聴講した fujiwara さんの「レガシーサーバーを現代の技術で再構築する」の質疑応答で「再構築にあたり、使われていないものを捨てるときにどのように"使われていない"ことを確認するのか」質問させていただいたことを期に、日頃考えていたり、過去に経験したりといったことを書き出してみたくなった。

builderscon.io

セッションの内容は大変すばらしいものだったので、ぜひスライドや動画を見ていただきたい。スライドのリンクを見つけられなかったので、セッション詳細のページを紹介しておく。

builderscon.io

あまりまとまりがないものになるが、個人のメモだと思ってご容赦いただきたい。

前提

この記事では、主に会社や部署など特定の組織内で利用されているもの。特に Web アプリケーションを対象に扱い、BtoC など組織外の利用者がいるケースは想定していない。

また、以降は対象のアプリケーションや仕組みのことを簡便のために「システム」と呼ぶことにする。

「使われていない」ことを知るために

使われていないという状態は、どのように知ることができるだろう。

現時点で思いつく限りを列挙してみる。

  • アクセスログやデータの作成・更新日時から知る
  • 運用マニュアルなどが存在する場合は、そのドキュメントを参照する
  • 利用者が特定できる場合は、ヒアリングをする
  • 利用者にアンケートを取る
  • 計画的に対象を停止し、利用者からの反応を見る

アクセスログやデータの作成・更新日時から知る

アクセスログやデータから利用情報を知るというのは、ごく一般的かつ、信頼性の高い方法だと思う。

Web アプリケーションという前提においては、期間はさておき何らかの形でアクセスログは残る。

また、データベースやファイルシステムに保存されたデータの量や更新日時などから、どれぐらい回数や量、どの程度の頻度で利用されているかを掴むことができると。

運用マニュアルなどが存在する場合は、そのドキュメントを参照する

特定の組織内で利用するシステムには、マニュアルや業務フローなどのドキュメント類が整備・定義されていることも多い。

それらの情報に触れることができる場合は、ドキュメントから利用シーン、利用頻度などを読み解くこともできる。

ただし、こういったドキュメント類は「使われていない=メンテナンスされない」となるケースも多く、現在そのドキュメントが取り扱うシステムが使われているかどうかの判断材料にはならないことが多いように思う。

利用者が特定できる場合は、ヒアリングをする

組織内でも特定の部署や担当者が利用するシステムで、それが明らかな場合は、ヒアリングを行うことも有用だ。

対象のシステムが扱う業務ドメインについても豊富な知識を持つ担当者にヒアリングができれば、システムがどのように使われているか、またはいつから使われなくなったか、なぜ使われなくなったかなど、前述のふたつの方法では知ることのできない情報を得ることができることが多い。

しかし、相手は人間になるので、ヒアリングをしてもその場で思い出せなかった、言いそびれてしまった、忘れてしまったということは簡単に起こりうるので、前述の方法で得た情報とあわせてヒアリング内容を精査したほうがよい。

利用者にアンケートを取る

組織内でも不特定。というには大げさだが、組織横断的に利用されているシステムでは、利用者が定まらないようなケースもある。

その場合、何らかの方法でアンケートを取ったり、意見を求めたりすることも利用状況を知る方法となる。

これによって、今まで知りえなかったような情報を想定外の利用者から提供してもらえることなどが期待できるが、アンケートのような手法を取ると、アンケートの設問の設計、回収率などの頭を抱えることになるかもしれない。

計画的に対象を停止し、利用者からの反応を見る

これは当日の質問でも登壇者や参加者、質問者である私も思わず笑ってしまった方法ではあるが、現実においてはあながちトンデモな方法と言えなくもないし、むしろ実践的とも言える側面もあると思う。

前述のどのような方法をとっても、実際にシステムを止めてみないとそれが使われているかどうかを真に知ることは難しい。

ただし、この方法は業務フローに大きな影響を与えてしまう可能性を含んでいるため、計画や実施を慎重におこの合う必要がある。

たとえば、以下のような段階を考えることができる。

  • システムの一時停止を告知し、そのスケジュールにあわせてシステムを停止する
  • システムの一時停止を告知せず、システムを短期間停止する

各段階のいずれにおいても、ロールバック(再開)の手順は必ず用意しておく。

また、実施する時間帯は業務にあわせて計画する。

早朝や休日など明らかに利用者が居ない時間帯や日程で実行しても得られる情報は少なくなるし、かといって月末、月初、期末の多忙な時期にシステムの停止をすると、リカバリーが難しい規模の業務停止を引き起こしてしまう可能性もある。

まとめ

個人の経験からいくつかの例を挙げつつ、それぞれの方法について意見を書いてみた。

ここで挙げられなかった方法や、こんな方法を取ったことがある。などがあれば、どんな形でもいいので教えてほしい。

この記事が、誰かにとっての Discover Something New になっていたら嬉しい。

f:id:ariarijp:20190831145157j:plain

あとがき

この記事は builderscon 2019 会場近くのイタリアントマトで書きました。

参加者にランチを提供していただいた、さくらインターネットさん、ごちそうさまでした。

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.ymlserver サービス内、 environment に追加した。

GUNICORN_CMD_ARGS: "--timeout 90"

90秒という設定は適当。

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

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

まとめ

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

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

Mackerel アンバサダーになりました

f:id:ariarijp:20190406094516p:plain

アンバサダープログラムについては以下の記事に詳しく書いてあります。

mackerel.io

Mackerel 関連の活動ふりかえり

アンバサダーに選出していただいたので、これまでの活動をざっくり振り返ってみました。

プラグイン開発への参加

github.com

Mackerel はエージェントやプラグインOSS として公開していますが、私も以下のプラグインの開発に微力ながら参加しました。

個人の OSS

個人的にもいくつか Mackerel 関連の OSS を公開しています。実装が中途半端なものも多いですが、以下の2つはそれなりに使える状態になっていると思います。

ブログなどでの記事公開

改めて振り返ってみると。意外といろいろ書いていました。

イベントでの LT 登壇

参加者としては以下のイベント意外にも参加したことがありますが、2度ほど LT 枠で登壇したこともありました。

今後の活動について

アンバサダーになったからといって、変に気負って Mackerel 関連の活動をすることは無いと思いますが、Mackerel は気に入っているプロダクトのひとつなので、今後もなんらかの形でコミュニティやエコシステムに関わりたいと思っています。

Happy Monitoring !!