スタートアップである弊社が全員ほぼ未経験でRuby on RailsをScalaに移行した理由、その効果と苦労点

## この記事を書くに至った経緯

僕が代表をしている株式会社KOSKAでは製造業の原価管理をIoTで自動化するGenkanというサービスを提供しております。

そんな弊社では半年前、バックエンドをRuby on RailsからScalaに移行したのですが、その効果が思ったよりだいぶ大きく、いずれこの効果を共有したいなーと思っていました。

<blockquote class="twitter-tweet"><p lang="ja" dir="ltr">弊社ではスタートアップで全員ほぼ未経験状態のScalaを採用するという挑戦をした結果、「Scalaを書きたい」というレベルの高い人材をかなりの確率で捕まえられるようになり、開発がものすごい加速した上に堅牢になったのでそのうちスタートアップでScalaを採用するメリットを記事にする予定。 <a href="https://t.co/uqZ5YWs6Ru">https://t.co/uqZ5YWs6Ru</a></p>&mdash; ソネケン (@sonken625) <a href="https://twitter.com/sonken625/status/1215118953774768133?ref_src=twsrc%5Etfw">January 9, 2020</a></blockquote> <script async src="https://platform.twitter.com/widgets.js" charset="utf-8"></script>

そんな折、このようなツイートをしたところ予想外にいいねRTが多く、思っていたよりだいぶ興味ある人が多いことがわかったので早く書かないといけないと感じて書き始めました・・・が、書きたいことがおおくて全く進まない

