こんにちは、虎の穴ラボのT.Mです。
この記事は「虎の穴ラボ 夏のアドベントカレンダー」9日目の記事です。
8日目は片岡さんによる「タイムトラッキングをやってみましょう」が投稿されました。
10日目は磯江さんによる「アジャイルで生活をカイゼンする」が投稿されます。こちらもぜひご覧ください。
はじめに
突然ですが皆さんはデータベース(以下DB)のパフォーマンスを向上させる場合、何を思い浮かべますか?
最初はINDEXやクエリのチューニング、続いて設定周りの見直しでしょうか。
場合によっては正規化をあえて崩し、テーブルの再設計などを行うかもしれません。
またサーバスペックを上げたり、リードレプリカを増やすなどの負荷分散も試すことでしょう。
今回触れるPlanetScaleは、負荷分散の手法の一つであるシャーディングを得意とします。
シャーディングといえば面倒なイメージがありますが、PlanetScaleはその手間を一手に引き受けてくれる優れものです。
仕事には役立たないかもしれない?
今週のテーマは「仕事には役立たないかもしれない技術」なのですが、「シャーディング」は本当に役立たないのでしょうか。
確かに一般的な規模のサービスからするとシャーディングの導入は、メリットがありつつもオーバースペックなのは否めません。
特に、サービス立ち上げ期に導入する施策としては、候補には上がりにくいものかもしれません。
しかしサービスは成長するもので、負荷分散を重視すべきフェーズはいずれ訪れます。
その際に選択肢として挙がるよう記憶の片隅にでも留めていただければ幸いです。
それではチュートリアルに従い簡単なWEBアプリを作っていきましょう。
シャーディングのメリット
まずシャーディングのメリットですが、一般的にはこれらが挙げられます。
- 複数のサーバに分割されるため、テーブルあたりのレコード数を少なく保てる
- レコード数が少ないことからINDEXサイズも同様に小さく、検索パフォーマンスが期待できる
- 取得したいレコードの保存場所が分かれているため、同時接続を分散できる
- 物理的にデータが分かれていることによりスケールアウトが容易である
ただしシャーディングは「何でも解決できる魔法の道具」ではないことをご理解ください。
複数のシャードを参照する場合、サーバ間のレイテンシが問題になる場合があります。
また独自実装の際はその複雑さもデメリットとして挙げられるでしょう。
PlanetScaleとは
PlanetScaleとは、Vitessを利用し水平スケーリングを実現したMySQL互換のサーバレスDBプラットフォームです。
※ ただしPlanetScaleはオリジナルのVitessではなくForkしたものを利用しているようです
※ Vitessの歴史について興味がある方はこちらをご参照ください
Vitess自体は様々な機能を持っており、それだけでもシャーディングの実装は可能です。
しかしVitessを正しく活用できるエンジニアとなると数は限られます。
その知識や経験といった部分を全て引き受けてくれるのがPlanetScaleです。
PlanetScaleはサービスに登録し、CLIをインストールするだけでMySQLとほぼ同じ感覚で利用できます。
外部キー制約が使えないという制限がありますが、対応方法は提示されていますのでこちらをご確認ください。
登録方法と注意点
登録自体は簡単に行えますので、順を追って見ていきましょう。
登録時のプランは自動的にフリープランとなり費用はかかりません。
必要に応じてクレジットカードを登録し上位プランに移る方式ですので、安心してお試しいただけます。
それではPlanetScaleにアクセスし、Get started
を押下しましょう。
登録画面へ遷移しますので、メールかGitHub連携での登録を行ってください。
登録するとこの画面が表示されます。
Github連携の場合、組織名にアカウント名がセットされます。
後ほど変更することもできますので、今はこのままで構いません。
この後は説明が5ページほど続きます。
最後の画面で「DBの新規作成」か「既存のMySQLをインポート」かを聞かれますが、今回は新規で作成します。
作成時に注意するポイントとして、当たり前ではありますが「最寄りのリージョン」を選択しましょう。
以前はus-westが一番近かったようですが、現在はTokyoもちゃんと選択肢にあります。
Create database
を押下でDBが作成されました。
この時点ではusernameやpassword等の設定は不要です。
簡単ですね!
CLIのインストール
コンソールから各種操作を行うために、CLIをインストールしましょう。
ドキュメントのCLIの項目またはCLIのリポジトリのREADME.mdを参照してください。
各OS毎のインストール方法が記載されており、記載されている内容を実行するだけで完了します。
macの場合
$ brew install planetscale/tap/pscale $ brew install mysql-client
完了したらお約束のバージョン表示でインストールされたことを確認します。
$ pscale --version pscale version 0.107.0 (build date: 2022-06-30T20:25:44Z commit: 3f2626a)
アプリケージョンの準備
ドキュメントに従い、PlanetScaleを利用するアプリを作成します。
ここではRailsを使いますが、お好みの言語/フレームワークをお試しください。
※ rubyやRailsのインストールは割愛します
rubyとRailsの確認
$ ruby -v ruby 3.1.2p20 (2022-04-12 revision 4491bb740a) [x86_64-darwin19] $ rails -v Rails 7.0.3
PlanetScaleのログイン
※ 一旦WEBページに飛ばされて、認証後にコンソールに戻ってきます
$ pscale auth login Confirmation Code: XXXXXXXX If something goes wrong, copy and paste this URL into your browser: https://auth.planetscale.com/oauth/device?user_code=XXXXXXXX Successfully logged in.
ブログアプリの作成とディレクトリへ移動
$ rails new blog $ cd blog
ドキュメントの通りmysql2をGemfileに追加
$ vi Gemfile # 「gem "mysql2"」を追記し保存
bundle installの実行
$ bundle install
DBの準備
blogという名称でブログ用のDBを作成します。
しかしフリープランは1台までなので怒られてしまいました。
アカウント作成と同時に作成したDBが既に存在するからですね。
$ pscale database create blog Error: This organization is at its limit of 1 free database.
再度PlanetScaleを訪れます。
最初に作成したDBを選択後、SettingのGeneralに移動すると一番下にDelete database
があるので消してしまいましょう。
削除することで通るようになりました。
$ pscale database create blog Database blog was successfully created. View this database in the browser: https://app.planetscale.com/xxxxxxxxx/blog
続いてmainブランチ用のパスワードを設定します。
こちらにhoge
と打ち込んだ値は実際のusernameやpasswordではありませんのでご安心ください。
どちらも自動的に生成され、下記のような形で返ってきます。
$ pscale password create blog main hoge Password hoge was successfully created in blog/main. Please save the values below as they will not be shown again NAME BRANCH USERNAME ACCESS HOST URL ROLE ROLE DESCRIPTION PASSWORD ------ -------- -------------- ----------------------------------- ------- ------------------------------ ------------------------------------------------------- hoge main XXXXXXXX XXXXXXXX.us-east-2.psdb.cloud admin Can Read, Write & Administer pscale_pw_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX
しかしACCESS HOST URLがus-east-2になってしまいました。
チュートリアルのpscale database create
コマンドにリージョン指定がなかったのが原因です。
これでは困りますので、今度はコマンドラインから先ほどのDBを消してみましょう。
$ pscale database delete blog ? Please type blog to confirm: blog Database blog was successfully deleted.
リージョンを指定して再度DBを作成します。
利用できるリージョンを知るコマンドはこちらになります。
$ pscale region list NAME (9) SLUG ENABLED ----------------------------------- -------------------- --------- AWS us-east-1 (Northern Virginia) us-east Yes AWS us-west-2 (Oregon) us-west Yes AWS eu-west-1 (Dublin) eu-west Yes AWS ap-south-1 (Mumbai) ap-south Yes AWS ap-southeast-1 (Singapore) ap-southeast Yes AWS ap-northeast-1 (Tokyo) ap-northeast Yes AWS eu-central-1 (Frankfurt) eu-central Yes AWS ap-southeast-2 (Sydney) aws-ap-southeast-2 Yes AWS sa-east-1 (Sao Paulo) aws-sa-east-1 Yes
DB作成時にリージョンを指定するパラメータは--region
ですので、その後にap-northeastと続けます。
$ pscale database create blog --region ap-northeast Database blog was successfully created. View this database in the browser: https://app.planetscale.com/xxxxxxxx/blog
パスワードも同様に再度設定します。
どうやらap-northeast-2で正しく作られたようです。
発行された内容は二度と表示されませんので大切に保管してください。
今回はお試しですので、DBを捨てる前提で忘れてしまっても構いません。
$ pscale password create blog main hoge Password hoge was successfully created in blog/main. Please save the values below as they will not be shown again NAME BRANCH USERNAME ACCESS HOST URL ROLE ROLE DESCRIPTION PASSWORD ------ -------- -------------- ---------------------------------------- ------- ------------------------------ ------------------------------------------------------- hoge main XXXXXXXXX XXXXXXXXX.ap-northeast-2.psdb.cloud admin Can Read, Write & Administer pscale_pw_XXXXXXXXXXXX
上記の内容で、config/database.yml
を編集します。
development: <<: *default adapter: mysql2 database: blog username: <USERNAME> host: <ACCESS HOST URL> password: <PASSWORD> ssl_mode: :verify_identity sslca: "/etc/ssl/cert.pem"
ここまで来れば後一息です。
PlanetScaleへ戻り、作成したblog DBのSettingを押下。
その中にあるAutomatically copy migration data
にチェックを入れましょう。
Migration framework
は元からRailsが指定されていると思いますが、異なる場合はRailsに変更してください。
Save database settingsを押下して設定完了です。
完成したアプリを動かす
入れ物の準備はできましたが、まだ中身が空です。
チュートリアルを進めてテーブルを作りましょう。
$ rails generate migration CreateUsers
ここまでチュートリアルの通りに進めた場合、下記のエラーが出ると思われます。
/Users/XXXX/.rbenv/versions/3.1.2/lib/ruby/gems/3.1.0/gems/bootsnap-1.12.0/lib/bootsnap/load_path_cache/core_ext/kernel_require.rb:15:in `require': cannot load such file -- sprockets/railtie (LoadError)
その場合はGemfileのコメントアウトされたsassc-rails
をもどし、bundle install
を実行してください。
# Use Sass to process CSS - #gem "sassc-rails" + gem "sassc-rails"
これでマイグレーションファイルができました。
$ rails generate migration CreateUsers invoke active_record create db/migrate/20220704174257_create_users.rb
作成されたマイグレーションファイルを今回は下記の内容で書き換えます。
※ チュートリアルは6系でした
class CreateUsers < ActiveRecord::Migration[7.0] def change create_table :users do |t| t.string :name t.string :email t.timestamps end end end
マイグレーションの実行
$ bin/rails db:migrate == 20220704174257 CreateUsers: migrating ====================================== -- create_table(:users) -> 0.0443s == 20220704174257 CreateUsers: migrated (0.0443s) =============================
CLIでDBに接続し確認するとテーブルが作られています。
$ pscale shell blog main blog/main> show tables; +----------------------+ | Tables_in_blog | +----------------------+ | ar_internal_metadata | | schema_migrations | | users | +----------------------+ blog/main> desc users; +------------+--------------+------+-----+---------+----------------+ | Field | Type | Null | Key | Default | Extra | +------------+--------------+------+-----+---------+----------------+ | id | bigint | NO | PRI | NULL | auto_increment | | name | varchar(255) | YES | | NULL | | | email | varchar(255) | YES | | NULL | | | created_at | datetime(6) | NO | | NULL | | | updated_at | datetime(6) | NO | | NULL | | +------------+--------------+------+-----+---------+----------------+
これでアプリからマイグレーションを実行し、PlanetScaleに向けてDDL文を発行するところまでできました。
チュートリアルはここまでとなります。
まとめ
一通りチュートリアルを試してみましたが、いかがだったでしょうか。
シャーディングと聞くと難しそうなイメージですが、複雑な部分は全てPlanetScaleが受け持ってくれます。
既存MySQLからのデータ移行方法などもドキュメントにありますので、ハードルはかなり下がったのではないでしょうか。
「Amazon RDSとの比較」なんて記事もありますので、PlanetScaleのブログを眺めるのも面白いかもしれません。
明日は磯江さんによる「アジャイルで生活をカイゼンする」です。
実生活に即した楽しい内容となっていますのでご期待ください。
P.S.
虎の穴ラボでは、私たちと一緒に新しいオタク向けサービスを作る仲間を募集しています。
詳しい採用情報は以下をご覧ください。
yumenosora.co.jp