見出し画像

バックエンドに Rust を採用している「いい生活アカウント」について、プロダクトオーナーと CTO に語ってもらいました #2

こんにちは!いい生活エンジニア採用・広報担当の黒江です🐇

今回も前回に引き続き、データプラットフォーム本部の多田さんとCTOの松崎さんに、いい生活アカウントについて語ってもらいました!

今回の対談は3つの記事に分けてご紹介させていただきます。
こちらの記事は中編です!

前編の記事は以下よりご覧ください💁‍♀️


【前回の対談のおさらい】
いい生活アカウントは、いい生活のサービスにおける認証基盤を提供しているプロダクト。

もともとはある1つの当社プロダクトの認証基盤でしたが、他の当社プロダクトとも連携できるよう新しく作り直したプロダクトです。

また作り直すにあたっては、プロダクトのデータモデルの整理や、開発言語の変更など、技術の刷新も行いました。




Rust をバックエンドの開発言語に選んだ理由

開発するのが楽しい言語

松崎:
ところで、なぜバックエンドの開発言語を Rust にしたのかな?

多田:
僕の趣味(笑)と、チームメンバーがそれでやろうという気持ちになったからです。
選択肢は複数あって、TypeScript で書いて Cloud Functions を使うといった構成も考えました。

松崎:
その構成以外にも、他にも構成はいくらでもあるじゃない?
Express で、Node.js を立ててそれをコンテナで動かすこともできるし、型を強くしたいなら Go だって選択肢にあるだろうし。
パフォーマンスがシビアなロジックが多くあるわけでもないから、言語の選択肢としては結構いろいろあったと思うんだよね。
社内の他のチーム見渡せば、Python や Java だって選択肢になりうる。

それでも Rust を選んだのは「流行ってるし処理速度が速いから、Rust で書きたい」みたいな、そういう思いがあった?

多田:
僕が静的型付けコンパイル型言語をやりたいなと思ったのは間違いないですね。
実際に書いてみても、いい言語だなと思いました。

松崎:
そうだよね。ただ、Rust はメモリ周りとかに結構気を使わないといけないじゃない?
C/C++ ほど自由ではない分、メモリ安全性を高めるために Box や Move といった独自の概念がある。
言語機能としてもモダンな機能が多くあるので、 Mixin とも Interface ともちょっと違う Trait とかもあるし、Generics もある。
他にも Closure とかは慣れないとなかなかスッと読めない感覚もあるかなぁ。
その辺も含めて、学習コストって現実的にどうだったの?

多田:
学習コストは基本的には高いですね。
学習コストが高いことを楽しめる人が向いているなと自分でやってても感じますし、メンバーがやっているのを見てもそう思いますね。
まず、コンパイルが通るまで粘るという活動ができるかどうかですね。

松崎:
ただその分 C/C++ より安全で、実行時にメモリがリークしちゃうような事故が起きづらいじゃない?
クレートが多くなるとビルドはめっちゃ時間かかるけど……。

多田:
コンパイラが「駄目」と言ってるのに対して戦い続けて、それさえ解決すればとりあえずバグなく動作するだろうという気持ちになれるのは、いいところですね。

松崎:
逆に書くところにエネルギーを割きやすいので、実際に動かしてテストをしてみるよりも、コードの方に向き合いやすい分、開発生産性が高いのかもね。

多田:
そうだと信じてます(笑)
一回学んでしまえば、固く書けるのかなと思います。

あとは、プロダクトを作るにあたって、メンバーがやって楽しいものであるべきだよなと思ってました。
単純に Rust は興味がある言語だったので、1回ぐらい自分のプロダクトでやってみたいという思いもありましたが(笑)

僕のチームにはプログラムという意味でのコーディングをまるっと任せられるメンバーがいますしね。
そうじゃないところで何かあっても、何とか僕ができるだろうって思って。

