今すぐできる Redash の健康診断

Redash のトラブルシューティングをしていて、手癖のようなものがあることに気づいたので紹介しておきます。

前提

  • 利用している Redash は v8.0.0 の Self-hosted を想定
  • Redash のデータベースにアクセスできること
    • 文中では psql を使用していますが、Redash の postgres に接続できればクライアントは特に限定しません

その定期実行は本当に必要ですか?

無邪気に設定された定期実行がキューを詰まらせていることがあるかもしれません。

特に「毎分」実行になっているものがあったら要注意です。以下の SQL で定期実行の間隔が短いものを確認してみましょう。

もし、短い間隔で実行されているクエリーが見つかったら、そのクエリーを確認し、現在でも利用されているか?本当に定期実行が必要か?定期実行の間隔は適切か?を見直してみましょう。

select
    id
    , (schedule::json->>'interval')::INT as interval
    , created_at
    , updated_at
from
    queries
where
    is_archived=false
order by
    interval
limit 100
;

実行例

postgres=# select
postgres-#     id
postgres-#     , (schedule::json->>'interval')::INT as interval
postgres-#     , created_at
postgres-#     , updated_at
postgres-# from
postgres-#     queries
postgres-# where
postgres-#     is_archived=false
postgres-# order by
postgres-#     interval
postgres-# limit 100
postgres-# ;
 id | interval |          created_at           |          updated_at           
----+----------+-------------------------------+-------------------------------
  4 |       60 | 2021-03-02 13:33:40.378489+00 | 2021-03-02 13:33:59.178892+00
  2 |      600 | 2021-02-11 04:15:33.374336+00 | 2021-03-02 13:34:08.125934+00
(2 rows)

重いクエリーを見落としていませんか?

Redash の活用が進むにつれて、作成当時はすぐに結果が返っていたクエリーも、時間が経ってデータ量が増えていたり、データの構造が変わって想定を超えるデータ量を扱うことになってしまっているという状況もありえます。

以下の SQL で、実行に時間がかかっているものを確認してみましょう。

実行に時間がかかっているクエリーが見つかった場合、SQL のチューニング、データのパーティショニング、データソース側のスケールアップなど、データソースや対象のデータの特性によっても扱いは変わりますが、実行時間を短くできるか検討してみましょう。

select
    qr.id
    , qr.query_hash
    , qr.runtime
    , qr.retrieved_at
    , q.id query_id
from
    query_results qr
left join
    queries q on qr.query_hash = q.query_hash or qr.id
order by
    qr.runtime desc
limit 100
;

実行例

postgres=# select
    qr.id
    , qr.query_hash
    , qr.runtime
    , qr.retrieved_at
    , q.id query_id
from
    query_results qr
left join
    queries q on qr.query_hash = q.query_hash
order by
    qr.runtime desc
limit 100
;
 id |            query_hash            |       runtime        |         retrieved_at          | query_id 
----+----------------------------------+----------------------+-------------------------------+----------
 39 | 5a6ac618d80fde285f76b0fda8138395 |  0.00146913528442383 | 2021-03-02 14:02:46.552977+00 |         
 35 | e1d51032e9f9e91e5bf3c94e87491fc6 |  0.00141096115112305 | 2021-03-02 13:59:57.11131+00  |         
 33 | 9c021c8d73b6c64005b2d748b40c758b |  0.00129294395446777 | 2021-03-02 13:59:44.440632+00 |         
...省略...
 48 | 7830e05b1c1fe5cfde05865bb3837e86 | 0.000459909439086914 | 2021-03-02 14:06:20.15143+00  |        4
 36 | 7830e05b1c1fe5cfde05865bb3837e86 |  0.00043177604675293 | 2021-03-02 14:00:20.126168+00 |        4
 18 | 7830e05b1c1fe5cfde05865bb3837e86 | 0.000409841537475586 | 2021-03-02 13:40:19.92023+00  |        4
(38 rows)

上記の実行例では重いクエリーは見受けられませんが、runtime の値が大きなクエリー結果は注意してみましょう。どの程度を「大きい」と捉えるかは、利用しているデータソースや扱うデータ量などによっても異なるので、適宜判断してください。

クエリーパラメータを使用していない場合は query_hash で該当のクエリーの ID を突き止めることができますが、それができない場合はクエリー結果の id を使って実行されたクエリーを特定し、実行されたクエリーの部分文字列を使って該当のクエリーを探すことになります。

postgres=# select query from query_results where id = 39;
         query         
-----------------------
 select 1 hello;
(1 row)

postgres=# select id from queries where query like '%select 1 hello;%';
 id 
----
  6
(1 row)

キューが詰まったときの対応についておすすめの記事

qiita.com