秘伝のredash v1.0.3 から redash v8.0.0 on ECSになるまで

この記事はTech KAYAC Advent Calendar 2019 Update/MigrationTrack 3日目の記事です。

昨年のAdvent Calendarで闇のredash の記事を書いていたゲームコミュニティ(Lobi)事業部の自称データエンジニアの池田です。今回も、redashについて記事を書いていきたいと思います。
redashは様々な種類のデータソースにアクセスできる、OSSの素晴らしいダッシュボードツールです。
2017-01-31にv1.0.0-rc.1のリリースされて以来開発が続けられており、この前の2019-10-27にv8.0.0 がリリースされました。 今後もビジネスインテリジェンスの現場でのダッシュボードツールの選択肢として利用され続けることでしょう。

ゲームコミュニティ事業部でのRedashの課題

私の所属するゲームコミュニティ事業部でも、以前本ブログで事例紹介したようにredashを使用し続けております。
techblog.kayac.com

さて、このredashですが、2017年10月頃よりある問題が囁かれ続けていました。

  • 公式AMIベースで起動したEC2インスタンスを直接変更
  • 変更した設定を管理する手段がない
  • なにかの拍子に現在のEC2インスタンスが失われると、復元作業が大変

そのredashの動いているEC2インスタンスは俗に、秘伝のタレのようなインスタンスと呼ばれていました。 当然、秘伝のタレのように継ぎ足しで設定してきたためアップデート失敗のリスクを考え、メジャーバージョンのアップグレードは見送られv1.0.3の状態のままで運用されていました。このまま、v1.0.3を使い続けるしかないのか?と思ってはいてもメジャーバージョンが2つ3つどころか、4つ以上先を行っている状況はなんとかしたい。 そういう問題をゲームコミュニティ事業部のredashは抱えていました。

重い腰を上げてのアップグレード - v1.0.3からv7.0.0へ

ゲームコミュニティ事業部では様々な業務にredashを使っており、アクセス分析にも活用しています。分析的な業務を行うSQLでは、通常のSQLとは異なり多数のWITH句副クエリを活用します。redash v7.0.0ではクエリの部分実行が可能になったため、WITH句副クエリの部分だけ実行して結果を確かめられるため非常に重宝することが予想できました。
そういう背景もあり、重い腰を上げてv1.0.3からv7.0.0へのアップグレードを行うことを決意しました。

念のためのバックアップ

秘伝のタレとなったredashインスタンスは、設定を管理していない関係でアップグレードの拍子に壊れるともとに戻せなくなってしまいます。 ですので、AWSコンソールから作業前に既存のインスタンスのAMIを取得し、これをバックアップとしました。手順はこのリンクのものをそのまま行いました。
Amazon EC2 インスタンスからの AMI の作成 - AWS Toolkit for Visual Studio

これは大事な作業です。 後にこのAMIが私を救ってくれました。

最初の壁 - Pythonが古い

意気揚々と当時の最新バージョンへアップグレードを開始!

$ sudo bin/upgrade
Starting Redash upgrade:
Found version: 7.0.0
Current version: 1.0.3+b2850

と始まり順調に見えたものの、

Command python setup.py egg_info failed with error code 1 in /tmp/pip_build_root/gevent
Storing debug log for failure in /home/ubuntu/.pip/pip.log

oh... どうやら依存パッケージのinstallに失敗したようだ。pythonが古すぎたんだ!! pythonの知識と格闘してpythonのパッケージ管理ツールpipをアップグレードを行いました。

マイグレーションで失敗するので一度v4.0.1を経由する

古すぎたPythonをアップグレードして、再実行すると以下のようなエラーメッセージが出ます。

