Redash のクエリ結果がクリーンアップされる仕組み

この記事は Redash Advent Calendar 2018 20日目の記事です。

adventar.org

お題

discuss.redash.io

フォーラムでクエリ結果を使ってごにょごにょされている方の投稿がありました。

私もコメントしてみましたが、Redash のクエリ結果はあるルールで定期的に削除されています。

この記事では、その動きを追ってみようと思います。使用するバージョンは v6.0.0 ブランチです。

動きを追ってみる

server と worker

まず、Redash は大きく server(Flask) と worker(Celery) のプロセスがあります。

クエリ結果を削除する仕組みは worker 側で実行されています。

worker が実行される仕組み

Redash の worker プロセスは Celery を使って実行されます。

エントリポイントは redash/worker.py になっています。

クエリ結果が削除される仕組み。

redash/worker.py 中の以下のコードがクエリ結果の削除に大きく影響します。

if settings.QUERY_RESULTS_CLEANUP_ENABLED:
    celery_schedule['cleanup_query_results'] = {
        'task': 'redash.tasks.cleanup_query_results',
        'schedule': timedelta(minutes=5)
    }

Redash は環境変数でいろいろな設定を変更できるようになっており、 QUERY_RESULTS_CLEANUP_ENABLED もその設定のひとつです。

文字通り、クエリ結果をクリーンアップするかどうかをこの環境変数で決定しており、デフォルトは True になっています。

この設定が有効になっていると、redash/tasks/queries.pycleanup_query_results が5分に1度実行されます。

@celery.task(name="redash.tasks.cleanup_query_results")
def cleanup_query_results():
    """
    Job to cleanup unused query results -- such that no query links to them anymore, and older than
    settings.QUERY_RESULTS_MAX_AGE (a week by default, so it's less likely to be open in someone's browser and be used).
    Each time the job deletes only settings.QUERY_RESULTS_CLEANUP_COUNT (100 by default) query results so it won't choke
    the database in case of many such results.
    """

    logging.info("Running query results clean up (removing maximum of %d unused results, that are %d days old or more)",
                 settings.QUERY_RESULTS_CLEANUP_COUNT, settings.QUERY_RESULTS_CLEANUP_MAX_AGE)

    unused_query_results = models.QueryResult.unused(settings.QUERY_RESULTS_CLEANUP_MAX_AGE).limit(settings.QUERY_RESULTS_CLEANUP_COUNT)
    deleted_count = models.QueryResult.query.filter(
        models.QueryResult.id.in_(unused_query_results.subquery())
    ).delete(synchronize_session=False)
    models.db.session.commit()
    logger.info("Deleted %d unused query results.", deleted_count)

ここで QUERY_RESULTS_CLEANUP_MAX_AGE に指定された日数(デフォルトは 7 日) 以上前に実行されたクエリ結果を QUERY_RESULTS_CLEANUP_COUNT に指定された件数(デフォルトは 100)削除されます。

利用の仕方によってはクエリ結果が大きくなってしまい、ディスクなどのリソースを圧迫してしまうことがあるため、実行済みのクエリ結果を多用しない場合は QUERY_RESULTS_CLEANUP_MAX_AGE を適切に調整するのをおすすめします。

私が業務で運用している Redash インスタンスはクエリパラメータを多用していたり、毎時結果が変わるような特性のデータを扱っていることもあるため、 QUERY_RESULTS_CLEANUP_MAX_AGE3 に設定しています。

この記事で紹介した環境変数以外にもいろいろな項目が設定できるので、以下の記事もぜひ読んでみてください。

qiita.com

まとめ

クエリ結果が削除される仕組みについて改めて調べてみました。

クエリ結果が大きくなるようなクエリを多く運用されている方でこれらの設定を見直したことがないという方がいたら。一度見直してみると良いと思います。

明日は y-tomoyasu さんによる「Python Data Sourceの利用ケースについてなにか」です。

y-tomoyasu さんは Redash Meetup 4.0.2-dev でも少しお話を伺いましたが、Python データソースをガッツリ使われているようです!お楽しみに!