Redashのメモリ使用量を節約する

IaaSが一般化してからメモリで悩むことは減りましたが、それでも無駄は減らしたいものです。

この記事ではRedashのメモリ使用量の節約について紹介します。

前提条件

以下の環境で検証しました。

コンテナのメモリ使用量確認にはctopを使用します。

github.com

検証準備

$ git clone git@github.com:getredash/redash.git
$ git checkout refs/tags/v3.0.0
$ docker-compose -f docker-compose.production.yml run --rm server create_db
$ docker-compose -f docker-compose.production.yml up

docker-compose.production.yml はRedashのバージョンを以下のように固定しました。

@@ -7,7 +7,7 @@
 version: '2'
 services:
   server:
-    image: redash/redash:latest
+    image: redash/redash:3.0.0.b3147
     command: server
     depends_on:
       - postgres
@@ -23,7 +23,7 @@ services:
       REDASH_WEB_WORKERS: 4
     restart: always
   worker:
-    image: redash/redash:latest
+    image: redash/redash:3.0.0.b3147
     command: scheduler
     environment:
       PYTHONUNBUFFERED: 0

デフォルトのメモリ使用量

ctop で確認します。

   NAME                     CID                      CPU                      MEM                      NET RX/TX                IO R/W                   PIDS

 ◉  redash_nginx_1           e99e574f0b9d                         0%                   1M / 1.95G       816B / 0B                0B / 0B                  2
 ◉  redash_postgres_1        7f190ff29476                         0%                  57M / 1.95G       24K / 14K                0B / 44M                 6
 ◉  redash_redis_1           7423c68518f1                         0%                   1M / 1.95G       26K / 24K                160K / 0B                3
 ◉  redash_server_1          0b2a249270f8                         0%                  348M / 1.95G      3K / 3K                  60K / 0B                 5
 ◉  redash_worker_1          87ee7979b2ad                         0%                  195M / 1.95G      22K / 21K                288K / 12K               4

server が約350MB、 worker が約200MBほどメモリを使用しています。他のコンテナについてはこの記事では扱いません。

ミドルウェアの設定でメモリ使用量を節約する

ミドルウェア周りで調整できそうなものを考えます

これらの設定はRedashの環境変数で変更できるので、以下のように docker-compose.production.yml を変更します。

@@ -7,7 +7,7 @@
 version: '2'
 services:
   server:
-    image: redash/redash:latest
+    image: redash/redash:3.0.0.b3147
     command: server
     depends_on:
       - postgres
@@ -20,10 +20,10 @@ services:
       REDASH_REDIS_URL: "redis://redis:6379/0"
       REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
       REDASH_COOKIE_SECRET: veryverysecret
-      REDASH_WEB_WORKERS: 4
+      REDASH_WEB_WORKERS: 1
     restart: always
   worker:
-    image: redash/redash:latest
+    image: redash/redash:3.0.0.b3147
     command: scheduler
     environment:
       PYTHONUNBUFFERED: 0
@@ -31,7 +31,7 @@ services:
       REDASH_REDIS_URL: "redis://redis:6379/0"
       REDASH_DATABASE_URL: "postgresql://postgres@postgres/postgres"
       QUEUES: "queries,scheduled_queries,celery"
-      WORKERS_COUNT: 2
+      WORKERS_COUNT: 1
     restart: always
   redis:
     image: redis:3.0-alpine

再度コンテナを作り直して、Redashを起動します。

$ docker-compose -f docker-compose.production.yml rm
$ docker-compose -f docker-compose.production.yml run --rm server create_db
$ docker-compose -f docker-compose.production.yml up

ctop で確認します。

   NAME                     CID                      CPU                      MEM                      NET RX/TX                IO R/W                   PIDS

 ◉  redash_nginx_1           a063c735099a                         0%                   1M / 1.95G       992B / 0B                0B / 0B                  2
 ◉  redash_postgres_1        26fdae3b9f2c                         0%                  59M / 1.95G       27K / 18K                0B / 44M                 7
 ◉  redash_redis_1           433f533a2bc3                         0%                   1M / 1.95G       52K / 43K                0B / 0B                  3
 ◉  redash_server_1          71fd4978d9a8                         0%                  101M / 1.95G      1K / 1K                  0B / 0B                  2
 ◉  redash_worker_1          dab363fafcab                         0%                  168M / 1.95G      45K / 51K                0B / 16K                 3

server が約100MB、 worker が約170MBほどメモリを使用しています。実用上どこまで詰めていいかは使いながら調整になりますが、ミドルウェアのプロセス数調整は効果がありそうです。

Redashの設定ファイルを変更してメモリ使用量を節約する

もうすこし切り詰めていきます。

Redashの設定はたいてい環境変数で変更可能ですが redash/settings.py のみで変更できるものもあるので、その設定を変更します。

データソースの種類を減らす