sqlalchemy.exc.ProgrammingError: (psycopg2.ProgrammingError) column dashboards.tags does not exist
LINE 1: ...ived, dashboards.is_draft AS dashboards_is_draft, dashboards...
                                                             ^
 [SQL: 'SELECT dashboards.updated_at AS dashboards_updated_at, dashboards.created_at AS dashboards_created_at, dashboards.id AS dashboards_id, dashboards.version AS dashboards_version, dashboards.org_id AS
dashboards_org_id, dashboards.slug AS dashboards_slug, dashboards.name AS dashboards_name, dashboards.user_id AS dashboards_user_id, dashboards.layout AS dashboards_layout, dashboards.dashboard_filters_enab
led AS dashboards_dashboard_filters_enabled, dashboards.is_archived AS dashboards_is_archived, dashboards.is_draft AS dashboards_is_draft, dashboards.tags AS dashboards_tags \nFROM dashboards'] (Background
on this error at: http://sqlalche.me/e/f405)

redashで使っているPostgreSQL関係のマイグレーションで失敗したようです。
ok, google! 解決策を探して! 色々検索して探してみるとジャストミートな解決策を見つけました。

Redash v5 にアップグレードすると「dashboards.tags does not exist」エラーが発生する現象の対応 - Qiita

ありがとうございます!記事の内容を参考にupgradeスクリプトをコピーして以下のように改変し、一度v4.0.1にアップグレードするようにします。

--- bin/upgrade 2017-04-19 04:53:04.000000000 +0900
+++ bin/upgrade_v4      2019-07-04 15:56:11.278452683 +0900
@@ -95,9 +95,12 @@
     response = requests.get('https://version.redash.io/api/releases?channel={}'.format(channel))
     release = response.json()[0]

+    release['version'] = '4.0.1'
+    release['download_url'] = 'https://s3.amazonaws.com/redash-releases/redash.4.0.1.b4038.tar.gz'
     filename = release['download_url'].split('/')[-1]
     release = Release(release['version'], release['download_url'], filename, release['description'])

+    print(release)
     return release

このスクリプトを実行すると

Continue with upgrade? (y/n): y
Downloading release tarball...
Unpacking to: redash.4.0.1.b4038...
Changing ownership to redash...
Linking .env file...
Installing new Python packages (if needed)...
Running migrations (if needed)...
Linking to current version...
Restarting...
Done! Enjoy.

無事にv4.0.1になりました。

無事にv4.0.1からv7.0.0へ

ここでもう一度、オリジナルのupgradeスクリプトを実行すると

$ sudo bin/upgrade
Starting Redash upgrade:
Found version: 7.0.0
Current version: 4.0.1+b4038

と始まり

Continue with upgrade? (y/n): y
Downloading release tarball...
Unpacking to: redash.7.0.0.b17535...
Changing ownership to redash...
Linking .env file...
Installing new Python packages (if needed)...
Running migrations (if needed)...
Linking to current version...
Restarting...
Done! Enjoy.

無事にv7.0.0にアップグレードできました。

完璧ではなかったアップグレード、そしてECS化の流れ

アップグレード翌日、事件が発生する。既存の運用クエリが動かないとの報告を受ける。
Google SpreadSheet Data Source が 消滅してる

取っててよかったAMI

運用期間が長くなった秘伝のredashでは、オペレーターが簡易的に使えるデータソースとしてGoogle SpreadSheetを採用しており、シート上の値を読み取って、その値に従って様々な情報を取得してくるクエリが日常化していた。昨日アップグレードしたredashからは何故かGoogle SpreadSheet QueryRunnerが読み込まれていない状態であったのだ。

早急に解決しなければ運用に支障が出る!?

早期の解決を諦め、アップグレード作業前に取得していたAMIから新たなインスタンスを立ち上げ、状態を復元してアップグレード前のredash v1.0.3を利用できる状態にした。予めバックアップとして取得していたAMIが役に立った瞬間である。

諦めも大事。思い切ってECS化する流れに

古い秘伝インスタンスを復元し運用への影響から逃れたあと、なぜGoogle SpreadSheet QueryRunnerが読まれていないのかを調べた。 原因を調べた結果、依存するpython パッケージのバージョンが原因のようであった。
しかし、このパッケージのバージョンアップを試みると、osのアップデートやら別の関連パッケージのアップデートやらと芋づる式に問題が発生する状況になっていった。疲弊感の伴う中、@fujiwaraさんから

  • Ubuntu14.04.3 LTSはEoL
  • 古いPythonと格闘するのは不毛
  • DBがv7.0.0のものにできたんだから、ECSで新しいの動かせば?

たしかに!!
実はこのとき、redash v7.0.0 on ECS自体は @handlenameさんによって起動だけはされていた。
(ECS化の一環で色々テストするのに使っていたらしい)
方針としては、昨日アップグレードした秘伝のタレのPostgreSQLからデータをDumpして、redash v7.0.0 on ECSが参照しているRDSへデータを移行するという形になった。

データをRDSへお引越し

作業は単純 sshで秘伝のタレにアクセスし、データをdump

$  sudo -u redash pg_dump  -Fc redash > old_redeash.dump

scpを使って、dumpデータをVPCとlocalを経由して、RDS上にデータをそのまま転送

$ ssh -N -L 5432:<RDS postgreSQLのエンドポイント>:5432  <RDS にアクセスできるインスタンス>
$ pg_dump -Fc -h localhost -U root redash > ecs.dump
$ pg_restore -h localhost -Fc -U redash -d redash -C old_redash_backup.dump

これで、redash v7.0.0 on ECS が完成し、秘伝のタレと化したインスタンスに別れを告げることができました。

ECS化の恩恵、らくらくv8.0.0にアップグレード!

先日の2019-10-27にv8.0.0がリリースされました。 ECSのtask-difinitionという形でredashの設定を管理できるようになった今ではv7.0.0=>v8.0.0へのアップグレードもたやすく行えました。さらに、アップグレードの際には

f:id:ikeda-masashi:20191125175532p:plain

なんと!Pull Requestにしてreviewできるのです。infrastructure as code素晴らしい!

おわり

今回の記事は、秘伝のタレとなったEC2インスタンスのredash v1.0.3をなんとかアップグレードし、その過程でECSに乗り換えるという内容でした。
今回のredashアップグレードを通して痛感したことは以下です。

  • こまめにアップデート/アップグレードする
  • 秘伝化する前に 『Infrastructure as Code』
  • バックアップって本当に大事!
  • redash 最新版はいいぞぉぉぉぉ!

redash v8.0.0 では遂にMySQL query runnerの暴走に対する修正が入りました。これを期に皆様も秘伝化されているredashをアップグレードしませんか?