Ruby
 Computer >> コンピューター >  >> プログラミング >> Ruby

「PaaS不要」のアプローチはRails開発者にとって賢明な選択なのか?Rails 8の実力を検証

Rails 8は「No PaaS Required(PaaSは不要)」という大胆なコンセプトを掲げてリリースされました。クラウドプラットフォームのコストが高騰する中、Ruby on Railsは外部インフラへの依存を減らす方向へシフトし、開発者がより少ないサービス依存関係でアプリケーションをデプロイ・実行できるようにしています。

「PaaS不要」のアプローチはRails開発者にとって賢明な選択なのか?Rails 8の実力を検証

従来、Railsアプリをインターネット上に公開するには、PostgreSQLなどのデータベースサーバーを用意し、さらにキャッシュやバックグラウンドジョブ、WebSocketのためにRedisといった追加サービスを導入するのが一般的でした。Rails 8では、コアチームがこの常識を変えようとしています。キャッシュ、ジョブキュー、リアルタイムWebSocketのソリューションをフレームワーク本体に組み込み、すべてをアプリケーションのデータベースだけで動かせるようにしたのです。

本記事では、「Solid Trifecta(Solid三種の神器)」の概要から始めて、Rails 8がどのように「No PaaS Required」の約束を果たしているのかを見ていきます。

Solid Cache:Redisなしでキャッシュを実現

Rails 8の注目機能のひとつがSolid Cacheです。RedisやMemcachedに代わる新しいキャッシュストアとして登場しました。Solid Cacheは、インメモリのキーバリューストアではなくデータベースを使ってキャッシュデータを永続化します。ディスクにキャッシュオブジェクトを保存するのはRAMより技術的には遅いのですが、大きなメリットがあります。

第一に、ディスクストレージはメモリよりも容量が多く、はるかに安価です。Solid Cacheなら、RAMの上限を気にせず、より多くのデータをより長くキャッシュできます。BasecampやHEYを手がける37signalsでは、RedisからSolid Cacheへ移行したことでキャッシュを10TB超に拡張でき、結果としてP95レンダリング時間を50%削減しました。

確かに、メモリからの読み取りはディスクより速いです。しかし多くの場合(Basecampのユースケースなど)、より多くのデータをキャッシュできるというトレードオフの方が、速度面の損失を上回る価値があります。

デフォルトでは、Rails 8はSQLiteをバックエンドとするSolid Cacheを使用します。もちろん、Railsのお約束どおり、自分にとって最適ならRedisなど別の選択肢を選ぶことも可能です。ただ、このデフォルトを使えば、Redisのような追加の本番サービスを運用することなくキャッシュが利用でき、インフラ管理の負担が大きく軽減されます。

Solid Queue:Redisなしでバックグラウンドジョブを処理

「Solid」トリオのもうひとつの注目ポイントがSolid Queueです。Redisはおろか、Sidekiqのような別のジョブシステムへの依存も必要としない、新しいActive Jobバックエンドです。

多くのRails開発者は、バックグラウンドジョブにSidekiq(Redisに依存)やDelayed Jobなどのgemを使ってきました。Solid Queueは、そうした依存をなくすことを目指したRailsの試みです。ジョブキューイングをアプリケーションのデータベースに統合するため、メモリストアやキューイングシステムを別途用意する必要がありません。

Solid Queueはジョブをデータベーステーブルのレコードとして保存し、効率的なSQL機能でジョブキューを管理します。単一サーバー構成ではRailsのWebプロセスに組み込んで(Pumaプラグインとして)実行することも、独立したワーカープロセスとして実行することもできます。

Railsコアチームのあるメンバーは、その目標について「開発者がRailsをインストールし、データベースをセットアップすれば、7つものgemや他のシステムを管理しなくても、バックグラウンドジョブ処理がすぐに使えるようにすることだ」と語っています。

Solid Cable:WebSocketも(驚きですが)Redisなしで

Rails 8の「Redis不要」パズルの3つ目のピースがSolid Cableです。お察しのとおり、こちらもデータベースを使う新しいAction Cableアダプタです。従来、Action Cableで複数のRailsプロセス間にメッセージをブロードキャストするにはRedisサーバーが必要でした。Solid Cableを使えば、追加サービスを稼働させることなくAction CableによるリアルタイムWebSocket機能を活用でき、チャットや通知などのライブ更新機能を実現できます。

