Location via proxy:   [ UP ]  
[Report a bug]   [Manage cookies]                

every Tech Blog

株式会社エブリーのTech Blogです。

Redashをv25.1.0にアップグレードする

はじめに

こんにちは。
株式会社エブリーの開発本部データ&AIチーム(DAI)でデータエンジニアをしている吉田です。

今回は、Redashのアップグレードについてのお話です。

背景

デリッシュキッチンではデータ分析のための可視化ツールとしてRedashを利用しており、ECS上にRedashをデプロイして運用しています。
RedashはOSS版の更新が長らく停止していましたが、昨年プロジェクトが再始動され(参考)、先日v25.1.0がリリースされました。

今回、Redash v10.0.0 から v25.1.0 へのアップグレード試験を実施しました。

現在のRedashの運用状況については、以下の記事で詳しく解説しています。
https://tech.every.tv/entry/2024/03/06/160148

アップグレード手順

v10.0.0 から v25.1.0 へのアップグレードは、v10.1.0 を経由する必要があります。
v10.0.0 から v10.1.0 はイメージの差し替えのみで、DBマイグレーションは不要です。
v10.1.0 から v25.1.0 はDBマイグレーションが必要です。

具体的な手順は以下の通りです。

  1. 事前準備
    1. Redash v25.1.0でビルドしたDockerイメージをECRに登録します
    2. マイグレーションタスク用のECSタスク定義とサービス定義を作成します
    3. Redash DBのバックアップを作成します
  2. 作業
    1. 古いRedashコンテナを停止します
    2. マイグレーションタスクを実行します
    3. 新しいRedashコンテナを起動します
  3. 確認
    1. Redashにログインし、データが正常に表示されることを確認します

マイグレーションタスクの作成

Redashのデプロイにはecspressoを利用しており、ecspresso runコマンドでマイグレーションタスクを実行できるようにマイグレーション用定義ファイルを作成します。
タスク定義ファイルは以下のように作成します。(一部抜粋)

{
  "family": "redash-migration",
  "containerDefinitions": [
    {
      "name": "redash-migrate",
      "image": "ECR/Custom-Redash:25.1.0",
      "command": [
        "manage", "db", "upgrade"
      ]
    }
  ]
}

手順2.1で古いRedashコンテナを停止した後、ecspresso run --wait-until stoppedのようなコマンドを実行することで、マイグレーションタスクを実行できます。
このとき、ある程度の時間がかかるのでecspressoのタイムアウト設定を適切に行う必要があります。

ハマりどころ

v10.1.0からv25.1.0へのアップグレードにおいて、以下のようなハマりどころがありました。

エラーDETAIL: \u0000 cannot be converted to text.が発生する

マイグレーションタスクを実行中に、"change type of json fields from varchar to jsond" ステップで以下のエラーが発生しました。
DETAIL: \u0000 cannot be converted to text.

これはIssueでも報告されており、以下のSQLを実行することで対応できます。

UPDATE visualizations
SET options = replace(options::text, '\u0000', '')::json
WHERE strpos(options::text, '\u0000') > 0;

エラーTypeError: 'NoneType' object is not iterableが発生する

マイグレーションタスクを実行中に、"fix_hash"ステップで、以下のエラーが発生しました。(一部抜粋)

2025/02/12 14:38:32   File "/app/migrations/env.py", line 85, in run_migrations_online
2025/02/12 14:38:32     context.run_migrations()
2025/02/12 14:38:32   File "<string>", line 8, in run_migrations
2025/02/12 14:38:32   File "/usr/local/lib/python3.10/site-packages/alembic/runtime/environment.py", line 948, in run_migrations
2025/02/12 14:38:32     self.get_context().run_migrations(**kw)
2025/02/12 14:38:32   File "/usr/local/lib/python3.10/site-packages/alembic/runtime/migration.py", line 627, in run_migrations
2025/02/12 14:38:32     step.migration_fn(**kw)
2025/02/12 14:38:32   File "/app/migrations/versions/9e8c841d1a30_fix_hash.py", line 55, in upgrade
2025/02/12 14:38:32     new_hash = update_query_hash(record)
2025/02/12 14:38:32   File "/app/migrations/versions/9e8c841d1a30_fix_hash.py", line 29, in update_query_hash
2025/02/12 14:38:32     parameters_dict = {p["name"]: p.get("value") for p in record['options'].get('parameters', [])} if record.options else {}
2025/02/12 14:38:32 TypeError: 'NoneType' object is not iterable

コードの該当箇所を確認したところ、取得されたparameters_dictは利用されていなかったためコメントアウトすることで対応しました。

https://github.com/getredash/redash/blob/master/migrations/versions/9e8c841d1a30_fix_hash.py#L29-L31

def update_query_hash(record):
    should_apply_auto_limit = record['options'].get("apply_auto_limit", False) if record['options'] else False
    query_runner = get_query_runner(record['type'], {}) if record['type'] else BaseQueryRunner({})
    query_text = record['query']

    # parameters_dict = {p["name"]: p.get("value") for p in record['options'].get('parameters', [])} if record.options else {}
    # if any(parameters_dict):
    #    print(f"Query {record['query_id']} has parameters. Hash might be incorrect.")

    return query_runner.gen_query_hash(query_text, should_apply_auto_limit)

最後に

Redash v10.0.0 から v25.1.0 へのアップグレードが完了しました。
一部暫定的な対応を行いましたが、試験環境でのアップグレードは成功しました。
現在、既存クエリとダッシュボードが正常に動作するかどうか、試験環境で確認を行っています。
これらに問題がないことを確認次第、本番環境へのアップグレードを進める予定です。