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 データソースをガッツリ使われているようです!お楽しみに!

Redash v6 で追加されたオートコンプリートの無効化について挙動とコードを追ってみる

この記事は Redash Advent Calendar 19日目の記事です。勤務先でも師走ムードを感じ始めました。

adventar.org

お題

この問題と関係あるかどうかはわかりませんが、オートコンプリートと聞いて、先日リリースされた Redash v6 (正確には 6.0.0-beta から追加)で以下の機能が追加されたことを思い出しました。

If the live autocomplete in the code editor annoys you, you can disable it now

今日はこの機能について検証しつつ、ざっくりと実装を追ってみます。

検証環境は docker-compose で起動し、Docker イメージは redash/redash:6.0.0.b8537 を使用しました。

影響範囲

この機能はクエリ編集画面に影響があります。

以下はオートコンプリートを無効にする前の画面で、今までのバージョンと同じくオートコンプリートが有効になっています。

f:id:ariarijp:20181218134613p:plain

上記の画面で表示されている、雷のマークがオートコンプリートの有効・無効を切り替えるトグルになっていて、無効にすると静止画ではわかりにくいですが、以下の画面のようにオートコンプリートが効かなくなります。

f:id:ariarijp:20181218135022p:plain

オートコンプリートの設定はどこに保持されているか?

Chrome の開発者ツールなどで見るとすぐに分かりますが、LocalStorage に保持されています。

f:id:ariarijp:20181218135316p:plain

liveAutocompleteDisabledfalse だとオートコンプリートが有効になるようです。

オートコンプリートを制御しているのはどのコードか?

client/app/components/QueryEditor.jsxliveAutocompleteDisabled を操作しています。

redash/QueryEditor.jsx at v6.0.0 · getredash/redash · GitHub

Redash は現在 Angular から React への移行を進めていて、クエリエディタ周りも v6.0.0 時点では React のコンポーネントに書き換わっています。

このコンポーネントのなかでオートコンプリートのボタンがクリックされるたび、コンポーネントの State と一緒にブラウザの Local Storage を書き換えているようです。

toggleAutocomplete で呼ばれている localOptions.set は Redash 独自のもので、Web Storage API を薄くラップしたもののようでした。

redash/localOptions.js at v6.0.0 · getredash/redash · GitHub

まとめ

まとめと書きつつ、これといったまとめはありませんが、オートコンプリート周りの実装を読んだことで、また少し Redash についての理解が深まりました。

それも元ツイートのおかげなので、ありがたい限りです。

お知らせ

Redash についての疑問などを Twitter で拾えることもあるのですが、できればフォーラムへの投稿をしていただけるとありがたいです!日本語でOK!

discuss.redash.io

30行ぐらいで Redash のクエリ実行結果を Google スプレッドシートに書き込むサンプルコード

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

adventar.org

タイトルの通り、Redash の利用事例で話されることが多く、私も活用している Redash と Google スプレッドシートの連携について、Python のサンプルコードを公開してみます。

使うもの

主に以下のパッケージを利用します。

github.com

github.com

github.com

github.com

サンプルコード

GitHub で公開しました。

github.com

正確には 27行です。行数を削るために少し苦しい書き方になっている部分はご了承ください。

動かし方

まずは venv で環境構築します。

$ python3 -m venv .venv
$ source .venv/bin/activate
$ pip install -r requirements.txt

Google のサービスアカウントを使用して API にアクセスします(この記事ではサービスアカウントの作成などについては割愛します)

サービスアカウントの JSON 鍵ファイルを環境変数で指定します。

$ export CLIENT_SECRET_FILE="/path/to/json/key/credential.json"

Redash のユーザー API キーも同様に環境変数で指定します。

このサンプルコードでは、Redash のデモサイトを使用していますが、お使いの環境にあわせてサンプルコードの URL を変更してください。

$ export REDASH_API_KEY="YOUR_REDASH_USER_API_KEY"

最後に、 main.py を編集します。

                         spreadsheet_id="スプレッドシートID",
                         spreadsheet_range="シート1!A1",