松崎:
そういう意味で言うと多田くんはアーキテクチャデザイン全体を見ていて、実装やコード設計、モジュール設計とかの部分をそのメンバーが見てる感じなのかな?

多田:
そうですね。僕がサンドイッチしてるイメージかもしれないですね。
インフラ的な足回りみたいな部分と、いわゆる PO 的な全体を整える部分、「こういうユースケースがあるのでこれを作っていきたいんだけど…」のような交渉などを担当していますね。

松崎:
ソフトウェア的な面で、どういう設計にするのがいいか、どのようにコードを書くか、データをどのように扱うかみたいなのは全て任せているんだね。

多田:
基本的にはもう任せるようにしています。
たまに「僕はここはこっちがいいな…」って言うこともありますが…。

松崎:
そうやって意見を言うことは大事だよね。

Rust の不十分な点

松崎:
一方で、いわゆる計算量にバイアスが高い処理だと、Rust の 特性もあって言語機能だけでもカバーできることが多いし向いてるのはわかる。
でも データベースに繋いだり、Web にサービスを展開したり、別のミドルウェアと通信したりと、いろいろやろうとすると、周辺ライブラリの選択肢の幅や整備状況などの観点では、Rust はまだ未成熟な面があるよね?

多田:
まさしくそこの部分は Rust が一番大変ですね。
まだ SDK があまり整備されていないので、そこの点がクラウドやる上でやっぱり、ひと手間かかるなとは思います。

松崎:
やっぱりそうだよね。ライブラリの整備度合いや成熟度はそこまで高くはないし、Rust バインディングはありません、なんてことも普通にありそう。

多田:
ほとんどオフィシャルで転がっていることがないですね。

松崎:
それが Python との一番の違いだよね。

多田:
Python もそうですし JavaScript とも違いますね。比較対象でいうと Go が一番近いような気がします。

松崎:
Go だと結構公式のライブラリも充実しているし、スタンダードライブラリに結構いろんなものが詰まっている気がするけど?

多田:
Go は SDK も多くの場合が存在していますね。

松崎:
SDK がないということは、外部のサービスを呼び出そうとしたときに、Rust のクライアントがないので、通信部分から自作する必要がある気がするんだよね。
当然 HTTP のクライアントはあるけれど、API の定義とかデータモデルなどが Rust で定義されてるものがない。
だから 外部のWebサービス、例えば Auth0 とかと通信しようとすると、Rust の良さを活かすにはしっかりと型を書く必要があるから、結構自分で書かなきゃいけないことが多そうだよね。

選択肢は多くないものの O/Rマッパーもあるしデータベースドライバーもメジャーなものはあるので、データベースまわりはある程度は大丈夫だろうけど。

多田:
そうですね。
意外と接続するものの数が多いかなと思います。

松崎:
Auth0 は当然として、他にはどの辺が多いイメージ?

多田:
他には SendGrid とかもありますが、数でいうと一番多いのは今だと GCP 上のマネージドサービスですね。
例えば、非同期実行で使ってる Cloud Tasks なんかも HTTP でやり取りするところから書かないといけないのは大変かなと思います。

松崎:
確かに GCP 上に構築して、GCP の機能を使おうとするとその問題が出るよね。
Google はどちらかというと Go 推しなので、Go のバインディングは山ほどあるんだけど。

多田:
GCP はまだ Rust のSDK はないですが、AWS は1〜2年前ぐらいのイベントで Rust の SDK を発表していたかなと思います。

松崎:
AWS の Rust の SDK(AWS SDK for Rust)は一応あるね。まだデベロッパープレビュー だけどね。(2023年10月現在)
そういう意味では、Rust をピンポイントで使うんじゃなくて、バックエンド というか API を丸ごと Rust にしちゃうというのは、結構攻めの姿勢であると思うんだよね。

多田:
そうですね。
でも、やりたかったんでやりました(笑)

松崎:
やっぱり書いていて、やってて楽しいみたいなことなのかな?

