一分一秒真剣勝負!

Ruby, Railsなど。Web系の技術ネタを充実させたい・・が、そうなるかは分からない。

Elasticsearch2.3.3から5.4.3への移行作業

去年からElasticsearchをいじってたんだけど、全くブログなどに書いてなかったので書いてみる。 ツッコミとか大歓迎です。

あらすじ

HerokuのAdd-onsでElastic Cloudを使っているのですが、ある日、Elasticsearch 2.3 のサポート期限終了のお知らせが届きました。

Elasticsearch 2.3 reaches end of life (EOL) on September 30

This is a friendly reminder that Elasticsearch 2.3 reaches end of life on September 30, 2017. According to our records, you are still running one or more Elastic Cloud clusters using Elasticsearch version 2.3. Before that date, you need to upgrade your clusters to a more recent version. We highly recommend you to upgrade to the latest version which is Elasticsearch 5.4. Please note that if you upgrade from an Elasticsearch version prior to version 5 make sure you read the documentation on how to Upgrade to Elasticsearch 5.x.

If you have not upgraded your clusters by September 30, we will upgrade the clusters to the latest available version on the 2.x branch for you. As of today, this is Elasticsearch 2.4.

If you have a Cloud Gold or Platinum subscription, our support engineers can help you with this upgrade. Open a case to get started.

Kind Regards,

Your Elastic Cloud Team

サポートの終了がちょっと早い気もしたけど、古いバージョンをいつまでもサポートするのは良くない文明派なので素直にバージョンアップすることにしました。

状況

  • Heroku
  • Elasticserch(2.3.3)をHeroku Add-onsから利用中
  • indexの元ネタはPostgresqlから1日1回インポート
  • バージョン5.4.3へダウンタイムゼロで移行したい

バージョンアップ前の確認

Elasticsearch Migration Helperというバージョンアップ前のチェックツールが公式より提供されています。 Elastic Cloudでは標準でこれがインストール済みなので確認します。

f:id:yatmsu:20170716002629p:plain

自分の環境ではオールグリーン。 でも実際は1.xの時に作成した未使用のindexが残っていて、初回はレッドになりました。indexの1.x→5.xへの移行はできないんですね。これは削除するだけの対応で終了となりました。

Blue-Greenデプロイをしたい

Elasticsearchはメジャーバージョンアップを行う場合、Full cluster restart upgradeでバージョンアップを行わなければならない為、一定の時間クラスタが停止してしまいます。 そこで、ダウンタイムゼロでの移行を実現する為Blue-Greenデプロイをしようと考えました。リモートクラスタからもデータ参照が可能になったReindex APIを使えば簡単にできそうだなと予測。 しかし、複数クラスタを起動しようとしたところ、Heroku Add-onsのElastic Cloudだと単一のクラスタしか起動できない(Elastic Cloud単体で契約すると複数クラスタの起動可能)事に気付きました。これではBlue-Greenデプロイ出来ない。

別のappを使ってBlue-Greenデプロイ

そこで、ステージング環境として使っていたappで起動しているElasticsearchのクラスタを5.4.3に移行し、一時的にプロダクションからステージングのElasticsearchを参照させ、その間にプロダクションのバージョンを上げ、Elasticsearchの向き先を戻す・・・という手順で移行しました。

Elasticsearch(production-app)

     ↑ 通常はこっちを参照

WebServer(production-app)

     ↓ 一時的にこちらを参照させる

Elasticsearch(staging-app)

なんかイマイチだけど、まあこんなもんですね。

こうしておけば良かったこと

HerokuのAdd-onsではなく、Elastic Cloud単体で契約しておけばよかったなと。 Elastic Cloudは素晴らしいサービスなんだけども、HerokuのAdd-onsだと複数クラスタの運用が出来ないことだけが残念でした。今後の複数クラスタ起動対応に期待。

HerokuでBambooStackからCedarStackに移行する

