一休.comレストランのシステムアーキテクチャ

アーキテクチャ選択の背景や意図
運用コストを下げるため、およそ7年前にデータセンターからクラウドにすべてのサービスを移行しました。以後、AWSを中心に、クラウドのみを利用しています。
コンピューティングリソースは、クラウド移行当初は、AWS ElasticBeanstalkを利用していましたが、今は、AWS EKSを利用して、コンテナのメリットを最大限享受できるようにしています。
簡易にコンテナのワークロードを扱えるようにするため、現在は、Google Cloud Run/Cloud Run Jobsも利用しています。
また、fastlyをリバースプロキシ兼CDNとして利用することで、トラフィックのコントロールや各種アクセス制御を行っています。
現在のアーキテクチャの課題と今後の改善予定
データベースが、クラウドが提供するマネージドDBではなく、EC2インスタンス上にマニュアルで構築したSQL Severクラスタになっています。
これによって、Windowsクラスタに関する細かな知識を持ち続ける必要があります。
今後は、マネージドなDBサービスへの移行を検討しています。また、レガシーなWindows系のバッチ処理など、いくつかコンテナ化できていないワークロードがあります。これらを、コンテナ化して可搬性/リソースの効率性を確保したいと思っています。

事前知識
気になったこと
1. Google Cloud と AWS の併用
構成図だけみると Google Cloud で特殊なものを使ってるようには見えない
簡易にコンテナのワークロードを扱えるようにするため、現在は、Google Cloud Run/Cloud Run Jobsも利用しています。
デプロイの簡易さだけなのかなあ。複雑度を考えるとマルチクラウドにするメリットがそこまで大きくはなさそうだけど。
をみると
本サービスではPrismaを利用してDBのスキーマをアプリのコードと同じリポジトリで管理しているため、 複数の新機能を平行して開発していく場合に開発環境が1つだと、DB定義が衝突したりして尚更大変です。 そこで、複数の開発環境を作成できるようにしました。
って書いてあるので開発だけだったりする? いやでもCDNでルーティングしてるから違うか。
クラウドサービスについて、一休では、AWSとGoogle Cloudを併用しています。 新しく作るサービスではGoogle Cloudを使うケースが増えている一方で、一休.com 宿泊ではまだ事例が少なかったこともあり、今回はGoogle Cloudを使うことにしました。
2. サービスは大きいと思うけどモノリスなのかな?
これはレストランではないが。。。
3. Spinnaker は最近珍しいイメージ(GitOps的に)
2019年に移行してそれ以来かな。
確かに当時だとこれか JenkinsX とか Tekton になるのかな。
4. DB が EC2 で動いているらしい
SQL Serverなのも珍しい。Zozoもそうだったような。
データベースが、クラウドが提供するマネージドDBではなく、EC2インスタンス上にマニュアルで構築したSQL Severクラスタになっています。
これによって、Windowsクラスタに関する細かな知識を持ち続ける必要があります。
今後は、マネージドなDBサービスへの移行を検討しています。また、レガシーなWindows系のバッチ処理など、いくつかコンテナ化できていないワークロードがあります。これらを、コンテナ化して可搬性/リソースの効率性を確保したいと思っています。
5. Rust + GraphQL
社内の技術選定方針として「シンプル、かつすばやく、それでいて堅牢に作れる」という方針があります。その方針に基づき、Rustが以下の点からバックエンドの新たな言語として選定されました。
型の表現力が高く、「一休レストラン」の扱う業務のドメインモデルを正確にコードに落とし込むことが可能。
これにより、型システムに基づいて堅牢なシステムを構築することができる。
高速かつ省リソースなバックエンドサーバーの実現が可能。
これにより、サービス運用コストを中長期的に改善することが期待できる。
一休レストランのリニューアル計画が始まったころ、一休では宿泊予約サービスや社内の基盤サービスを中心としてGoが標準的なバックエンドの技術スタックでした。
一休レストランの開発でも、宿泊予約サービスでの経験があるメンバーのスキルセットに基づいてGoを使うこともできました。その一方で、この方針だと社内の技術ポートフォリオがGoに偏ってしまうという懸念もありました。
一休では、社内で蓄積する技術的知見に多様性を持たせ、結果として状況に応じて最適な技術選定ができるように、複数のプログラミング言語を使うことを意図的に選択しています。
へ〜〜。会社としての統一感より広がりをとったのか。
そこで、チームメンバーの中にRustに詳しいエンジニアがいたことも助けになり、Rustをバックエンドの言語として採用するかどうかを検討しました。
Rustの採用による狙いは次のとおりです。
まず置き換えたい参照系処理のCPU利用効率を上げて、高速なバックエンドサーバとする
今後のさらなる開発を見据え、メモリ安全、型安全な開発体験を実現する
技術的知見の多様性という点で、関数型のメンタルモデルでプログラミングできるエンジニアを増やす

印象として長く続いているサービスなのでレガシーな技術が随所に残っている感じなのかな?
とはいえ、サービス規模的にも思い切ったりアーキテクチャをする感じでもないので、部分的に局所最適化が行われているとかなのかな。(問題があるわけじゃない)
当時は全て.NETだったというサービス基盤の刷新や技術的負債の解消、開発組織の整備といったエンジニアリングにおいて重要な改善を進めてきましたが、あるとき自身が「事業に貢献していない」ことを明確に意識することがあったといいます
CEOからの勅命とはいえ CTO がこのレベルをやってるのか。意外。
僕が「やります」と宣言して最初にやろうとしたのは、コードや設計書を読むことです。また、それまで手掛けた個人ユーザー向けのB2Cサービスでは、特定のユーザーにフォーカスするのではなく、ネットワーク越しにユーザーの行動を観察したり想像したりして、データに基づいて高い精度でユーザー全体を分析することで開発してきました。
ただ、上記の活動も以下に書かれているように「顧客のユーザーエクスペリエンスの問題解決にコミットすること」に収斂されるなら関係ないのかな。(おそらく当時は、上記の課題を委託できるチームや体制もなかったのかもしれない)
結論としては、主体的に問題解決に関わっていくことです。ところが、エンジニアに「ビジネスに貢献しよう」という話をすると、売り上げに貢献しなければいけないと考えて、コンバージョンレートとか利益率といった数字を上げるための機能改善を考えてしまいがちです。
しかし、決して僕たちエンジニアに売り上げを立てろとか、企画を考えろと言われているわけではない。テクノロジーの専門家として、顧客のユーザーエクスペリエンスの問題解決にコミットすることが求められていて、それに対して主体的に関わっていくことがビジネスへの貢献なんだと今では考えています。
当時の一休を振り返ってみると、みんな「レガシーシステムは嫌だ、これで開発するのはつらい、それが原因で僕たちの開発スピードは遅くなっている」と言うのだけど、実際にそれを新しくする活動をしている人はほとんどいませんでした。
なるほどなー。「受発注の関係」とか「レガシー」とかがよくでてくるので、企画や営業側とエンジニア側が受発注な感じだったのかな(もしくは外注していたか)? そこにCTO(その前から居たかはわからないが)が参画して、徐々にエンジニアが主体的に変えていけるようになったという感じだろうか。
これが当時の資料か。

↑の話まとめて読んだけど、CTOの伊藤さん(と携わられたみなさん)すごいな。