多田:
そうですね。
できたものもいい感じかなと思います。

松崎:
なるほどね。楽しくやってるって感じなんだね。

データの移設

松崎:
あとさっきも出てきたバックエンドの話だと、ドキュメント系のデータベースからリレーショナルデータベースにデータ構造も含めてデータストアを変えて、データを移設するというタスクが発生したじゃない?
データストアを多くの人々が変えたくないと思う一番の理由は、異なるアーキテクチャやスキームのものにデータを移設するのはかなり大変な作業になるからと思ってるし、過去の経験的にもそれはわかりみが深い。

でも今回は、このままではのちのち破綻してしまうのが分かっているから、早い段階でデータストアの変更を決断したと思うんだけど、データの移設は実際大変じゃなかった?

多田:
大変だったとは思いますね。
ですが、移設元の方がモデルとしては簡単で移設先の方が、複雑なものを表現できる状態なので、今回の移設はある程度難易度が低かったかなと思います。
あとは、いい生活アカウントのチームメンバーは、「大変でもやるしかない」って割り切ってやってくれるメンバーだったので、やり切れたと思います。

松崎:
そうだね。「やるだけだしね!」みたいな感じだよね。

多田:
移設は、概ね上手くいったんで良いかなと思います。


新しい技術を導入するときに

CTO はどのように使用する技術を判断するか

黒江:
プロダクトオーナーやプロダクトチームがこういう技術を使いたいという意見に対して、松崎さんは基本的に OK を出すんですか?
どういう判断基準で決めているのでしょう?

多田:
新しい技術を導入するときに、明確に OK と言われたことは多分ないと思うんですよね。

松崎:
どちらかというと、OK を明示的に出すというアクションは普段から取らない一方で、駄目な時は NG を明確に出しに行く感じかな。
どういう動きになってるか、何で作ってるかなどはSlackを通じて見えているので、もちろん駄目なときは駄目ってはっきり言いますね。

ただ「これぐらいの規模とこれぐらいのチームであれば、とりあえずまず始めてみて様子みるかな」と判断していることも多い。
今回の Rust 採用はまさにそういう感じ。
もし「これ以上書ける人が増えない」みたいな状態になったら、途中でストップをかけるつもりではあったよね。

黒江:
なるほど。今は「書ける方」が集まっているんですね。

松崎:
そうだね。「どれぐらい書ける人が増えるか」は結構大事なところかなと。
「○○さんしか書けない」や、「△△くんしかわからない」になると、それは人材の流動性という意味で、その人を他の仕事に充てられなくなっちゃうし、当然新しい人を増やすこともできなくなってしまう。
そうするとそのチームが固定化してしまうし、それは避けたいので…。

多田:
今のところ必要な人数は確保できているんですよね。
僕も万が一のときのために読んでいますし、社内に意外と Rust が書ける人がいたりもします。
あるいは、これから書きたいと思っている人も実はいるんじゃないかなと思います。

松崎:
うん、意外といるよね(笑)
だから、人員の入れ替えもやろうと思えば実はできるんだよね。

Rust は世の中のトレンド的にも、もう少し経ったらよりメジャーシーンに行くだろうなと思っているので、そういう意味でも先行投資としていいかなと。
これまで C/C++ で書かれていた多くのソフトウェアが少しずつ Rust 化していく未来が、今ちょうど見え始めたかな、って感覚。

多田:
そうですね。一方で、インタラクティブに何かをするときはさすがに Python だと思いますけど。

松崎:
そこら辺はね、何でもそうだけど、メリットデメリットがある部分だと思う。

ただ、Rust はいわゆる DLL が作れるので、ピンポイントで高速化したいところに刺すという使い方もきっとできるはず。
なので Python における C Extention の置き換えみたいな使い方もありだと思う。

