某飲食店予約システムのインフラ構成を予想したい。

インフラのイの字もわからないのにインフラ系のことをせざるを得ない状況になっており、勉強のために某飲食店予約システムのインフラ構成を予想しようと思いました。ピンクくて丸いやつ向けです。

注意

記事の内容は、野球の試合をテレビで見ながらイチャモンをつけるおっさんくらい薄く、知識量に比例して正確性は皆無です。インフラをわかってない人が頑張るとこういう予想にたどり着くんだね、という参考にはなるかもしれません。

参考にしたページ

とりあえず情報を集めます。

トレタのインフラ運用、支えている道具(Packer, Terraform, Serverspec, Ansible, Roadworker, Circle CI)、考え方 – トレタ開発者ブログ
トレタのインフラ運用 – Speaker Deck
トレタのMySQL MySQL casual #8
記事が結構古いからだいぶ変わってそうですね。どっかに答え載ってるんじゃないかと思って開発者ブログを見てみたけど最近の記事はなかった…。SlideShareとかにはあるのかもしれないですね。

うっす~いよそう

実際に使ってみてのエラーの返り方やレスポンスの感じだと以下のような構成でしょうか…?

  • サーバ:Amazon EC2
  • ロードバランサ:ALB?NLB?
  • バックエンド:Ruby on Rails
  • DB:Amazon RDS for MySQL
  • 静的コンテンツ(json等):CloudFront
  • 静的コンテンツ(画像等):Amazon S3

default backend – 404(多分Nginx Ingress Controllerのデフォルトバックエンドのレスポンス)が時たま返ってきたことから予想すると、おそらくRoRはKubernetesのPodで動いてるかもしれません。AWSを使ってるなら、GKEを採用しているのかなぁと予想しました。(リバースプロキシもIngressを使用)

実際の挙動からのうっす~いよそう

予約用の内部APIは予約対象の店舗のIDごとに処理する仮想サーバが決まっているわけではないようで、一店舗に予約処理が集中すると他の店舗のリクエストも応答しなくなるという挙動でした。(実際、先月はそれで巻き添え食らったところが落ちていた)
EC2使ってるならスケールアウトするか、予行演習で前もってやばいのはわかってたので、ピンクいやつだけL7ロードバランサでRDSもRoRも専用のインスタンスに処理させるとかいくらでも手は打てたと思うのですが、どうしてこうしなかったのかはよくわかりません。

以下を読んだのですが、ELB自体は5万RPSかけても受けきれるっぽいのと、API叩いたときに502 Bad Gateway返ってきてたので、Ingress Controllerまでは問題なくて、バックがボトルネックになっているのかなぁと思いました。(小学生並みの感想)
[社内勉強会]ELBとALBと数万スパイク負荷テスト

感想

やっぱりよくわからない。

metabaseを日本語化するとバグりすぎてつらいので英語のまま使う。

metabase v0.30.3の話です。コントリビューターの方々には本当に申し訳ないのですが、日本語化すると表示周りのバグのせいでビジュアライゼーションの種類が選択できなくなるのと、翻訳がめちゃくちゃで使い勝手が著しく悪くなるので、英語の状態のまま使用することにしました。 
ビジュアライゼーションの種類が選択できなくなるのは、ブラウザのDeveloper Tool等で要素を書き換えれば回避可能です。issueにはすでに上がっていました。

ここを書き換えれば選択可能になる

対策案

  1. metabase.jarをいじる
  2. リバースプロキシ(nginx)の設定でaccept-languageからja-JPを消す

metabase修正するのはできるけど、バージョン上がっても治ってなかった場合に同じことを繰り返すのがつらいので、リバースプロキシ(nginx)でどうにかします。

proxy_hide_header accept-language;
proxy_set_header accept-language "en-US,en;q=0.9";

無事英語のダッシュボードが表示されるようになりました。

metabaseの設定画面で一瞬でもLanguageにトルコ語(Turkish)を選択すると詰む。

500エラーで詰んだ。

???? "SETT?NG" ????????
Table "SETT?NG" not found. SQL statement:
SELECT * FROM "SETT?NG" WHERE ("KEY" = ? AND "VALUE" > ?) LIMIT 1 [42102-197]

バージョンはv0.30.3です。
最初何が起こったのか全くわかりませんでしたが、エラー内容的に言語設定があやしそうだったので、 metabase.db.mv.dbの中身を直接見て、SETTINGのsite-localeをen-USに設定したら無事に復旧しました。
ゆとりなので修正にはGUIのH2 Consoleを使用しました。あと、DBのIDとPWはそれぞれ空文字でした。