ここまで読めば、「Solid」トリオのメリットが見えてきたはずです。Redisサーバーやその他のpub/subサービスを立ち上げることなく、長期データのキャッシュ、高スループットのバックグラウンドジョブ処理、リアルタイム機能のデプロイがすべて可能になります。これらの機能により、小規模アプリでは1台のホスト・1つのデータベースですべてを動かせるようになり、デプロイを簡単にするというRails 8の哲学にも合致しています。

Redisが不要になるのは、それほど大きなことなのか?

Rails 8の多くがRedisへの依存排除に関わっていると知ると、それが実際どれほど重要なのか気になるところです。答えは状況によりますが、間違いなくいくつかの顕著なメリットがあります。

可動部品が少ないほど複雑さは減り、特にデプロイにおいてその効果は顕著です。Redisや専用のジョブランナーなど、追加サービスが1つ増えるごとに、壊れたりスケールが必要になったりする要素が1つ増えます。データベースをより多く活用すれば、本番運用がシンプルになります。Redisのメモリ監視も、Redisインスタンスが常に稼働していることの確認も不要になるのです。

多くのRails開発者が経験したことがあるでしょう。開発環境ではキャッシュサーバーを動かさなかったり、別のキューアダプタを使ったりするのに、本番環境ではRedis/Sidekiqを使う、というシナリオです。新しいRailsのデフォルト設定なら、開発と本番で同じ構成を実行でき、予期せぬトラブルを最小限に抑えられます。スタックはより自己完結型になり、本番向けの特別な設定をしなくても「そのまま動く」のです。

サーバーやアドオンが減れば、ホスティング費用も安くなります。ある程度の規模でも、インフラを統合すればコスト効率が上がります。データベースの容量はメモリより安いのです!

もちろん、RailsはRedisやその他のサービスの使用を妨げません。あくまで任意選択にするだけです。まず組み込みのSolidアダプタで始め、必要になれば後からRedisなどを導入できます。

SQLiteがデータベースプロセスを不要にする

Rails 8におけるもうひとつの重要な変化は、SQLiteを実用的な本番データベースとして受け入れたことです。これはRailsのSQLiteアダプタへの数多くの改善によって実現しました。アプリが本番でSQLiteを使えるなら、別のデータベースサーバーを稼働させる必要はありません。代わりに、データはアプリプロセス自身が管理するディスク上のシンプルなファイルに置かれます。Rails 8のSQLite改善により、以前より現実的な選択肢になったのです。

SQLiteなら、デプロイが格段にシンプルになります。サーバーにMySQLやPostgresをインストール・管理したり、マネージドDBサービスを(お金を払って!)使ったりする必要はありません。Railsアプリが読み書きするただのファイルなのです。

SQLiteの規模を超えて成長したら、もちろん後からフル機能のデータベースシステムへ移行できます。Railsコアチームはデフォルトを軽量な選択肢に変えただけであり、それは「No PaaS」という思想にぴったり合っています。

Kamal 2でデプロイを支援

Rails 8は本番でのアプリ実行を簡素化しましたが、アプリを本番環境へ届けるにはどうするのか? Kamal 2のリリースはその問いへの答えです。

Kamalは、Dockerコンテナ経由でアプリを最小の手間で任意のLinuxサーバーにデプロイするオーケストレーションツールです。アプリイメージのビルド、プッシュ、サーバー上での実行を自動化し、サーバー設定をすべて手作業で行う必要をなくします。

「PaaS不要」のアプローチはRails開発者にとって賢明な選択なのか?Rails 8の実力を検証

いくつかの設定とコマンド1つ(kamal setup)で、Kamalは真っ新なLinuxマシンにDockerコンテナ実行に必要なものをプロビジョニングしてくれます。

その後のデプロイはkamal deployを実行するだけ。最新イメージを取得し、古いコンテナを新しいものに入れ替えるゼロダウンタイムデプロイが行われます。