Redashの利点のひとつは、多くのデータソースに対応していることですが、どのデータソースを利用可能にするかは redash/settings.py に定義されています。

試しに、BigQuery、GoogleスプレッドシートMySQLPostgreSQLGoogle Analytics、Query Resultsだけを使用するように設定を変更します。

@@ -199,30 +199,11 @@ ACCESS_CONTROL_ALLOW_HEADERS = os.environ.get("REDASH_CORS_ACCESS_CONTROL_ALLOW_

 # Query Runners
 default_query_runners = [
-    'redash.query_runner.athena',
     'redash.query_runner.big_query',
     'redash.query_runner.google_spreadsheets',
-    'redash.query_runner.graphite',
-    'redash.query_runner.mongodb',
     'redash.query_runner.mysql',
     'redash.query_runner.pg',
-    'redash.query_runner.url',
-    'redash.query_runner.influx_db',
-    'redash.query_runner.elasticsearch',
-    'redash.query_runner.presto',
-    'redash.query_runner.hive_ds',
-    'redash.query_runner.impala_ds',
-    'redash.query_runner.vertica',
-    'redash.query_runner.clickhouse',
-    'redash.query_runner.treasuredata',
-    'redash.query_runner.sqlite',
-    'redash.query_runner.dynamodb_sql',
-    'redash.query_runner.mssql',
-    'redash.query_runner.memsql_ds',
-    'redash.query_runner.jql',
     'redash.query_runner.google_analytics',
-    'redash.query_runner.axibase_tsd',
-    'redash.query_runner.salesforce',
     'redash.query_runner.query_results'
 ]

再度コンテナを作り直し、設定をコンテナにコピーしてからRedashを起動します。

$ docker-compose -f docker-compose.production.yml rm
$ docker-compose -f docker-compose.production.yml create
$ docker cp redash/settings.py redash_worker_1:/app/redash/settings.py
$ docker cp redash/settings.py redash_server_1:/app/redash/settings.py
$ docker-compose -f docker-compose.production.yml run --rm server create_db
$ docker-compose -f docker-compose.production.yml up

ctop で確認します。

   NAME                   CID                    CPU                    MEM                    NET RX/TX              IO R/W                 PIDS

 ◉  redash_nginx_1         f821d84a023a                      0%                 1M / 1.95G      886B / 0B              0B / 0B                2
 ◉  redash_postgres_1      2270aa342a0c                      0%                57M / 1.95G      25K / 15K              0B / 43M               6
 ◉  redash_redis_1         1315adf2f232                      0%                 1M / 1.95G      29K / 26K              0B / 0B                3
 ◉  redash_server_1        53b407a5f23b                      0%                79M / 1.95G      1K / 1006B             0B / 0B                2
 ◉  redash_worker_1        6452b35d9227                      0%                132M / 1.95G     25K / 25K              0B / 12K               3

server が約80MB、 worker が約130MBほどメモリを使用しています。不要なデータソース対応を切り詰めるのもメモリ消費量節約に効果がありそうです。

プロセス数をデフォルトに戻す

データソース対応を減らした状態で、プロセス数はもとに戻してみます。

$ docker-compose -f docker-compose.production.yml rm
$ docker-compose -f docker-compose.production.yml create
$ docker cp redash/settings.py redash_worker_1:/app/redash/settings.py
$ docker cp redash/settings.py redash_server_1:/app/redash/settings.py
$ docker-compose -f docker-compose.production.yml run --rm server create_db
$ docker-compose -f docker-compose.production.yml up

ctop で確認します。

   NAME                   CID                    CPU                    MEM                    NET RX/TX              IO R/W                 PIDS

 ◉  redash_nginx_1         d76e0f2476be                      0%                 1M / 1.95G      816B / 0B              0B / 0B                2
 ◉  redash_postgres_1      808563ad0d67                      0%                57M / 1.95G      24K / 15K              0B / 43M               6
 ◉  redash_redis_1         91ebe6d65268                      0%                 1M / 1.95G      27K / 25K              0B / 0B                3
 ◉  redash_server_1        f0adc13795f5                      0%                269M / 1.95G     3K / 3K                0B / 0B                5
 ◉  redash_worker_1        bebaf0d04026                      0%                159M / 1.95G     23K / 22K              76K / 12K              4

server が約270MB、 worker が約160MBほどメモリを使用しています。

データソース対応を減らすだけでも、デフォルトと比較して server で約80MB、 worker で約40MBほどメモリ使用量を節約できました。

プロセス数などはRedashの利用状況にあわせてチューニングしなければいけない一方、データソース対応は比較的気軽に変更できることが多いので、Redashの導入や設定見直しの際は確認してみることをおすすめします。

まとめ

RedashはRaspberry Piでも動くという記事を書きましたが、メモリ使用量は少ないに越したことはありません。

節約できたぶんをGunicornやCeleryに割り当て、さらに快適にRedashを使うということもできると思います。