スプレッドシート ID と書き込み先の範囲を指定します。

書き込み対象のスプレッドシートには、サービスアカウントから書き込み可能な権限を付与してください。

デモサイトを使用しない場合は、以下のコードを書き換えて使用したいクエリ ID を指定してください。

    df = query_to_df(redash, 1)

以下のようにパラメータを使用することもできます。

    df = query_to_df(redash, 123, {'foo': 1, 'bar': 2})

実行してみる

準備ができたら実行してみましょう。

$ python main.py

f:id:ariarijp:20181214204422p:plain

実行が完了すると、上記のようにスプレッドシートの指定した範囲に結果が書き出されるはずです。

まとめ

Redash とスプレッドシートを簡単に連携されることができました。

まだスプレッドシート連携までは手が出せていない。というかたは、よろしければ試してみてください。

明日の Redash Advent Calendar は Redash のメンテナーでもある deecay さんによる「2018年の活動振り返り」です!お楽しみに!

Redash のアラート通知先を独自拡張する

この記事は Redash Advent Calendar 13日目の記事です。折返し地点ですね!

adventar.org

きっかけ

このツイートを見てやってみようと思いました。

やりかた

コードをパッケージ化する

redash/destinations に置いているコードを以下のような感じにパッケージ化します。

github.com

必ずしも GitHub や Git を使わなくてもよいのですが、今回は説明を省きたいのでこれで進めます。

この記事の本題にはたいして関係ありませんが、この Destination はアラートを JSONL 形式でログファイルに書き出す。というものにしてみました。

Redash の requirements.txt を変更する

アラート通知のパッケージを requirements.txt に追加します。

-e git+https://github.com/ariarijp/redash-json-logger-destination.git#egg=redash-json-logger-destination-0.1.0

Redash の docker-compose.yml を変更する

検証には Docker を使用するので、docker-compose.ymlserverworkerenvironment に以下を追加します。

REDASH_ADDITIONAL_DESTINATIONS: "redash_json_logger_destination"

この REDASH_ADDITIONAL_DESTINATIONS 環境変数で、アラート通知先を追加することができます。

追加したいものが複数ある場合はカンマ区切りで設定できます。

ビルドする

requirements.txt の変更を反映したイメージをビルドします。

これにはかなり時間がかかるので気長に待ちましょう。

$ docker-compose build

起動してみる

これで準備は完了です。起動してみましょう。

$ docker-compose run --rm server create_db
$ docker-compose up -d

管理者ユーザーの追加などの設定は割愛します。

設定画面を見ると、アラートの通知先が追加されています。

f:id:ariarijp:20181213203749p:plain

f:id:ariarijp:20181213203907p:plain

まとめ

この手順は、去年書いたクエリランナーを追加するという記事とほとんど同じだったりします。

ariarijp.hatenablog.com

今朝、先のツイートを見るまでやってみようと思ったことがなかったのですが、結果として同じようにできたのでよかったです。

Redash v6 でクエリの読み込みが早くなる?

Redash Advent Calendar 12日目の記事です。

adventar.org

v6 のベータ版リリースに気になる一文が

先日 v6 のベータ版がリリースされました🎉

discuss.redash.io

新データソースの対応、既存のデータソースの改善、今までは毎回クエリを発行していた Query Results データソースでキャッシュが使えるようになるなど、多くの変更が含まれていますが、そのなかで気になるものがありました。

Fast queries will now load faster.

気になりますね。私は気になりました。

調べてみる

ここ最近の変更を追いかけてみたところ、以下の PR を見つけました。

github.com

仕組みはかんたんで、Redash ではクエリを実行するとジョブが発行され、そのジョブをポーリングするのですが、最初の10回は0.5秒間隔、その後は3秒間隔でポーリングすることで、すぐ実行が完了するようなクエリであれば今までより画面に結果が現れるまでの時間が短くなる。というものでした。

まとめ

シンプルなクエリであったり、Query Results でキャッシュを使うケースにおいては体感がかなり変わってきそうですね。

ちょっとした変更ですが、副作用も少なくユーザーにはうれしい変更だなと思いました。