あとは 同じような文脈で、WebAssembly での Rust の採用もこれからどんどん増えて行く可能性が高いよね。
ブラウザでの処理性能を劇的に上げようと思うと、結局こうやって高速で動く言語が必要になってきちゃうから。

多田:
現代的にそういうものを作るには、ブラウザしかり、エッジコンピューティングしかり、コンテナ前提なら Kubernetes 上とかも含めて、C/C++ よりは Rust 製のプログラムが作られていくんでしょうね。
流行るかは分からないですが、WebAssembly が動く世界観に多分なっていくでしょうし。

松崎:
「今回のユースケースに Rust が本当に向いていたか?」という質問に関して、今現在は僕は「まだどうでしょう…?」と思うんだけど、Rust 製のちゃんと動いてるソフトウェアが一つあるのは、会社として大事だろうと思ってるかな。

みんな同じようなスタックで、みんな同じような言語で書いていることはメリットもあるんだけど、デメリットがあって。
みんなが使い慣れた言語に技術スタックを集約していけば、当然会社の中で人材の流動性は高まるんだけど、それが進みすぎると新しい技術に取り組む障壁が高くなっちゃうんだよね。

サービス運用をする上では、時代に合わせて少しずついろんな構成要素の技術を変えていく、例えばプログラミング言語の流行り廃りや、Webアプリケーション を提供するインフラの変化、エッジコンピューティングの台頭やAI技術の活用などといった、多くのことに対応しつづける必要がある。

でも、使用技術を固定してしまうと、変化に対して組織が固くなってしまうんだよね。
作って終わりで、サービスを長期にわたって運用していなければ、それでもいいかなと思うんだけどね。
でもサービスプロバイダはそうじゃない。ましてや BtoB となればプロダクトのライフサイクルはとても長いものになるから、モダナイゼーションし続けるのは宿命といってもいいんじゃないかな。

だから 新しい技術を導入したいときは、僕が思わず驚いてしまうような突飛なものじゃなければ止めないですね。
例えば「Haskell や OCaml で書きたいです」って言われたら「え~!?」って多分言うと思う気はします。
でも Rust と言われたらそうならないし、Go と言われても別にそうならないし、という感じかな。
もちろん Haskell は純関数型言語としてはいい言語だし、OCaml も派生の F# を含めいい言語とは思うけど エコシステムがまだ弱いので……。


Rust が社内でも好まれている

多田:
ちなみに Go にならなかったのは、社内で Go よりも Rust の方が好まれていたからというのがありますね。

松崎:
僕は Go はいい言語だと思ってるけどね。

多田:
僕もそう思います。

松崎:
確かに Go はエラー処理とかがちょっと独特なのはあるけど、それ言ったら Rust だって最終行が戻り値になっていたりするから。
今ってわざわざ明示リターンせずに、最後の式の値が評価される前提にしてるよね?

多田:
はい、そうですね。

松崎:
そういうところは、特に書かない人からすると「癖があるな…」と見えるはずなので。

多田:
癖があるし、クレートとかも初見でわかるはずもなく…。
15回ぐらい使うとようやく手になじんできて、慣れてしまうとそれがない言語で書くのが大変なんですよね。
それが Rust の中毒性があるところ。

松崎:
結局どんな言語も善し悪しはあるので、あとはトレンドとの兼ね合いで決めるかな。



続きが気になるところですが、今回はここまでとさせていただきます!
読んでいただき、ありがとうございました😊

いい生活では新卒/キャリア採用を行っております🧑‍💻
エンジニアとデザイナー職は2025年の新卒採用も始まっております!
以下から気軽にご応募ください!


また、いい生活公式noteの「いいnote」のフォローもお願いいたします!

次回の記事は松崎さんと多田さんの対談の最終回です!
高いサービス品質を保つためには?などに迫りました👀

それでは今回はこちらで失礼します!

撮影:杉山 泰之


いい生活では、新卒・中途ともに積極採用中! 採用サイトもぜひご覧ください。