そして半年後、あまりにも僕が書かないので弊社CPOが以下の記事を書きました。
[0からScalaを本番導入して感じたこと・考えたこと - Qiita](https://qiita.com/KtheS/items/c91df9f641dcbf1a2d22)

ここで結構色々書いてくれてるのですが、当時の詳しい状況や、CEOとして考えていたこと等を僕も書いておこうと思い公開します。


結果だけ知りたい人は最後にまとめておきますので最初の方は飛ばしてください。スタートアップでRuby on RailsやPHPのようなスクリプト言語系を移行しようか迷っている人、などを考えている人の参考になれば幸いです。


## 当時の状況
2019年7月時点まで、弊社のGenkanはフロントエンドがTypeScript×React、バックエンドはRuby on Railsで作られていた。2018年11月に起業したので人数は少なく、2019年3月くらいまでは実質僕とCPOの2人でバックエンドフロントエンドをほぼ全て作る必要があったため、2人が一番慣れている構成にしていた。

PMF前でもあったので仕様変更が激しく、とりあえず動くならなんでもいいという状況であったため負債のたまり方も尋常ではなかった。

いわゆる普通のWEBサービスと少し差があったのは、弊社のサービスはIoTデータを自動で分析し、原価で分析するというものでセンサーから送られてくるタイムスタンプをかなり色々な複雑な計算によって分析結果を出さなければならなかった。とはいえ四則演算の領域なのでアプリケーションだけの計算でどうにかなるだろうと見積もり、Ruby on Railsで基本計算も行うような形にしていた。

IoTデータとはいえセンサー側で計算もしており、4秒に１回ほどのデータが飛ぶだけなのでNoSQLに頼るほどのものでもないという考え方でRDBMSにタイムスタンプデータを貯め、SQLとRailsのモデル層で計算し、フロントにJSONを返す流れでおこなっていた。

ただ実際これが意外と複雑で、SQLである程度行えば計算部分は多少マシにはなるがRuby on RailsでSQLを柔軟に構築するタスクに躊躇していたのと、アプリケーションの方がアルゴリズムを変えるのが(自分たちの慣れの問題で)早かったために、アプリケーションコードでほとんどのアルゴリズムを構築していた。


その結果、Ruby on Rails側での複雑性はどんどん増していった。対処法としてサービス層作成、モジュール化、Trailbrazer使ってDDDのレイヤードアーキテクチャの真似事をするなど頑張ってリファクタし続けていたが、7月になるころにはサーバーの機能を追加するのにも影響範囲を考えながら行う必要が出てきたために機能追加がだんだん遅くなってしまっていた。

また、会社的にはトライアルが増え始め、最初は運用は完全手動でやるしかなかったためにCTO、CPO、僕で半田付けしたり、センサーのアルゴリズム書き換えたりハードウェアスタートアップによくある多大な苦労がどんどん増えていた。

また弊社のエンジニアの人材的な側面での環境を整理すると

- CTOはハードウェア担当。ソフトウェアもできるがモダンな開発が得意というほどでもない。
- CPOはソフトウェア担当。フロントもサーバーも行うがRuby on Railsでのバックエンド作成を最後の方ほとんど一人で行っていた。
- CEOである僕もソフトウェアをガンガン開発していた。バックエンドもフロントエンドもできるがフロントエンドの方が得意なためフロントエンドメインと、インフラ(AWSでECSを使って基本コンテナで運用している。)を担当した。

- これは少し特殊なカルチャーであり自慢でもあるのだが、弊社は創業時からエンジニア経験ゼロの文系学生を教育しモダンな開発ができるレベルまで育てており、2020年現在ではそうやって育てたエンジニアがすでに5人ほどいる。1年程度しか経っていないが全員React×TypeScriptはできるし、特に初期からいた2人(@unirt,@Ki-da)はScalaサーバーをメインエンジニアとしてガンガン開発していたりHadoop&Sparkでの分散プラットフォーム分析環境を構築、開発していたりと経験1年のエンジニアとしてはあり得ないレベルまで育っている。そこまでにするのに相当な教育コストをかけているが、弊社の大事にしていることは「エンジニアが成長できる環境」をつくることであり、エンジニアが成長できるなら多少コストがかかっても組織としては強くなると考える文化が形成されていた。

## 意思決定

### 課題
8月になった際にこのままだとまずいが、どう対処を取るかという会議を行った。弊社の状況を整理すると

- 機能追加がどんどん遅くなっている。アーキテクチャを再検討していく必要がありそう
- トライアルにかかるコストを減らしていかないとどう考えてもリソースが足りない。スケールさせる上でも必須なことは間違いない
- エンジニアが成長できる環境を作りたい。それは難しい言語やフレームワークを使わなくても達成はできるのでアーキテクチャ採用に直接は関係しないが、やはりエンジニアの意識に影響するような環境を作れるのであれば技術の難しさは関係ない。
- 一方でシード期のスタートアップに時間はそこまで残されていない。実はこの時すでに資金調達が迫っていた。とはいえ現在のシステムを全て移行するなら３ヶ月程度を見込まないといけないと考えられる。ここはCEOである僕がもし再設計や再実装を行うのであればそのメリットを投資家に伝え、社内でも全員が正しい意思決定であると納得するまで議論することがCEOの責任でもあると考えていた。

このような条件のもと議論し、どのように対処していくのが一番最適かを全員で考えた。

### 決定事項
まず最初に決まったのは

- 少なくともトライアルにかかるコストを削減するために、ハードウェアやセンサー解析アルゴリズムをある程度自動化する社内システムを作る。
- その社内システムは現在のシステムとは独立して動かす。

ということだった。(現在そのシステムはGKAssistantという名で、ハードウェア内のアルゴリズムを自動で書き換えたり管理できたりするシステムとして狙い通り動いている。)

これはトライアルのコストを削減するためには必須であったし、ハードウェア管理コストが減れば減るほど機能追加が加速できるのもあり明らかなメリットがあったためすぐに決まった。

### Genkanの改修戦略
続いてGenkanのリファクタについて議論した。この時の選択肢は


- Ruby on Railsでアーキテクチャを作り直す(trailbrazerというライブラリである程度作っていたが、さらに改造していく)
- RubyではあるがDDDに向いていたHanamiを試す
- 別言語にする

というものであった。

単純に他の言語やフレームワークがやりたい！で意思決定しても仕方ない。僕はそこにメリットがあるのかのロジックを詰めることに重きを置いていた。(ちなみにCPOはやりたいがメインだった見たいですが、それはそれでいいカルチャーだと僕は思います。技術は手段だからなんでもいいみたいな考え方は技術が好きな人が多かった弊社だとあまり合いませんでした。)

まずHanamiを試すという選択肢はすぐに消えた。
そこまでしてRubyにこだわる必要を感じられなかった上に、その当時DDDもそこまで知見がなく、そもそも今回のシステムの問題がDDDで解決するのかも不明だった。（実際結局現在はCQRSを採用しているのでリードが複雑な部分は解消しなかったかもしれない）

実質的にはRuby on Railsに留めるか、別言語にするかの二択であった
Ruby on Railsに留めるメリット

- （別言語に変えるよりは）工数がかからない。これにつきる。
- （別言語よりは）現在の問題に対する打ち手がいくらか思いつく。別に言語を変えなくても解決する可能性はある。

別言語にするメリット

- 静的型付け言語に変えることができる。(TypeScriptでフロントエンドを書いていたため、サーバーでも静的型付け言語を使いたかった)
- アーキテクチャの選択肢が言語に縛られないためより最適な構成を作れる可能性がある。

- エンジニアのモチベーションを高めることができる。弊社のエンジニアは成長できることにインセンティブを感じる人間が上記の理由で多かった。そのためエンジニアのモチベーションを大幅に上がる可能性があった。

このような部分で議論を繰り返し、結局は別言語を採用することになった。
決め手となったのは上記のメリットもあったのだが、実はもう一つ自分たちで考えた仮説があった。


#### スタートアップの言語選択の採用への影響
どこのスタートアップでもそうだと思うのだが、エンジニアの採用の難易度は非常に高い。特にtoCアプリの場合プロダクトの魅力などで参加してくれるエンジニアもいるが、toBのSaaSプロダクトなどはそもそもその分野のことを知っているエンジニアの方が少ないためプロダクトの魅力が特に最初の時点では非常に伝わりづらい。（例えば弊社のサービスは「IoTで工場の原価管理を自動化し、工場の方々が簡単に分析できるようにする」といったサービスだが、工場と原価管理に関わったことがないとピンとこないと思う。）
そのためスタートアップならではの働き方だったりをアピールすることになるのだが、だいたいスタートアップでやれることはみんな一緒になるのでどこも似たような形になる。さらにいうならそういう施策はシード期のベンチャーよりシリーズA以降のベンチャーの方がよっぽど強い。同じ条件なら既にでかくなっている企業に入りたいと思うのは合理的だとも思う。

そうなるとシード期のスタートアップでエンジニアが働く理由は
1. 超レベルの高いエンジニアがいる
2. 給料
3. プロダクトの技術スタックが自分がやりたい方向

などが主要因になる。僕が他のスタートアップで働いていた時もだいたいそのような軸であって、決してお菓子が食べ放題でフリーアドレスだからではない。

そこで上の３つを達成しようと思った時に、1は運ゲーであり、超ハイレベルエンジニアが興味持ってくれるかどうかによる。うちのエンジニアもレベルは高いが流石に超有名OSSのコミッターとかはいない。そういうのがシード期にいるスタートアップの方が珍しいと思う。

2も弊社は結構頑張っているつもりだが、シリーズAを超えたスタートアップに勝つのは非常に難しいだろう。同じ水準を出すことは可能だが差が出るほどではない。

となるとシード期のスタートアップはどこにいってもエンジニア側からすると似たような部分だけになってくる。あとはもはや合う合わないの世界である。
そこで3をある程度狙っていくのも戦略の一つではないかと考えた。
僕がもし採用される側なら選ぶ要因の一番大きいのは言語や技術スタックだし、そういう人材はスキルもかなり高いことが多い。そこで僕らが採用したのはScalaであった。



### Scalaの採用理由
選択肢はGoとKotlinとScalaであった。バックエンドでの実績が多く、現状の課題を解決する可能性がある言語を選んだ結果である。
様々な議論があった。CPOもここで書いている。
[0からScalaを本番導入して感じたこと・考えたこと - Qiita](https://qiita.com/KtheS/items/c91df9f641dcbf1a2d22#scala%E3%81%AE%E9%81%B8%E6%8A%9E)

CPOは割と楽しそうだからというところしか書いていないが、(ここも重要なポイント)実際はScalaにした理由がいくつかある。

1. DDDがやりやすい言語と聞いていた。
もともとRailsのコードがある程度めんどくさい分析をコードで行なっていたというのもあり、今後管理系の機能も追加されていくことがわかっていたので、DDDをはじめとしたいい感じのアーキテクチャを使いたかった。Scalaという言語はDDDにおいてかなり優秀であるという噂を聞いていたのでうまくいく可能性も大きいのではと予想した。

2. 金融系やTwitterでの採用実績から大規模分散処理に強そうという予想
弊社はIoTデータを分析するサービスなので、サービス規模の割には処理量が多い。今後スケールしてきたときに分析バッチなどをどのように回すのか等を考えた場合、Scalaなら外さないだろうと考えた。

3. 採用として強い。
GoやKotlinも悪くないのだが、実際今スタートアップだとかなりの割合でGo,TypeScript, Kotlin等のモダン言語で開発が行われている。
ちょうど僕らの投資元がとてもいい資料を作ってくれたので見てみると、pythonやrubyなどは圧倒的だが、かなりGoとかKotlinもいる。
[スタートアップ開発環境マップ（約40社）by Coral Capital - Google スプレッドシート](https://docs.google.com/spreadsheets/d/15l0YhBwEh7Nu6J5bLM5aBk-gw5rsiZBA-8z_Hnx3KaY/edit?utm_campaign=Coral%20Community&utm_content=133919810&utm_medium=social&utm_source=twitter&hss_channel=tw-1048448469524860930#gid=0)
上で書いてある採用を考えたとして、Go言語使えるからという理由だけなら選択肢がたくさん存在する。Scala言語は見ればわかるのだがその難易度や情報の少なさとの関連上そもそも実務で行うことが意外と難しい。なので「Scalaを実務で使ってみたい」というレベルが高いし成長意欲が高いエンジニアが採用できる可能性が高いのではという理由であった。




## 現在の状況
かくしてScala採用を行い、すでに1年過ぎた。
**結論からいうと正解でしかなかった。** どういうメリットがあったか上げていく。

### 管理系のシステムをとても効率よく作ることができた。
現在は全てのバックエンドがScalaで動いている。
アーキテクチャはDDD×CQSっぽいReadとWriteをコードベースで分けたものを採用している。
このアーキテクチャで一番良かったのは管理系の仕組みを作った時で、弊社のように原価計算をやるときには原価情報の管理がかなり複雑な条件を持つ(工場の工程や機械は時系列で変化しうるのでバージョン管理みたいなものが必要)
しかし管理系のシステムを実装したとき、ほとんど問題がなく設計し実装まで全員で取り組め、1ヶ月程度でほとんど完成した。
Scala×DDDの破壊力を知ることができた部分であった。

###  採用活動が本当に一瞬でおわった。
調達直後に採用を始め、とりあえず３人程度増やしたいと考えた。
１ヶ月採用活動して、結果

- Scalaやりたがってたフロントエンドエンジニア
- Scalaやりたがってたバックエンドエンジニア
- Scalaを実務で行なっていた金融系のエンジニア
- Scalaをやりたがっていたフロントエンドエンジニア
- Scalaをやりたがっていたインフラ系エンジニア

と技術力が尋常じゃないメンバーをすぐに採用することができた。かれらが弊社に貢献してくれた部分はとても大きく、組織が明らかに大きく成長していった。

ちなみに採用活動中に行なったのは、CEOである僕が面接中にひたすらScalaって言語で開発するのが本当に楽しいって話しをし続けただけである。本当に素晴らしい言語である。

Scala採用したときによく言われたのが「Scalaってできる人が少ないしできる人はすごく単価高いから採用難しいんじゃ？」だった。
これは確かに事実。Scalaを使っているような企業に所属するエンジニアを採用するのはなかなか難しい。
だが、今まで他の言語をやっていて、Scalaをやってみたいエンジニアも同じくらいハイレベルなことが多い。そういう人材は普通に１、２ヶ月以内にある程度Scalaをマスターし、開発に参加し、今までの持ってた経験等で組織を大きく成長させてくれた。

つまり、Scalaを採用し、少しキャッチアップに時間を割くだけで、結局強力な人材を速攻で採用しているのと変わらなくなっている。
Rubyで３ヶ月以上採用活動してもあまりいい人材が見つかっていないスタートアップを様々みてきたが、採用に関しては人材がたくさんいるRubyやPHPよりも人材がそこまでいないがみんながやりたがるScalaの方が優位であると感じた。

### 分析システムにSparkをすぐに採用することができた。
SparkというHadoopを使う仕組みがある。これはScalaで動いており、ものすごくScalaと相性がいい。(Pythonでもうごくので別にScala限定ではない。)
今弊社の分析バッチ処理は全てSparkで行われており、IoTデータがスケールしたとしてもほとんど同じ仕組みで継続できる。
Scalaを採用したことでこのSpark採用に全く抵抗がなかったのは大きくメリットであった。



他にも弊社CPOが書いた記事にある定性的なメリットもすごく大きかったので参考にしていただければ。


## 結論：スタートアップでScalaを採用できるのか&意味はあるのか？
結論からいうとできるし、採用やチームのモチベーション、開発スピードにものすごいプラスの影響を与える。
**特に「Scalaをやりたいという優秀なエンジニア」を採用できるというメリットが会社としてここまで影響があるとは思わなかった。エンジニア採用はスタートアップにとって大きな課題であるため、このメリットだけでもScalaを選択肢にいれてもいいと考えている。**


ただ、いきなりシステムを置き換えるのはお勧めしない。一番いいのはとりあえず別の機能や小さいサービスを別サーバーで作り、それをScalaで作る方がいいであろう。
Scalaは慣れてしまえばメリットが大きいのだが、RubyやPHP,Python等でサービス作ることに慣れていると本当に混乱する。そこに慣れるまでにおそらく３ヶ月はかかると考えていい。
さらに情報が全くないので、これが正解なんだろうかという疑問を常時持っている状態になる。個人的にはCTOなどチームの中でも技術力が高いメンバーが１人か２人で探索していくのがいいだろう。

(弊社では僕とCPOがハードウェアを管理する仕組みをScalaで作ることでScala開発を探索していきました。)



## 苦労はしないのか？

**導入が大変じゃないのかといえば、結構大変である。**
Scalaを採用したら５ヶ月くらいは色々苦労すると思う。
ただ、弊社の場合それ以降の開発の速度が尋常じゃ無くなった。
優秀な人が組織を成長させてくれたし、成功体験が多くなり、開発が楽しいのでみんな熱中して開発するみたいな素晴らしいサイクルが生まれた。

その結果弊社では次から次へと機能開発が進みCEOである僕はほとんど開発に参加しなくても問題ないようになっていった。
もし検討している人がいたら勇気を持って採用してほしい。
あと多分苦労するところは同じなので困ったらなんか連絡くだされば答えられることであればなんでも答えます。[DMでも飛ばしてください](https://twitter.com/sonken625)

最後に、今後Scalaを採用するに当たってめちゃくちゃ引っかかるところをだいたい解決策も書いた記事を書きました。

[Ruby on RailsやLaravelなどのフレームワークを使ってきた人がScalaを導入した時に引っかかる点とその解決策](https://qiita.com/sonken625/items/80c0d86d507dedcc654b
)

RoR等を使った開発に慣れているがScalaが初めてと言う人は参考になるかなと思います。
Scalaは本当にいい言語ですし、メリットも大きいのでスタートアップのCTOなどは、ぜひ検討してみてください。