issueにはすでに上がっていました。
Table Not Found – Wrong table name with locale characters · Issue #8565 · metabase/metabase

翻訳しなくてもいいところが翻訳されまくっててわかりにくいので英語に戻したいんですが、ブラウザのロケールで強制的に言語が決まってしまうので大変に辛いです。

Metabaseを使ってポケモンGOで孵化したタマゴの情報を可視化する。

旦那さんとポケモンGOをプレイしているのですが、タマゴから孵るポケモンに偏りがあるかを知りたかったので、記録を取るようにしています。
記録の方法は以下の通り。

  1. タマゴが孵化したらLINEグループ宛に報告する
  2. 報告をLINE botが拾ってDB(SQLite3)に書き込む

LINE botと会話して統計を取れるようにはなっているのですが、テキストベースだと情報がデジタルでいまいちピンとこないため、Metabaseで情報を可視化してみることにしました。最初Grafanaが使いたかったのですが、SQLiteに対応していないので自動的にMetabase一択になりました。

動かし方

インストールは以下の記事を参考にしました。
OSSのデータ可視化ツール「Metabase」が超使いやすい
Dockerが多分一番楽に立ち上げられる気がします。私の環境はいろいろあってDockerが動かせないので、jarをそのままOpenJDK 8で動かす方法をとりました。使用したMetabaseのバージョンは0.30.1です。デフォルトだと3000番がMetabaseのポートになります。
セットアップはほんとに楽すぎて何も困ることなかったので割愛。

可視化したいDBの設定

DBの追加画面

ここから解析対象のDBまでのパスを入力すればすぐ解析してくれます。

DBの可視化結果とか

DBの可視化結果
ポケモンの円グラフとかホエルコのグラフとか

お互いが孵したポケモンの円グラフを作ってみました。本当はグラフの横に凡例と値が出力できるのですが、GUIのバグで凡例が多すぎるとグラフが表示できなくなるため、非表示にしています。カーソルを当てると内容がわかるのですが、不便なので次バージョンに期待します。

DBのフィルタリング結果

フィルター機能で期間やタマゴの距離を絞り込むこともできます。めちゃくちゃ楽です。

使ってみた感想

私がQuestionをあまり上手に使いこなせていないので、今の所Kibanaのように息を吸って吐くレベルのグラフ作成には到達できていません。が、最悪SQL文を書いてもグラフは作れるので、可視化するには困らなさそうです。ただ動かすまでの手軽さは、ElasticSearchとFluentdのハードルが高い分、圧倒的にMetabaseのほうが勝ります。java jarコマンド打つだけだったので本当に手軽でした。アクセスログを解析するぐらいであれば、Metabaseで十分用が足りると思います。GUI周りのバグについては今後の修正に期待したいと思います。

あと、旦那さんが使っているブラウザがモダンブラウザではないので、表示がバグったり動作しないスクリプトがあったりするのが悩みどころです。他人とダッシュボードを共有するときは、モダンブラウザの使用ルール化することをおすすめします。

Metabase v0.30.1 でSQLite3のテーブルのFILTERED BYが動作しない

あらまし

Metabase v0.30.1でSQLite3のテーブルを読み込んだのですが、DB追加時にMetabaseが実施してくれるExploreが500を返し続けて永遠に終わらなかったり、FILTERED BYを使おうとしてもfieldの候補が表示されないので原因を調べました。Sample datasetだと問題ないのでインストール時の問題ではなさそうです。

FILTERED BYが選択できない

FILTERED BYが選択できない

調査

logに以下の警告が出ています。Settingsからログが見られるのはありがたいですね。

Aug 26 12:50:00 WARN metabase.driver.generic-sql :: Don't know how to map column type '' to a Field base_type, falling back to :type/*.
(中略)
Aug 26 07:50:04 ERROR metabase.sync.util :: Error running sync step: class java.lang.ClassCastException
[]

テーブル作成時にカラムのデータ型を指定しなかったので、typeが空文字で返ってきてしまって、どの型にキャストしていいのかわからずにエラーを起こしているみたいですね。DBの仕様に合わせてその辺りよろしくやってくれると嬉しいのですが。

対処

カラムの型を定義したテーブルを作り直してMetabaseに登録し直します。SQLiteは途中でカラムの定義が変えられないようなので、create tableし直したあとにinsert intoで元のテーブルの内容をそっくりそのまま挿入する方法でどうにかしました。

結果

無事Exploreが動作してFILTERED BYも選択できるようになりました。SQLiteの時刻表記の文字列が時刻として扱われるのか不安でしたが、きちんと時刻として認識されました。よかったです。