Kamal 2は、任意のLinuxホストでPaaSのようなデプロイ体験を提供することを目指しています。コマンド1つでどんなサーバーも、あなたのアプリを動かすRailsサーバーに変えられます。初期設定は骨が折れるかもしれませんが、その後のデプロイははるかに簡単です。Herokuのようなプラットフォームへのプッシュ並みの利便性をセルフホスティングで実現する、大きな一歩と言えるでしょう。

「No PaaS」は本当に良いアイデアなのか?

Rails 8は本当にプラットフォームを過去のものにするのでしょうか? 中小規模のチームはセルフホスティングで本当にお金を節約できるのでしょうか?

筆者は最近、Kamalを使って趣味のプロジェクトをVPSにデプロイしましたが、正直なところフラストレーションの溜まる経験でした。一度動いてしまえばデプロイは比較的スムーズですが、セットアップは決して簡単ではなく、このプロジェクトをスケールさせる必要が出たときの作業量は相当なものになりそうです。

だから筆者にとっての答えはノー——Rails 8はプラットフォームの価値提案を消し去ってはいません。むしろ、自分のアプリ開発に集中し、Herokuのようなプラットフォームにインフラを任せたいと思うのです。

個人開発者や小規模チームにとっては、規模の経済を追いかけるよりも、ユーザーに集中する方が得策です。ホスティング、デプロイ、スケーリングを、それらに秀でたプラットフォームに外注し、顧客が愛する製品作りに集中してはどうでしょうか?

もちろん、チームとアプリケーションが成長すれば、プラットフォームの料金設定が魅力的でなくなることもあります。いつかはSREや運用業務に専任の時間・人員を割く価値が出てきますが、Kamal(および他の素晴らしいRails 8のデフォルト設定)は、その移行を容易にするための大きな前進です。

まとめ

Rails 8はセルフホスティングとプラットフォーム利用の差を確かに縮めましたが、「No PaaS required」と正直に主張できるほどには埋まっていません。とはいえ、Rails 8によって開発者体験を大きく犠牲にすることなくVPSを選べるようになったのは明らかです。ただ、筆者自身はこれを「プラットフォームキラー」とまでは思いません。

Solid Cache、Solid Queue、Solid Cableは、かつてサードパーティ製ツールが必須だったWebアプリの要件をファーストパーティのサポートに引き入れました。これは非常にありがたいことです。アプリを立ち上げるための軽量かつ強力なデフォルトがあり、しかも大掛かりなインフラを必要としないのは素晴らしいことです。セルフホスティングを選ぶなら、Kamalがデプロイの負担を一部肩代わりしてくれるでしょう。

プラットフォームを使うかどうかにかかわらず、エラーや障害に迅速に対応し、優れたユーザー体験を提供するには監視が不可欠です。Honeybadgerに登録して、Railsアプリケーションの健全性とパフォーマンスに関するリアルタイムな洞察を手に入れましょう。

  1. Ruby on RailsでAction Policyをマスターする:安全な認可のための実践ガイド(前編)

    アプリケーションを安全に保つためには、誰が・何に対してアクセスできるのかを制御する必要があります。アクセス制御は、「誰を許可するか」を扱う認証(Authentication)と、「何にアクセスできるか」を扱う認可(Authorization)の2つに分類できます。 認証の詳細は別の機会に譲るとして、ユーザーの認可については、一般的に「ロールベース」と「リソースベース」の2つのアプローチがあります。 本記事は2部構成のシリーズで、Ruby on Railsのブログアプリケーションを題材に、Action Policy gemの使い方を深く掘り下げて解説します。この前編では、Action Polic

  2. 【Ruby入門】any?・all?・none?・one?メソッドで条件判定をスマートに書く方法

    今回は、配列やハッシュなど、Enumerableモジュールをincludeしているオブジェクトに対して条件判定を行う際に役立つ、4つの便利なメソッド「all?」「none?」「any?」「one?」について解説します。 これらのメソッドは、いずれもtrueまたはfalseを返します。 それでは始めましょう! Rubyのall?メソッド 例えば、「配列内のすべての文字列が特定のサイズであるか」を確認したい場面を考えてみましょう。 素朴に書くと、このようになります: def all_words_have_specific_size?(words) return false if words.