Herokuでずっと更新していないアプリをruby2.0に上げようとしたのだが、Gemfileに「ruby "2.0"」と書いてもpushするとbundle installでエラーが出る。調べてみると過去にHeorkuで作ったアプリはBambooStack上で動いていて、使用出来るRubyのバージョンが古いなどなどが原因だった。
なので、Ruby2.0を使えるCedarStackに移行しようと思ったのだがBambooStackからCedarStackへの移行ツールなどは用意されておらず、CedarStackにするには新しくアプリを作るしかなかった。旧アプリ→新アプリへのデータ移行作業をすればいいかと考えたのだけど、BambooStackで作ったアプリのURLは「http://appname.heroku.com/」だったものがCedarStackだと「http://appname.herokuapp.com/」で作られるらしい。独自ドメインを設定していないので、URLが変わってしまう。これでは移行できない・・・と思ったが、アプリ名さえ同じであればheroku.comもherokuapp.comと同じIPを指してくれるので問題は無し。

というわけでまずDBのバックアップ。

bundle exec heroku db:pull sqlite://db/production.sqlite3 --app appname

ここで自分の環境ではエラーが出た。このエントリーを書いている時点ではRuby1.9.3以降でsqlite形式にデータを変換する時にバグがあるらしく、Ruby1.9.2以前のバージンでエクスポートしなくてはならない。(Macで開発している場合は「brew install apple-gcc42」でRuby1.9.2をコンパイルできるようになります。)

そして現在使っているHerokuドメイン"appname"をブラウザから別名にリネーム*1し、今まで使っていた"appname"でアプリを再作成します。

heroku create appname --stack cedar # アプリ削除からこのコマンド実行までに"appname"を取られたら作れなくなるので急いで作る

そしてバックアップしたDBを新アプリにインポート。

bundle exec appname db:push sqlite://db/production.sqlite3 --app appname

これでアクセスしてみて動作確認がとれれば旧アプリは削除してしまってOK。

ちょっと面倒ですね。ブラウザからクリックひとつでStackを移行できるツールがあったらいいのに。

*1:コマンドでもできます

HerokuでRails3.1+sqlite3アプリをデプロイする!

 GitのリポジトリをpushするだけでデプロイまでしてくれるHerokuでRialsアプリをデプロイしてみました!友人の居酒屋サイトを作成中なんですが、凄い便利ですねHeroku。以下はherokuを使う時のまとめ。ちなみにRails3.1でデプロイしたものの、実装はほぼ3.0.9のままで、DBはsqlite3です。

アカウント作成

以下のURLから新規登録する。
http://api.heroku.com/signup

事前準備

$ gem install heroku # heroku利用時に必要なgem
$ heroku keys:add # username/passを保存しておく

Gemfile

 このエントリーを書いている時点では、この問題がある為、以下のgemを入れておかないとpushできないですね。

group :production do
  gem 'therubyracer-heroku', '0.8.1.pre3' # you will need this too
  gem 'pg'
end

Railsアプリ作成

$ rails new hoge
$ git init
$ git add .
$ git commit -m 'first commit'

herokuにアプリを作成・デプロイ

$ heroku create # heroku上でアプリケーションを作成するコマンド
# https://api.heroku.com/loginでherokuにログインし、アプリケーションの名前を変更する

$ vi .git/config # リポジトリ名をブラウザで変更した名前に修正する
[remote "heroku"]
url = git@heroku.com:変更したアプリ名.git
# これをやっておかないとリポジトリが見つからずにpushできなくなる

$ git push heroku master # herokuにリポジトリをpushし、デプロイも実行
$ heroku open # ブラウザが起動し、サイトを表示する

その他よく使うコマンド

dbのmigrate
$ heroku rake db:migrate # heroku上でmigrate
dbのダウンロード
$ heroku db:pull sqlite://保存先のパス/保存したいファイル名
# 例
$ heroku db:pull sqlite://db/production.sqlite3
dbのアップロード
$ heroku db:push sqlite://パス/アップロードするファイル名
# 例
$ heroku db:push sqlite://db/production.sqlite3

 このコマンド実行時にアプリ名を入力する必要があります。省略する為のオプションもあるのですが僕は使ってません。

参考

HerokuでDBのデータをダウンロードしたりアップロードしたり - アインシュタインの電話番号☎

 とりあえず基本的なコマンドはこんな感じ。無料プランだとDBが5Mまでと少なすぎですが、簡単なアプリを作るには十分ですね。